add test cases for HTTP/HTTP2 probing resistance
This commit is contained in:
parent
445889c47e
commit
82003f4270
1
.testdata/probe_resist.txt
Normal file
1
.testdata/probe_resist.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
Hello World!
|
@ -211,6 +211,22 @@ var bypassReloadTests = []struct {
|
|||||||
bypassed: true,
|
bypassed: true,
|
||||||
stopped: false,
|
stopped: false,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
r: bytes.NewBufferString("#reverse true\n#reload 10s\n192.168.0.0/16"),
|
||||||
|
reversed: false,
|
||||||
|
period: 0,
|
||||||
|
addr: "192.168.10.2",
|
||||||
|
bypassed: true,
|
||||||
|
stopped: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
r: bytes.NewBufferString("#reverse true\n#reload 10s\n192.168.1.0/24"),
|
||||||
|
reversed: false,
|
||||||
|
period: 0,
|
||||||
|
addr: "192.168.10.2",
|
||||||
|
bypassed: false,
|
||||||
|
stopped: true,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
r: bytes.NewBufferString("reverse false\nreload 10s\n192.168.1.1\n#example.com"),
|
r: bytes.NewBufferString("reverse false\nreload 10s\n192.168.1.1\n#example.com"),
|
||||||
reversed: false,
|
reversed: false,
|
||||||
@ -227,6 +243,30 @@ var bypassReloadTests = []struct {
|
|||||||
bypassed: true,
|
bypassed: true,
|
||||||
stopped: true,
|
stopped: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
r: bytes.NewBufferString("#reverse true\n#reload 10s\nexample.com"),
|
||||||
|
reversed: false,
|
||||||
|
period: 0,
|
||||||
|
addr: "example.com",
|
||||||
|
bypassed: true,
|
||||||
|
stopped: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
r: bytes.NewBufferString("#reverse true\n#reload 10s\n.example.com"),
|
||||||
|
reversed: false,
|
||||||
|
period: 0,
|
||||||
|
addr: "example.com",
|
||||||
|
bypassed: true,
|
||||||
|
stopped: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
r: bytes.NewBufferString("#reverse true\n#reload 10s\n*.example.com"),
|
||||||
|
reversed: false,
|
||||||
|
period: 0,
|
||||||
|
addr: "example.com",
|
||||||
|
bypassed: false,
|
||||||
|
stopped: true,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestByapssReload(t *testing.T) {
|
func TestByapssReload(t *testing.T) {
|
||||||
@ -235,6 +275,8 @@ func TestByapssReload(t *testing.T) {
|
|||||||
if err := bp.Reload(tc.r); err != nil {
|
if err := bp.Reload(tc.r); err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
|
t.Log(bp.String())
|
||||||
|
|
||||||
if bp.Reversed() != tc.reversed {
|
if bp.Reversed() != tc.reversed {
|
||||||
t.Errorf("#%d test failed: reversed value should be %v, got %v",
|
t.Errorf("#%d test failed: reversed value should be %v, got %v",
|
||||||
i, tc.reversed, bp.reversed)
|
i, tc.reversed, bp.reversed)
|
||||||
@ -251,6 +293,7 @@ func TestByapssReload(t *testing.T) {
|
|||||||
if bp.Period() >= 0 {
|
if bp.Period() >= 0 {
|
||||||
t.Errorf("period of the stopped reloader should be minus value")
|
t.Errorf("period of the stopped reloader should be minus value")
|
||||||
}
|
}
|
||||||
|
bp.Stop()
|
||||||
}
|
}
|
||||||
if bp.Stopped() != tc.stopped {
|
if bp.Stopped() != tc.stopped {
|
||||||
t.Errorf("#%d test failed: stopped value should be %v, got %v",
|
t.Errorf("#%d test failed: stopped value should be %v, got %v",
|
||||||
|
@ -16,8 +16,8 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
// SetLogger(&LogLogger{})
|
SetLogger(&NopLogger{})
|
||||||
// Debug = true
|
Debug = true
|
||||||
DialTimeout = 1000 * time.Millisecond
|
DialTimeout = 1000 * time.Millisecond
|
||||||
HandshakeTimeout = 1000 * time.Millisecond
|
HandshakeTimeout = 1000 * time.Millisecond
|
||||||
ConnectTimeout = 1000 * time.Millisecond
|
ConnectTimeout = 1000 * time.Millisecond
|
||||||
@ -33,7 +33,11 @@ func init() {
|
|||||||
|
|
||||||
var (
|
var (
|
||||||
httpTestHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
httpTestHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||||
io.Copy(w, r.Body)
|
data, _ := ioutil.ReadAll(r.Body)
|
||||||
|
if len(data) == 0 {
|
||||||
|
data = []byte("Hello World!")
|
||||||
|
}
|
||||||
|
io.Copy(w, bytes.NewReader(data))
|
||||||
})
|
})
|
||||||
|
|
||||||
udpTestHandler = udpHandlerFunc(func(w io.Writer, r *udpRequest) {
|
udpTestHandler = udpHandlerFunc(func(w io.Writer, r *udpRequest) {
|
||||||
|
184
http2_test.go
184
http2_test.go
@ -1,9 +1,12 @@
|
|||||||
package gost
|
package gost
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"net/url"
|
"net/url"
|
||||||
"testing"
|
"testing"
|
||||||
@ -920,3 +923,184 @@ func TestH2CForwardTunnel(t *testing.T) {
|
|||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestHTTP2ProxyWithCodeProbeResist(t *testing.T) {
|
||||||
|
httpSrv := httptest.NewServer(httpTestHandler)
|
||||||
|
defer httpSrv.Close()
|
||||||
|
|
||||||
|
ln, err := HTTP2Listener("", nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
client := &Client{
|
||||||
|
Connector: HTTP2Connector(nil),
|
||||||
|
Transporter: HTTP2Transporter(nil),
|
||||||
|
}
|
||||||
|
|
||||||
|
server := &Server{
|
||||||
|
Listener: ln,
|
||||||
|
Handler: HTTP2Handler(
|
||||||
|
UsersHandlerOption(url.UserPassword("admin", "123456")),
|
||||||
|
ProbeResistHandlerOption("code:400"),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
go server.Run()
|
||||||
|
defer server.Close()
|
||||||
|
|
||||||
|
err = proxyRoundtrip(client, server, httpSrv.URL, nil)
|
||||||
|
if err == nil {
|
||||||
|
t.Error("should failed with status code 400")
|
||||||
|
} else if err.Error() != "400 Bad Request" {
|
||||||
|
t.Error("should failed with status code 400, got", err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHTTP2ProxyWithWebProbeResist(t *testing.T) {
|
||||||
|
httpSrv := httptest.NewServer(httpTestHandler)
|
||||||
|
defer httpSrv.Close()
|
||||||
|
|
||||||
|
ln, err := HTTP2Listener("", nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
client := &Client{
|
||||||
|
Connector: HTTP2Connector(nil),
|
||||||
|
Transporter: HTTP2Transporter(nil),
|
||||||
|
}
|
||||||
|
|
||||||
|
server := &Server{
|
||||||
|
Listener: ln,
|
||||||
|
Handler: HTTP2Handler(
|
||||||
|
UsersHandlerOption(url.UserPassword("admin", "123456")),
|
||||||
|
ProbeResistHandlerOption("web:"+httpSrv.URL),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
go server.Run()
|
||||||
|
defer server.Close()
|
||||||
|
|
||||||
|
conn, err := proxyConn(client, server)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
defer conn.Close()
|
||||||
|
|
||||||
|
conn, err = client.Connect(conn, "github.com:443")
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
recv, _ := ioutil.ReadAll(conn)
|
||||||
|
if !bytes.Equal(recv, []byte("Hello World!")) {
|
||||||
|
t.Error("data not equal")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHTTP2ProxyWithHostProbeResist(t *testing.T) {
|
||||||
|
httpSrv := httptest.NewServer(httpTestHandler)
|
||||||
|
defer httpSrv.Close()
|
||||||
|
|
||||||
|
sendData := make([]byte, 128)
|
||||||
|
rand.Read(sendData)
|
||||||
|
|
||||||
|
ln, err := HTTP2Listener("", nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
client := &Client{
|
||||||
|
Connector: HTTP2Connector(nil),
|
||||||
|
Transporter: HTTP2Transporter(nil),
|
||||||
|
}
|
||||||
|
|
||||||
|
u, err := url.Parse(httpSrv.URL)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
server := &Server{
|
||||||
|
Listener: ln,
|
||||||
|
Handler: HTTP2Handler(
|
||||||
|
UsersHandlerOption(url.UserPassword("admin", "123456")),
|
||||||
|
ProbeResistHandlerOption("host:"+u.Host),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
go server.Run()
|
||||||
|
defer server.Close()
|
||||||
|
|
||||||
|
conn, err := proxyConn(client, server)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
defer conn.Close()
|
||||||
|
|
||||||
|
cc, ok := conn.(*http2ClientConn)
|
||||||
|
if !ok {
|
||||||
|
t.Error("wrong connection type")
|
||||||
|
}
|
||||||
|
|
||||||
|
req := &http.Request{
|
||||||
|
Method: http.MethodConnect,
|
||||||
|
URL: &url.URL{Scheme: "https", Host: ln.Addr().String()},
|
||||||
|
Header: make(http.Header),
|
||||||
|
Proto: "HTTP/2.0",
|
||||||
|
ProtoMajor: 2,
|
||||||
|
ProtoMinor: 0,
|
||||||
|
Body: ioutil.NopCloser(bytes.NewReader(sendData)),
|
||||||
|
Host: cc.addr,
|
||||||
|
ContentLength: -1,
|
||||||
|
}
|
||||||
|
req.Header.Set("Gost-Target", "github.com:443")
|
||||||
|
|
||||||
|
resp, err := cc.client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
if resp.StatusCode != http.StatusOK {
|
||||||
|
t.Error("got non-200 status:", resp.Status)
|
||||||
|
}
|
||||||
|
|
||||||
|
recv, _ := ioutil.ReadAll(resp.Body)
|
||||||
|
if !bytes.Equal(sendData, recv) {
|
||||||
|
t.Error("data not equal")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHTTP2ProxyWithFileProbeResist(t *testing.T) {
|
||||||
|
ln, err := HTTP2Listener("", nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
client := &Client{
|
||||||
|
Connector: HTTP2Connector(nil),
|
||||||
|
Transporter: HTTP2Transporter(nil),
|
||||||
|
}
|
||||||
|
|
||||||
|
server := &Server{
|
||||||
|
Listener: ln,
|
||||||
|
Handler: HTTP2Handler(
|
||||||
|
UsersHandlerOption(url.UserPassword("admin", "123456")),
|
||||||
|
ProbeResistHandlerOption("file:.testdata/probe_resist.txt"),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
go server.Run()
|
||||||
|
defer server.Close()
|
||||||
|
|
||||||
|
conn, err := proxyConn(client, server)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
defer conn.Close()
|
||||||
|
|
||||||
|
conn, err = client.Connect(conn, "github.com:443")
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
recv, _ := ioutil.ReadAll(conn)
|
||||||
|
if !bytes.Equal(recv, []byte("Hello World!")) {
|
||||||
|
t.Error("data not equal")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
156
http_test.go
156
http_test.go
@ -1,7 +1,11 @@
|
|||||||
package gost
|
package gost
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"bytes"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
|
"fmt"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
"net/http/httptest"
|
"net/http/httptest"
|
||||||
"net/url"
|
"net/url"
|
||||||
"testing"
|
"testing"
|
||||||
@ -59,6 +63,8 @@ func TestHTTPProxy(t *testing.T) {
|
|||||||
rand.Read(sendData)
|
rand.Read(sendData)
|
||||||
|
|
||||||
for i, tc := range httpProxyTests {
|
for i, tc := range httpProxyTests {
|
||||||
|
tc := tc
|
||||||
|
t.Run(fmt.Sprintf("#%d", i), func(t *testing.T) {
|
||||||
err := httpProxyRoundtrip(httpSrv.URL, sendData, tc.cliUser, tc.srvUsers)
|
err := httpProxyRoundtrip(httpSrv.URL, sendData, tc.cliUser, tc.srvUsers)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
if tc.errStr != "" {
|
if tc.errStr != "" {
|
||||||
@ -72,6 +78,7 @@ func TestHTTPProxy(t *testing.T) {
|
|||||||
t.Errorf("#%d got error %v, want %v", i, err, tc.errStr)
|
t.Errorf("#%d got error %v, want %v", i, err, tc.errStr)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -142,3 +149,152 @@ func BenchmarkHTTPProxyParallel(b *testing.B) {
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestHTTPProxyWithCodeProbeResist(t *testing.T) {
|
||||||
|
ln, err := TCPListener("")
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
server := &Server{
|
||||||
|
Listener: ln,
|
||||||
|
Handler: HTTPHandler(
|
||||||
|
UsersHandlerOption(url.UserPassword("admin", "123456")),
|
||||||
|
ProbeResistHandlerOption("code:400"),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
go server.Run()
|
||||||
|
defer server.Close()
|
||||||
|
|
||||||
|
resp, err := http.Get("http://" + ln.Addr().String())
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
if resp.StatusCode != 400 {
|
||||||
|
t.Error("should failed with status code 400, got", resp.Status)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHTTPProxyWithWebProbeResist(t *testing.T) {
|
||||||
|
httpSrv := httptest.NewServer(httpTestHandler)
|
||||||
|
defer httpSrv.Close()
|
||||||
|
|
||||||
|
ln, err := TCPListener("")
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
server := &Server{
|
||||||
|
Listener: ln,
|
||||||
|
Handler: HTTPHandler(
|
||||||
|
UsersHandlerOption(url.UserPassword("admin", "123456")),
|
||||||
|
ProbeResistHandlerOption("web:"+httpSrv.URL),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
go server.Run()
|
||||||
|
defer server.Close()
|
||||||
|
|
||||||
|
r, err := http.NewRequest("GET", "http://"+ln.Addr().String(), nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
resp, err := http.DefaultClient.Do(r)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
if resp.StatusCode != 200 {
|
||||||
|
t.Error("got status:", resp.Status)
|
||||||
|
}
|
||||||
|
|
||||||
|
recv, _ := ioutil.ReadAll(resp.Body)
|
||||||
|
if !bytes.Equal(recv, []byte("Hello World!")) {
|
||||||
|
t.Error("data not equal")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHTTPProxyWithHostProbeResist(t *testing.T) {
|
||||||
|
httpSrv := httptest.NewServer(httpTestHandler)
|
||||||
|
defer httpSrv.Close()
|
||||||
|
|
||||||
|
sendData := make([]byte, 128)
|
||||||
|
rand.Read(sendData)
|
||||||
|
|
||||||
|
ln, err := TCPListener("")
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
u, err := url.Parse(httpSrv.URL)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
server := &Server{
|
||||||
|
Listener: ln,
|
||||||
|
Handler: HTTPHandler(
|
||||||
|
UsersHandlerOption(url.UserPassword("admin", "123456")),
|
||||||
|
ProbeResistHandlerOption("host:"+u.Host),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
go server.Run()
|
||||||
|
defer server.Close()
|
||||||
|
|
||||||
|
r, err := http.NewRequest("GET", "http://"+ln.Addr().String(), bytes.NewReader(sendData))
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
resp, err := http.DefaultClient.Do(r)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
if resp.StatusCode != 200 {
|
||||||
|
t.Error("got status:", resp.Status)
|
||||||
|
}
|
||||||
|
|
||||||
|
recv, _ := ioutil.ReadAll(resp.Body)
|
||||||
|
if !bytes.Equal(sendData, recv) {
|
||||||
|
t.Error("data not equal")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestHTTPProxyWithFileProbeResist(t *testing.T) {
|
||||||
|
ln, err := TCPListener("")
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
server := &Server{
|
||||||
|
Listener: ln,
|
||||||
|
Handler: HTTPHandler(
|
||||||
|
UsersHandlerOption(url.UserPassword("admin", "123456")),
|
||||||
|
ProbeResistHandlerOption("file:.testdata/probe_resist.txt"),
|
||||||
|
),
|
||||||
|
}
|
||||||
|
go server.Run()
|
||||||
|
defer server.Close()
|
||||||
|
|
||||||
|
r, err := http.NewRequest("GET", "http://"+ln.Addr().String(), nil)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
resp, err := http.DefaultClient.Do(r)
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
if resp.StatusCode != 200 {
|
||||||
|
t.Error("got status:", resp.Status)
|
||||||
|
}
|
||||||
|
|
||||||
|
recv, _ := ioutil.ReadAll(resp.Body)
|
||||||
|
if !bytes.Equal(recv, []byte("Hello World!")) {
|
||||||
|
t.Error("data not equal, got:", string(recv))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
name: gost
|
name: gost
|
||||||
version: '2.6'
|
version: '2.7'
|
||||||
summary: GO Simple Tunnel
|
summary: GO Simple Tunnel
|
||||||
description: |
|
description: |
|
||||||
A simple tunnel written in golang
|
A simple tunnel written in golang
|
||||||
@ -14,7 +14,7 @@ apps:
|
|||||||
|
|
||||||
parts:
|
parts:
|
||||||
go:
|
go:
|
||||||
source-tag: go1.10
|
source-tag: go1.11
|
||||||
gost:
|
gost:
|
||||||
after: [go]
|
after: [go]
|
||||||
source: .
|
source: .
|
||||||
|
Loading…
Reference in New Issue
Block a user