/
httpproxy.go
127 lines (119 loc) · 2.2 KB
/
httpproxy.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
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
package main
import (
"bufio"
"errors"
"io"
"log"
"net"
"net/http"
"strconv"
"strings"
)
func int2nl(i int) []byte {
b := make([]byte, 2)
b[0] = byte((i & 0xffff) >> 8)
b[1] = byte(i & 0xff)
return b
}
func handshakeWithSocksServer(conn net.Conn) bool {
conn.Write([]byte("\x05\x01\x00"))
b := make([]byte, 2)
conn.Read(b)
return b[0] == 5 && b[1] == 0
}
func connectSocksServer(socks net.Conn, domain string, port int) (err error) {
handshakeWithSocksServer(socks)
w := bufio.NewWriter(socks)
//send connect command
w.Write([]byte("\x05\x01\x00\x03"))
w.WriteByte(byte(len(domain)))
w.Write([]byte(domain))
w.Write(int2nl(port))
w.Flush()
b := make([]byte, 256)
socks.Read(b[:4])
if b[0] != 5 || b[1] != 0 {
return errors.New("cannot connect to server")
}
switch b[3] {
case 1: //ipv4
socks.Read(b[:6]) //discard the result
case 3:
socks.Read(b[:1])
socks.Read(b[:b[0]+2])
case 4:
socks.Read(b[:16])
}
return
}
func HandleHTTP(conn net.Conn) {
defer conn.Close()
r := bufio.NewReader(conn)
req, err := http.ReadRequest(r)
if err != nil || req == nil {
log.Print("Invalid HTTP Request: ", err)
return
}
var domain string
var port int
slices := strings.Split(req.Host, ":")
if len(slices) == 1 {
port = 80
} else {
port, _ = strconv.Atoi(slices[1])
}
domain = slices[0]
socks, err := net.Dial("tcp", client_listen)
if err != nil {
return
}
defer socks.Close()
err = connectSocksServer(socks, domain, port)
if err != nil {
log.Printf("cannot connect to server:%s", req.Host)
return
}
if req.Method == "CONNECT" {
io.WriteString(conn, "HTTP/1.1 200 OK\r\n\r\n")
} else {
req.Write(socks)
}
b := make([]byte, 1024*32)
var re, we error
var n int
go func() {
b := make([]byte, 1024*4)
for {
n, re = r.Read(b)
if n > 0 {
_, we = socks.Write(b[:n])
}
if re != nil || we != nil {
return
}
}
}()
for {
n, re = socks.Read(b)
if n > 0 {
_, we = conn.Write(b[:n])
}
if re != nil || we != nil {
return
}
}
}
func startHTTPProxyServer(addr string) {
lsn, e := net.Listen("tcp", addr)
if e != nil {
log.Fatal(e)
}
for {
conn, e := lsn.Accept()
if e != nil {
log.Print(e)
continue
}
go HandleHTTP(conn)
}
}