forked from ginuerzh/gost
-
Notifications
You must be signed in to change notification settings - Fork 0
/
http_test.go
127 lines (119 loc) · 3.42 KB
/
http_test.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 gost
import (
"bufio"
"bytes"
"crypto/rand"
"io"
"io/ioutil"
"net/http"
"net/http/httptest"
"net/url"
"testing"
)
var httpTestHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
io.Copy(w, r.Body)
})
func httpProxyRoundtrip(urlStr string, cliUser *url.Userinfo, srvUsers []*url.Userinfo, body io.Reader) (statusCode int, recv []byte, err error) {
ln, err := TCPListener("")
if err != nil {
return
}
h := HTTPHandler(UsersHandlerOption(srvUsers...))
server := &Server{Listener: ln}
go server.Serve(h)
exitChan := make(chan struct{})
defer close(exitChan)
go func() {
defer server.Close()
<-exitChan
}()
client := &Client{
Connector: HTTPConnector(cliUser),
Transporter: TCPTransporter(),
}
conn, err := client.Dial(ln.Addr().String())
if err != nil {
return
}
defer conn.Close()
conn, err = client.Handshake(conn)
if err != nil {
return
}
url, err := url.Parse(urlStr)
if err != nil {
return
}
conn, err = client.Connect(conn, url.Host)
if err != nil {
return
}
req, err := http.NewRequest(http.MethodGet, urlStr, body)
if err != nil {
return
}
if err = req.Write(conn); err != nil {
return
}
resp, err := http.ReadResponse(bufio.NewReader(conn), req)
if err != nil {
return
}
defer resp.Body.Close()
statusCode = resp.StatusCode
recv, err = ioutil.ReadAll(resp.Body)
return
}
var httpProxyTests = []struct {
url string
cliUser *url.Userinfo
srvUsers []*url.Userinfo
errStr string
}{
{"", nil, nil, ""},
{"", nil, []*url.Userinfo{url.User("admin")}, "407 Proxy Authentication Required"},
{"", nil, []*url.Userinfo{url.UserPassword("", "123456")}, "407 Proxy Authentication Required"},
{"", url.User("admin"), []*url.Userinfo{url.User("test")}, "407 Proxy Authentication Required"},
{"", url.User("admin"), []*url.Userinfo{url.UserPassword("admin", "123456")}, "407 Proxy Authentication Required"},
{"", url.User("admin"), []*url.Userinfo{url.User("admin")}, ""},
{"", url.User("admin"), []*url.Userinfo{url.UserPassword("admin", "")}, ""},
{"", url.UserPassword("admin", "123456"), nil, ""},
{"", url.UserPassword("admin", "123456"), []*url.Userinfo{url.User("admin")}, ""},
{"", url.UserPassword("admin", "123456"), []*url.Userinfo{url.UserPassword("", "123456")}, ""},
{"", url.UserPassword("", "123456"), []*url.Userinfo{url.UserPassword("", "123456")}, ""},
{"", url.UserPassword("admin", "123456"), []*url.Userinfo{url.UserPassword("admin", "123456")}, ""},
{"", url.UserPassword("admin", "123456"), []*url.Userinfo{url.UserPassword("user", "pass"), url.UserPassword("admin", "123456")}, ""},
{"http://:0", nil, nil, "503 Service unavailable"},
}
func TestHTTPProxy(t *testing.T) {
Debug = true
httpSrv := httptest.NewServer(httpTestHandler)
defer httpSrv.Close()
for _, test := range httpProxyTests {
send := make([]byte, 16)
rand.Read(send)
urlStr := test.url
if urlStr == "" {
urlStr = httpSrv.URL
}
_, recv, err := httpProxyRoundtrip(urlStr, test.cliUser, test.srvUsers, bytes.NewReader(send))
if err == nil {
if test.errStr != "" {
t.Errorf("HTTP proxy response should failed with error %s", test.errStr)
continue
}
} else {
if test.errStr == "" {
t.Errorf("HTTP proxy got error %v", err)
}
if err.Error() != test.errStr {
t.Errorf("HTTP proxy got error %v, want %v", err, test.errStr)
}
continue
}
if !bytes.Equal(send, recv) {
t.Errorf("got %v, want %v", recv, send)
continue
}
}
}