diff --git a/conf/frpc_full.ini b/conf/frpc_full.ini index a0988e3..bcb61d2 100644 --- a/conf/frpc_full.ini +++ b/conf/frpc_full.ini @@ -88,7 +88,7 @@ http_pwd = admin # if domain for frps is frps.com, then you can access [web01] proxy by URL http://test.frps.com subdomain = web01 custom_domains = web02.yourdomain.com -# locations is only useful for http type +# locations is only available for http type locations = /,/pic host_header_rewrite = example.com diff --git a/tests/clean_test.sh b/tests/clean_test.sh index 6a6ef56..b0b3763 100755 --- a/tests/clean_test.sh +++ b/tests/clean_test.sh @@ -10,5 +10,11 @@ if [ -n "${pid}" ]; then kill ${pid} fi +pid=`ps aux|grep './../bin/frpc -c ./conf/auto_test_frpc_visitor.ini'|grep -v grep|awk {'print $2'}` +if [ -n "${pid}" ]; then + kill ${pid} +fi + rm -f ./frps.log rm -f ./frpc.log +rm -f ./frpc_visitor.log diff --git a/tests/conf/auto_test_frpc.ini b/tests/conf/auto_test_frpc.ini index d21f01f..2d243e8 100644 --- a/tests/conf/auto_test_frpc.ini +++ b/tests/conf/auto_test_frpc.ini @@ -6,30 +6,96 @@ log_file = ./frpc.log log_level = debug privilege_token = 123456 -[echo] +[tcp_normal] type = tcp local_ip = 127.0.0.1 local_port = 10701 -remote_port = 10711 -use_encryption = true -use_compression = true +remote_port = 10801 -[web] -type = http +[tcp_ec] +type = tcp local_ip = 127.0.0.1 -local_port = 10702 +local_port = 10701 +remote_port = 10901 use_encryption = true use_compression = true -custom_domains = 127.0.0.1 -[udp] +[udp_normal] type = udp local_ip = 127.0.0.1 -local_port = 10703 -remote_port = 10712 +local_port = 10702 +remote_port = 10802 + +[udp_ec] +type = udp +local_ip = 127.0.0.1 +local_port = 10702 +remote_port = 10902 +use_encryption = true +use_compression = true [unix_domain] type = tcp -remote_port = 10704 +remote_port = 10803 plugin = unix_domain_socket plugin_unix_path = /tmp/frp_echo_server.sock + +[stcp] +type = stcp +sk = abcdefg +local_ip = 127.0.0.1 +local_port = 10701 + +[stcp_ec] +type = stcp +sk = abc +local_ip = 127.0.0.1 +local_port = 10701 +use_encryption = true +use_compression = true + +[web01] +type = http +local_ip = 127.0.0.1 +local_port = 10704 +custom_domains = 127.0.0.1 + +[web02] +type = http +local_ip = 127.0.0.1 +local_port = 10704 +custom_domains = test2.frp.com +host_header_rewrite = test2.frp.com +use_encryption = true +use_compression = true + +[web03] +type = http +local_ip = 127.0.0.1 +local_port = 10704 +custom_domains = test3.frp.com +use_encryption = true +use_compression = true +host_header_rewrite = test3.frp.com +locations = /,/foo + +[web04] +type = http +local_ip = 127.0.0.1 +local_port = 10704 +custom_domains = test3.frp.com +use_encryption = true +use_compression = true +host_header_rewrite = test3.frp.com +locations = /bar + +[web05] +type = http +local_ip = 127.0.0.1 +local_port = 10704 +custom_domains = test5.frp.com +host_header_rewrite = test5.frp.com +use_encryption = true +use_compression = true +http_user = test +http_user = test diff --git a/tests/conf/auto_test_frpc_visitor.ini b/tests/conf/auto_test_frpc_visitor.ini new file mode 100644 index 0000000..cc524de --- /dev/null +++ b/tests/conf/auto_test_frpc_visitor.ini @@ -0,0 +1,25 @@ +[common] +server_addr = 0.0.0.0 +server_port = 10700 +log_file = ./frpc_visitor.log +# debug, info, warn, error +log_level = debug +privilege_token = 123456 + +[stcp_visitor] +type = stcp +role = visitor +server_name = stcp +sk = abcdefg +bind_addr = 127.0.0.1 +bind_port = 10805 + +[stcp_ec_visitor] +type = stcp +role = visitor +server_name = stcp_ec +sk = abc +bind_addr = 127.0.0.1 +bind_port = 10905 +use_encryption = true +use_compression = true diff --git a/tests/conf/auto_test_frps.ini b/tests/conf/auto_test_frps.ini index 3d93359..c03dc14 100644 --- a/tests/conf/auto_test_frps.ini +++ b/tests/conf/auto_test_frps.ini @@ -1,7 +1,7 @@ [common] bind_addr = 0.0.0.0 bind_port = 10700 -vhost_http_port = 10710 +vhost_http_port = 10804 log_file = ./frps.log log_level = debug privilege_token = 123456 diff --git a/tests/echo_server.go b/tests/echo_server.go index 47b87cb..5c73fef 100644 --- a/tests/echo_server.go +++ b/tests/echo_server.go @@ -11,7 +11,7 @@ import ( ) func StartTcpEchoServer() { - l, err := frpNet.ListenTcp("127.0.0.1", TEST_TCP_ECHO_PORT) + l, err := frpNet.ListenTcp("127.0.0.1", TEST_TCP_PORT) if err != nil { fmt.Printf("echo server listen error: %v\n", err) return @@ -29,7 +29,7 @@ func StartTcpEchoServer() { } func StartUdpEchoServer() { - l, err := frpNet.ListenUDP("127.0.0.1", TEST_UDP_ECHO_PORT) + l, err := frpNet.ListenUDP("127.0.0.1", TEST_UDP_PORT) if err != nil { fmt.Printf("udp echo server listen error: %v\n", err) return diff --git a/tests/func_test.go b/tests/func_test.go index 1ac2505..238046f 100644 --- a/tests/func_test.go +++ b/tests/func_test.go @@ -1,17 +1,10 @@ package tests import ( - "bufio" - "bytes" "fmt" - "io/ioutil" - "net" - "net/http" - "strings" "testing" "time" - frpNet "github.com/fatedier/frp/utils/net" "github.com/stretchr/testify/assert" ) @@ -22,17 +15,24 @@ var ( TEST_TCP_EC_FRP_PORT int64 = 10901 TEST_TCP_ECHO_STR string = "tcp type:" + TEST_STR - TEST_UDP_PORT int64 = 10702 - TEST_UDP_FRP_PORT int64 = 10802 - TEST_UDP_ECHO_STR string = "udp type:" + TEST_STR + TEST_UDP_PORT int64 = 10702 + TEST_UDP_FRP_PORT int64 = 10802 + TEST_UDP_EC_FRP_PORT int64 = 10902 + TEST_UDP_ECHO_STR string = "udp type:" + TEST_STR TEST_UNIX_DOMAIN_ADDR string = "/tmp/frp_echo_server.sock" TEST_UNIX_DOMAIN_FRP_PORT int64 = 10803 TEST_UNIX_DOMAIN_STR string = "unix domain type:" + TEST_STR - TEST_HTTP_PORT int64 = 10704 - TEST_HTTP_FRP_PORT int64 = 10804 - TEST_HTTP_WEB01_STR string = "http web01:" + TEST_STR + TEST_HTTP_PORT int64 = 10704 + TEST_HTTP_FRP_PORT int64 = 10804 + TEST_HTTP_NORMAL_STR string = "http normal string: " + TEST_STR + TEST_HTTP_FOO_STR string = "http foo string: " + TEST_STR + TEST_HTTP_BAR_STR string = "http bar string: " + TEST_STR + + TEST_STCP_FRP_PORT int64 = 10805 + TEST_STCP_EC_FRP_PORT int64 = 10905 + TEST_STCP_ECHO_STR string = "stcp type:" + TEST_STR ) func init() { @@ -43,7 +43,7 @@ func init() { time.Sleep(500 * time.Millisecond) } -func TestTcpServer(t *testing.T) { +func TestTcp(t *testing.T) { assert := assert.New(t) // Normal addr := fmt.Sprintf("127.0.0.1:%d", TEST_TCP_FRP_PORT) @@ -58,7 +58,7 @@ func TestTcpServer(t *testing.T) { assert.Equal(TEST_TCP_ECHO_STR, res) } -func TestUdpEchoServer(t *testing.T) { +func TestUdp(t *testing.T) { assert := assert.New(t) // Normal addr := fmt.Sprintf("127.0.0.1:%d", TEST_UDP_FRP_PORT) @@ -66,32 +66,92 @@ func TestUdpEchoServer(t *testing.T) { assert.NoError(err) assert.Equal(TEST_UDP_ECHO_STR, res) -func TestUnixDomainServer(t *testing.T) { + // Encrytion and compression + addr = fmt.Sprintf("127.0.0.1:%d", TEST_UDP_EC_FRP_PORT) + res, err = sendUdpMsg(addr, TEST_UDP_ECHO_STR) + assert.NoError(err) + assert.Equal(TEST_UDP_ECHO_STR, res) +} + +func TestUnixDomain(t *testing.T) { assert := assert.New(t) // Normal addr := fmt.Sprintf("127.0.0.1:%d", TEST_UNIX_DOMAIN_FRP_PORT) res, err := sendTcpMsg(addr, TEST_UNIX_DOMAIN_STR) - assert.NoError(err) - assert.Equal(TEST_UNIX_DOMAIN_STR, res) + if assert.NoError(err) { + assert.Equal(TEST_UNIX_DOMAIN_STR, res) + } } -func TestHttpServer(t *testing.T) { - client := &http.Client{} - req, _ := http.NewRequest("GET", fmt.Sprintf("http://127.0.0.1:%d", HTTP_PORT), nil) - res, err := client.Do(req) - if err != nil { - t.Fatalf("do http request error: %v", err) +func TestStcp(t *testing.T) { + assert := assert.New(t) + // Normal + addr := fmt.Sprintf("127.0.0.1:%d", TEST_STCP_FRP_PORT) + res, err := sendTcpMsg(addr, TEST_STCP_ECHO_STR) + if assert.NoError(err) { + assert.Equal(TEST_STCP_ECHO_STR, res) } - if res.StatusCode == 200 { - body, err := ioutil.ReadAll(res.Body) - if err != nil { - t.Fatalf("read from http server error: %v", err) - } - bodystr := string(body) - if bodystr != HTTP_RES_STR { - t.Fatalf("content from http server error [%s], correct string is [%s]", bodystr, HTTP_RES_STR) - } - } else { - t.Fatalf("http code from http server error [%d]", res.StatusCode) + + // Encrytion and compression + addr = fmt.Sprintf("127.0.0.1:%d", TEST_STCP_EC_FRP_PORT) + res, err = sendTcpMsg(addr, TEST_STCP_ECHO_STR) + if assert.NoError(err) { + assert.Equal(TEST_STCP_ECHO_STR, res) + } +} + +func TestHttp(t *testing.T) { + assert := assert.New(t) + // web01 + code, body, err := sendHttpMsg("GET", fmt.Sprintf("http://127.0.0.1:%d", TEST_HTTP_FRP_PORT), "", nil) + if assert.NoError(err) { + assert.Equal(200, code) + assert.Equal(TEST_HTTP_NORMAL_STR, body) + } + + // web02 + code, body, err = sendHttpMsg("GET", fmt.Sprintf("http://127.0.0.1:%d", TEST_HTTP_FRP_PORT), "test2.frp.com", nil) + if assert.NoError(err) { + assert.Equal(200, code) + assert.Equal(TEST_HTTP_NORMAL_STR, body) + } + + // error host header + code, body, err = sendHttpMsg("GET", fmt.Sprintf("http://127.0.0.1:%d", TEST_HTTP_FRP_PORT), "errorhost.frp.com", nil) + if assert.NoError(err) { + assert.Equal(404, code) + } + + // web03 + code, body, err = sendHttpMsg("GET", fmt.Sprintf("http://127.0.0.1:%d", TEST_HTTP_FRP_PORT), "test3.frp.com", nil) + if assert.NoError(err) { + assert.Equal(200, code) + assert.Equal(TEST_HTTP_NORMAL_STR, body) + } + + code, body, err = sendHttpMsg("GET", fmt.Sprintf("http://127.0.0.1:%d/foo", TEST_HTTP_FRP_PORT), "test3.frp.com", nil) + if assert.NoError(err) { + assert.Equal(200, code) + assert.Equal(TEST_HTTP_FOO_STR, body) + } + + // web04 + code, body, err = sendHttpMsg("GET", fmt.Sprintf("http://127.0.0.1:%d/bar", TEST_HTTP_FRP_PORT), "test3.frp.com", nil) + if assert.NoError(err) { + assert.Equal(200, code) + assert.Equal(TEST_HTTP_BAR_STR, body) + } + + // web05 + code, body, err = sendHttpMsg("GET", fmt.Sprintf("http://127.0.0.1:%d", TEST_HTTP_FRP_PORT), "test5.frp.com", nil) + if assert.NoError(err) { + assert.Equal(401, code) + } + + header := make(map[string]string) + header["Authorization"] = basicAuth("test", "test") + code, body, err = sendHttpMsg("GET", fmt.Sprintf("http://127.0.0.1:%d", TEST_HTTP_FRP_PORT), "test5.frp.com", header) + if assert.NoError(err) { + assert.Equal(401, code) } } diff --git a/tests/http_server.go b/tests/http_server.go index 29eaa4d..6564d1d 100644 --- a/tests/http_server.go +++ b/tests/http_server.go @@ -3,13 +3,30 @@ package tests import ( "fmt" "net/http" + "strings" ) func StartHttpServer() { http.HandleFunc("/", request) - http.ListenAndServe(fmt.Sprintf("0.0.0.0:%d", 10702), nil) + http.ListenAndServe(fmt.Sprintf("0.0.0.0:%d", TEST_HTTP_PORT), nil) } func request(w http.ResponseWriter, r *http.Request) { - w.Write([]byte(HTTP_RES_STR)) + if strings.Contains(r.Host, "127.0.0.1") || strings.Contains(r.Host, "test2.frp.com") || + strings.Contains(r.Host, "test5.frp.com") { + w.WriteHeader(200) + w.Write([]byte(TEST_HTTP_NORMAL_STR)) + } else if strings.Contains(r.Host, "test3.frp.com") { + w.WriteHeader(200) + if strings.Contains(r.URL.Path, "foo") { + w.Write([]byte(TEST_HTTP_FOO_STR)) + } else if strings.Contains(r.URL.Path, "bar") { + w.Write([]byte(TEST_HTTP_BAR_STR)) + } else { + w.Write([]byte(TEST_HTTP_NORMAL_STR)) + } + } else { + w.WriteHeader(404) + } + return } diff --git a/tests/run_test.sh b/tests/run_test.sh index 5ef490a..a852a3d 100755 --- a/tests/run_test.sh +++ b/tests/run_test.sh @@ -3,6 +3,7 @@ ./../bin/frps -c ./conf/auto_test_frps.ini & sleep 1 ./../bin/frpc -c ./conf/auto_test_frpc.ini & +./../bin/frpc -c ./conf/auto_test_frpc_visitor.ini & # wait until proxies are connected sleep 2 diff --git a/tests/util.go b/tests/util.go index 0352463..9eed580 100644 --- a/tests/util.go +++ b/tests/util.go @@ -1,8 +1,11 @@ -package test +package tests import ( + "encoding/base64" "fmt" + "io/ioutil" "net" + "net/http" "time" frpNet "github.com/fatedier/frp/utils/net" @@ -10,11 +13,11 @@ import ( func sendTcpMsg(addr string, msg string) (res string, err error) { c, err := frpNet.ConnectTcpServer(addr) - defer c.Close() if err != nil { err = fmt.Errorf("connect to tcp server error: %v", err) return } + defer c.Close() timer := time.Now().Add(5 * time.Second) c.SetDeadline(timer) @@ -55,3 +58,36 @@ func sendUdpMsg(addr string, msg string) (res string, err error) { } return string(buf[:n]), nil } + +func sendHttpMsg(method, url string, host string, header map[string]string) (code int, body string, err error) { + req, errRet := http.NewRequest(method, url, nil) + if errRet != nil { + err = errRet + return + } + + if host != "" { + req.Host = host + } + for k, v := range header { + req.Header.Set(k, v) + } + resp, errRet := http.DefaultClient.Do(req) + if errRet != nil { + err = errRet + return + } + code = resp.StatusCode + buf, errRet := ioutil.ReadAll(resp.Body) + if errRet != nil { + err = errRet + return + } + body = string(buf) + return +} + +func basicAuth(username, passwd string) string { + auth := username + ":" + passwd + return "Basic " + base64.StdEncoding.EncodeToString([]byte(auth)) +}