gost_software/http_test.go
2017-08-13 09:30:18 +08:00

128 lines
3.4 KiB
Go

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
}
}
}