forked from inconshreveable/go-tunnel
-
Notifications
You must be signed in to change notification settings - Fork 0
/
proxy.go
95 lines (79 loc) · 2.61 KB
/
proxy.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
package client
import (
"bufio"
"code.google.com/p/go.net/proxy"
"crypto/tls"
"encoding/base64"
"fmt"
"github.com/inconshreveable/muxado"
"net"
"net/http"
"net/url"
)
func SOCKS5Dialer(network, proxyAddr, user, password, addr string, tlsConfig *tls.Config) func () (muxado.Session, error) {
return func() (muxado.Session, error) {
proxyAuth := &proxy.Auth{User: user, Password: password}
proxyDialer, err := proxy.SOCKS5(network, proxyAddr, proxyAuth, proxy.Direct)
if err != nil {
return nil, err
}
conn, err := proxyDialer.Dial("tcp", addr)
if err != nil {
return nil, err
}
// upgrade to TLS
conn = tls.Client(conn, tlsConfig)
return muxado.Client(conn), nil
}
}
func HTTPDialer(network, proxyUrl, addr string, tlsConfig *tls.Config) func() (muxado.Session, error) {
return func() (sess muxado.Session, err error) {
// parse the proxy address
var parsedUrl *url.URL
if parsedUrl, err = url.Parse(proxyUrl); err != nil {
return
}
var proxyAuth string
if parsedUrl.User != nil {
proxyAuth = "Basic " + base64.StdEncoding.EncodeToString([]byte(parsedUrl.User.String()))
}
var dial func(net, addr string) (net.Conn, error)
switch parsedUrl.Scheme {
case "http":
dial = net.Dial
case "https":
dial = func(net, addr string) (net.Conn, error) { return tls.Dial(net, addr, new(tls.Config)) }
default:
err = fmt.Errorf("Proxy URL scheme must be http or https, got: %s", parsedUrl.Scheme)
return
}
// dial the proxy
var conn net.Conn
if conn, err = dial(network, parsedUrl.Host); err != nil {
return
}
// send an HTTP proxy CONNECT message
req, err := http.NewRequest("CONNECT", "https://"+addr, nil)
if err != nil {
return
}
if proxyAuth != "" {
req.Header.Set("Proxy-Authorization", proxyAuth)
}
req.Header.Set("User-Agent", "Mozilla/5.0 (compatible; ngrok)")
req.Write(conn)
// read the proxy's response
resp, err := http.ReadResponse(bufio.NewReader(conn), req)
if err != nil {
return
}
resp.Body.Close()
if resp.StatusCode != 200 {
err = fmt.Errorf("Non-200 response from proxy server: %s", resp.Status)
return
}
// upgrade to TLS
conn = tls.Client(conn, tlsConfig)
return muxado.Client(conn), nil
}
}