-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathhttpconnect.go
79 lines (63 loc) · 2.28 KB
/
httpconnect.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
package main
// This file contains the HTTP CONNECT implementation of the proxy interface defined in proxy.go
import (
"bufio"
"encoding/base64"
"fmt"
"net"
"strings"
)
type httpConnect struct {
baseProxy
}
// address returns the address where the HTTP CONNECT proxy is exposed, i.e. proxy.host:proxy.port
func (p httpConnect) address() string {
return fmt.Sprintf("%s:%s", p.host, p.port)
}
// handshake takes net.Conn (representing a TCP socket) and an address and returns the same net.Conn connected to the provided address through the HTTP CONNECT proxy
func (p httpConnect) handshake(conn net.Conn, address string) (err error) {
gMetaLogger.Debugf("Entering CONNECT handshake(%v, %v)", conn, address)
defer func() { gMetaLogger.Debugf("Exiting CONNECT handshake(%v, %v)", conn, address) }()
if conn == nil {
err = fmt.Errorf("nil conn was provided")
return
}
reader := bufio.NewReader(conn)
host, _, err := net.SplitHostPort(address)
if err != nil {
return
}
var buff []byte
if p.user != "" {
gMetaLogger.Debugf("user is not empty, adding Proxy-Authorization header")
auth := base64.StdEncoding.EncodeToString([]byte(p.user + ":" + p.pass))
buff = []byte("CONNECT " + address + " HTTP/1.1\nHost: " + host + "\nProxy-Authorization: Basic " + auth + "\n\n")
} else {
buff = []byte("CONNECT " + address + " HTTP/1.1\nHost: " + host + "\n\n")
}
_, err = conn.Write(buff)
if err != nil {
return
}
gMetaLogger.Debugf("Wrote '%v' to the connection ", buff)
gMetaLogger.Debugf("Wrote '%v' to the connection ", string(buff))
response_line, err := reader.ReadString('\n')
if err != nil {
return
}
gMetaLogger.Debugf("proxy answer: %v", response_line)
if !(strings.HasPrefix(response_line, "HTTP/1.0 2") || strings.HasPrefix(response_line, "HTTP/1.1 2") || strings.HasPrefix(response_line, "HTTP/2 2")) {
err = fmt.Errorf("the proxy did not accept the connection and returned '%v'", response_line)
return
}
gMetaLogger.Debug("Connection accepted, reading headers")
for response_line != string([]byte{10}) && response_line != string([]byte{13, 10}) {
gMetaLogger.Debug("reading new header line")
response_line, err = reader.ReadString('\n')
if err != nil {
return
}
gMetaLogger.Debugf("Header line:\n%v%v", response_line, []byte(response_line))
}
return
}