make e2e echoserver support more protocals
This commit is contained in:
parent
3621aad1c1
commit
6db422957e
@ -23,7 +23,6 @@ import (
|
||||
"gopkg.in/ini.v1"
|
||||
)
|
||||
|
||||
|
||||
// Visitor
|
||||
var (
|
||||
visitorConfTypeMap = map[string]reflect.Type{
|
||||
@ -64,7 +63,6 @@ type XTCPVisitorConf struct {
|
||||
BaseVisitorConf `ini:",extends" json:"inline"`
|
||||
}
|
||||
|
||||
|
||||
// DefaultVisitorConf creates a empty VisitorConf object by visitorType.
|
||||
// If visitorType doesn't exist, return nil.
|
||||
func DefaultVisitorConf(visitorType string) VisitorConf {
|
||||
|
@ -19,8 +19,8 @@ import (
|
||||
|
||||
"github.com/fatedier/frp/pkg/consts"
|
||||
|
||||
"gopkg.in/ini.v1"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"gopkg.in/ini.v1"
|
||||
)
|
||||
|
||||
const testVisitorPrefix = "test."
|
||||
|
19
test/e2e/e2e.crt
Normal file
19
test/e2e/e2e.crt
Normal file
@ -0,0 +1,19 @@
|
||||
-----BEGIN CERTIFICATE-----
|
||||
MIIDGDCCAgCgAwIBAgIJAP/5mYzCo9TZMA0GCSqGSIb3DQEBBQUAMBkxFzAVBgNV
|
||||
BAMMDmV4YW1wbGUuY2EuY29tMB4XDTIxMDEyNzA4MDUyNFoXDTMxMDEyNTA4MDUy
|
||||
NFowVTELMAkGA1UEBhMCWFgxEDAOBgNVBAgMB0RFRkFVTFQxEDAOBgNVBAcMB0RF
|
||||
RkFVTFQxEDAOBgNVBAoMB0RFRkFVTFQxEDAOBgNVBAMMB2UyZS5jb20wggEiMA0G
|
||||
CSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDHzTaYcphSLOsV/PEWkv0XK2+hriyj
|
||||
+GegXct3H7K6KxWoHMSAjmSpdGgm2/D7r4hAtAid9WpAZXExG++LGR5G/wFDMAia
|
||||
FZiE+GwU20fGRsBhJVItIHVf/KwYSPBFHKCuqV0kY9Mkw1GOYZ9N33eaI4ouCSc6
|
||||
QphOgF7jRaaycXUaOLIHAYK/+QlEHi+qj5CzVqshI0YkWHY30Mvf1FmgdkCidJUC
|
||||
R8OLsnc8/OJMjb+7s7rL7vdKBoRau1G1vdRwH26Xk3dq5K5BTwtCYiXjR8JmDQMS
|
||||
4VoTg9BzGujd7IhTG3BVWNHo93FkmUfLaBEAdLVctBdC9J0sQviwBIV7AgMBAAGj
|
||||
JzAlMCMGA1UdEQQcMBqCCWxvY2FsaG9zdIcEfwAAAYIHZTJlLmNvbTANBgkqhkiG
|
||||
9w0BAQUFAAOCAQEA1blvgPF2Ey1sflkqKKJBzq8Vvh4UnHrsY1v01zAZHe6iJvTL
|
||||
UfkBSiU4eYE5EAOHPCilLjmG1sqdnCeXdglOqYZB0SOrBsIYhqKbfn+IlfQCS34l
|
||||
i8xDVzRFzotrzTiPk3HpSk2i6JMwGUegBhVxqYlvRyw3Od0UA18xVvxaFrHPczSl
|
||||
iRx8dMchvfNpqD4PgbUeAUO+sQEB3xZlPDetYG6uk47teKaQ4ZCT/cTSeuhvoPZ0
|
||||
477E+r1KWe/kI9zeHNQ+L1GsZuwQYFGFfDpSBs8PLtyciZtPvjsZEzJrmpoq1JXT
|
||||
KqkdBTZ4qElFMleV59Qtc9SRVsPbRHwT0O/cLQ==
|
||||
-----END CERTIFICATE-----
|
27
test/e2e/e2e.key
Normal file
27
test/e2e/e2e.key
Normal file
@ -0,0 +1,27 @@
|
||||
-----BEGIN RSA PRIVATE KEY-----
|
||||
MIIEpAIBAAKCAQEAx802mHKYUizrFfzxFpL9Fytvoa4so/hnoF3Ldx+yuisVqBzE
|
||||
gI5kqXRoJtvw+6+IQLQInfVqQGVxMRvvixkeRv8BQzAImhWYhPhsFNtHxkbAYSVS
|
||||
LSB1X/ysGEjwRRygrqldJGPTJMNRjmGfTd93miOKLgknOkKYToBe40WmsnF1Gjiy
|
||||
BwGCv/kJRB4vqo+Qs1arISNGJFh2N9DL39RZoHZAonSVAkfDi7J3PPziTI2/u7O6
|
||||
y+73SgaEWrtRtb3UcB9ul5N3auSuQU8LQmIl40fCZg0DEuFaE4PQcxro3eyIUxtw
|
||||
VVjR6PdxZJlHy2gRAHS1XLQXQvSdLEL4sASFewIDAQABAoIBAF/PnYWfNkH5vkXO
|
||||
BMJhfDJXJvHuNwPuQ6sYL1CRh8BUls8F9Ij9P3IvGx6/S6E1vG3ip1sv62K0AoKd
|
||||
NdKLGgTLlgxlBUr2XiwtgI7D1HhVRz2OiwiOzxpXbSM8HtPVdYwsNTkVEZRIgVx4
|
||||
nc7XAWCN+F45D3GVq7nBPz9XECfy/Aanrq4bwqGDjvw0vIRiy/M8gnJdL+1g0K1b
|
||||
Cp6JkYexV5v9pnCtvYRJYqKrRxxZU90JRSb8/wNtuLeaIM/aAoUzPkUj+1owglL8
|
||||
HXUeeHsAK527gZxubYAQOCP9NGZeMEE9vAyQDxpQ+wTC5i5zhT4xkH4F/P1aYQES
|
||||
fdVl86ECgYEA/NE3KgKBm5nUHOZwtZ+YiAmEkbMWXrkpYCRzQPbcMMMphMZQT4Pd
|
||||
aSdtzv1qRu95qnsY/cFceyOLbiNRF+uwYJwn2PmPW7jsUQG5vHsFn12edcWxnz6k
|
||||
sRRfU8HiVYoaipQD06aMUCZYKQJV4jfvcqKpVwj9b3fiN8/oDgx2AWsCgYEAylEj
|
||||
Tznw54mrOFYOLbLlwwpYbVuUHWFi9WjLGLVfOHQY03CCH+PMIFPnaYRAS3SqUL8s
|
||||
e5AQvNdez7HyPfGeUtXmTaEPgA8YRHTcmtfIuNn/jxjwbpcaGQn6kzB/TYdte4Pb
|
||||
CXwS3Yt1LqUgC1EqkUUpszn+O6d2mnnrq1aawDECgYEAh0tvOgwdUCgCW3T23DuM
|
||||
ZUCysUYlsotkmQ7ontt8+pt2nJeEYwkudBelrB/xwARoF9PIjAPuefeLpmVAAI0g
|
||||
1pK6wGLNVUihLri9rSAo4iA3rM8fPxlHCXzdhvU7Kou9qGuNoLaAYGQkyc12KJnG
|
||||
ipKCDRHCjuSZK0UX6mzAugECgYEAxYgw1GK67iXBEZEb6Mx5flO0gJlgZMs35mn5
|
||||
mddD8AeSUabQtbghDhM9pw0kBUgUHiB5mu7PGMGi5WBVJtuofDIx2Ot/CcYzKGt9
|
||||
FIXIiYr29M0huqg3J+lRSLKaKKUoZOcZTgphFQPbVr6MKeCGki2YCFCAA9h+eVa+
|
||||
nZxCHZECgYBJjNqhR9pc+56Mor6oBGnRbBCQn2naNuPx4AoZ8JWXU8Q8GRoI5son
|
||||
F7MGeuVwLDFvyQOAiDxqyrHM+PCPLcMBdfH8rMt7GQpBsSSA09WYtQ9Sj97QhbTy
|
||||
Zrq8EtPvRBmeGfZd8BDGVGunVZnNi3NaOV0fCOK6yQEtJN0J9BREbw==
|
||||
-----END RSA PRIVATE KEY-----
|
@ -12,18 +12,31 @@ const (
|
||||
TCPEchoServerPort = "TCPEchoServerPort"
|
||||
UDPEchoServerPort = "UDPEchoServerPort"
|
||||
UDSEchoServerAddr = "UDSEchoServerAddr"
|
||||
HTTPEchoServerPort = "HTTPEchoServerPort"
|
||||
HTTPSEchoServerPort = "HTTPSEchoServerPort"
|
||||
WSEchoServerPort = "WSEchoServerPort"
|
||||
WSSEchoServerPort = "WSSEchoServerPort"
|
||||
)
|
||||
|
||||
type MockServers struct {
|
||||
tcpEchoServer *echoserver.Server
|
||||
udpEchoServer *echoserver.Server
|
||||
udsEchoServer *echoserver.Server
|
||||
httpEchoServer *echoserver.Server
|
||||
httpsEchoServer *echoserver.Server
|
||||
wsEchoServer *echoserver.Server
|
||||
wssEchoServer *echoserver.Server
|
||||
}
|
||||
|
||||
func NewMockServers(portAllocator *port.Allocator) *MockServers {
|
||||
s := &MockServers{}
|
||||
tcpPort := portAllocator.Get()
|
||||
udpPort := portAllocator.Get()
|
||||
httpPort := portAllocator.Get()
|
||||
httpsPort := portAllocator.Get()
|
||||
wsPort := portAllocator.Get()
|
||||
wssPort := portAllocator.Get()
|
||||
|
||||
s.tcpEchoServer = echoserver.New(echoserver.Options{
|
||||
Type: echoserver.TCP,
|
||||
BindAddr: "127.0.0.1",
|
||||
@ -45,6 +58,34 @@ func NewMockServers(portAllocator *port.Allocator) *MockServers {
|
||||
BindAddr: udsAddr,
|
||||
RepeatNum: 1,
|
||||
})
|
||||
|
||||
s.httpEchoServer = echoserver.New(echoserver.Options{
|
||||
Type: echoserver.HTTP,
|
||||
BindAddr: "127.0.0.1",
|
||||
BindPort: int32(httpPort),
|
||||
RepeatNum: 1,
|
||||
})
|
||||
|
||||
s.httpsEchoServer = echoserver.New(echoserver.Options{
|
||||
Type: echoserver.HTTPS,
|
||||
BindAddr: "127.0.0.1",
|
||||
BindPort: int32(httpsPort),
|
||||
RepeatNum: 1,
|
||||
})
|
||||
|
||||
s.wsEchoServer = echoserver.New(echoserver.Options{
|
||||
Type: echoserver.WS,
|
||||
BindAddr: "127.0.0.1",
|
||||
BindPort: int32(wsPort),
|
||||
RepeatNum: 1,
|
||||
})
|
||||
s.wssEchoServer = echoserver.New(echoserver.Options{
|
||||
Type: echoserver.WSS,
|
||||
BindAddr: "127.0.0.1",
|
||||
BindPort: int32(wssPort),
|
||||
RepeatNum: 1,
|
||||
})
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
@ -58,6 +99,18 @@ func (m *MockServers) Run() error {
|
||||
if err := m.udsEchoServer.Run(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := m.httpEchoServer.Run(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := m.httpsEchoServer.Run(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := m.wsEchoServer.Run(); err != nil {
|
||||
return err
|
||||
}
|
||||
if err := m.wssEchoServer.Run(); err != nil {
|
||||
return err
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -65,6 +118,10 @@ func (m *MockServers) Close() {
|
||||
m.tcpEchoServer.Close()
|
||||
m.udpEchoServer.Close()
|
||||
m.udsEchoServer.Close()
|
||||
m.httpEchoServer.Close()
|
||||
m.httpsEchoServer.Close()
|
||||
m.wsEchoServer.Close()
|
||||
m.wssEchoServer.Close()
|
||||
os.Remove(m.udsEchoServer.GetOptions().BindAddr)
|
||||
}
|
||||
|
||||
@ -73,6 +130,10 @@ func (m *MockServers) GetTemplateParams() map[string]interface{} {
|
||||
ret[TCPEchoServerPort] = m.tcpEchoServer.GetOptions().BindPort
|
||||
ret[UDPEchoServerPort] = m.udpEchoServer.GetOptions().BindPort
|
||||
ret[UDSEchoServerAddr] = m.udsEchoServer.GetOptions().BindAddr
|
||||
ret[HTTPEchoServerPort] = m.httpEchoServer.GetOptions().BindPort
|
||||
ret[HTTPSEchoServerPort] = m.httpsEchoServer.GetOptions().BindPort
|
||||
ret[WSEchoServerPort] = m.wsEchoServer.GetOptions().BindPort
|
||||
ret[WSSEchoServerPort] = m.wssEchoServer.GetOptions().BindPort
|
||||
return ret
|
||||
}
|
||||
|
||||
|
@ -1,11 +1,15 @@
|
||||
package echoserver
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"net"
|
||||
"net/http"
|
||||
"strings"
|
||||
|
||||
fnet "github.com/fatedier/frp/pkg/util/net"
|
||||
|
||||
"github.com/gorilla/websocket"
|
||||
)
|
||||
|
||||
type ServerType string
|
||||
@ -14,6 +18,10 @@ const (
|
||||
TCP ServerType = "tcp"
|
||||
UDP ServerType = "udp"
|
||||
Unix ServerType = "unix"
|
||||
HTTP ServerType = "http"
|
||||
HTTPS ServerType = "https"
|
||||
WS ServerType = "ws"
|
||||
WSS ServerType = "wss"
|
||||
)
|
||||
|
||||
type Options struct {
|
||||
@ -28,6 +36,10 @@ type Server struct {
|
||||
opt Options
|
||||
|
||||
l net.Listener
|
||||
httpServer *http.Server
|
||||
httpsServer *http.Server
|
||||
wsServer *http.Server
|
||||
wssServer *http.Server
|
||||
}
|
||||
|
||||
func New(opt Options) *Server {
|
||||
@ -50,10 +62,12 @@ func (s *Server) GetOptions() Options {
|
||||
}
|
||||
|
||||
func (s *Server) Run() error {
|
||||
if err := s.initListener(); err != nil {
|
||||
if err := s.init(); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
switch s.opt.Type {
|
||||
case TCP, UDP, Unix:
|
||||
go func() {
|
||||
for {
|
||||
c, err := s.l.Accept()
|
||||
@ -63,6 +77,38 @@ func (s *Server) Run() error {
|
||||
go s.handle(c)
|
||||
}
|
||||
}()
|
||||
case HTTP:
|
||||
go func() {
|
||||
err := s.httpServer.ListenAndServe()
|
||||
if err != nil {
|
||||
fmt.Printf("echo http server exited error: %v\n", err)
|
||||
}
|
||||
}()
|
||||
case HTTPS:
|
||||
go func() {
|
||||
err := s.httpsServer.ListenAndServeTLS("e2e.crt", "e2e.key")
|
||||
if err != nil {
|
||||
fmt.Printf("echo https server exited error: %v\n", err)
|
||||
}
|
||||
}()
|
||||
case WS:
|
||||
go func() {
|
||||
err := s.wsServer.ListenAndServe()
|
||||
if err != nil {
|
||||
fmt.Printf("echo ws server exited error: %v\n", err)
|
||||
}
|
||||
}()
|
||||
case WSS:
|
||||
go func() {
|
||||
err := s.wssServer.ListenAndServeTLS("e2e.crt", "e2e.key")
|
||||
if err != nil {
|
||||
fmt.Printf("echo wss server exited error: %v\n", err)
|
||||
}
|
||||
}()
|
||||
default:
|
||||
return fmt.Errorf("unknown server type: %s", s.opt.Type)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
@ -70,10 +116,22 @@ func (s *Server) Close() error {
|
||||
if s.l != nil {
|
||||
return s.l.Close()
|
||||
}
|
||||
if s.httpServer != nil {
|
||||
s.httpServer.Close()
|
||||
}
|
||||
if s.httpsServer != nil {
|
||||
s.httpsServer.Close()
|
||||
}
|
||||
if s.wsServer != nil {
|
||||
s.wsServer.Close()
|
||||
}
|
||||
if s.wssServer != nil {
|
||||
s.wssServer.Close()
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *Server) initListener() (err error) {
|
||||
func (s *Server) init() (err error) {
|
||||
switch s.opt.Type {
|
||||
case TCP:
|
||||
s.l, err = net.Listen("tcp", fmt.Sprintf("%s:%d", s.opt.BindAddr, s.opt.BindPort))
|
||||
@ -81,6 +139,30 @@ func (s *Server) initListener() (err error) {
|
||||
s.l, err = fnet.ListenUDP(s.opt.BindAddr, int(s.opt.BindPort))
|
||||
case Unix:
|
||||
s.l, err = net.Listen("unix", s.opt.BindAddr)
|
||||
case HTTP:
|
||||
s.httpServer = &http.Server{
|
||||
Addr: fmt.Sprintf("%s:%d", s.opt.BindAddr, s.opt.BindPort),
|
||||
Handler: http.HandlerFunc(echo),
|
||||
}
|
||||
fmt.Println("http echo server listen port", s.opt.BindPort)
|
||||
case HTTPS:
|
||||
s.httpsServer = &http.Server{
|
||||
Addr: fmt.Sprintf("%s:%d", s.opt.BindAddr, s.opt.BindPort),
|
||||
Handler: http.HandlerFunc(echo),
|
||||
}
|
||||
fmt.Println("https echo server listen port", s.opt.BindPort)
|
||||
case WS:
|
||||
s.wsServer = &http.Server{
|
||||
Addr: fmt.Sprintf("%s:%d", s.opt.BindAddr, s.opt.BindPort),
|
||||
Handler: http.HandlerFunc(ws),
|
||||
}
|
||||
fmt.Println("ws echo server listen port", s.opt.BindPort)
|
||||
case WSS:
|
||||
s.wssServer = &http.Server{
|
||||
Addr: fmt.Sprintf("%s:%d", s.opt.BindAddr, s.opt.BindPort),
|
||||
Handler: http.HandlerFunc(ws),
|
||||
}
|
||||
fmt.Println("wss echo server listen port", s.opt.BindPort)
|
||||
default:
|
||||
return fmt.Errorf("unknown server type: %s", s.opt.Type)
|
||||
}
|
||||
@ -109,3 +191,51 @@ func (s *Server) handle(c net.Conn) {
|
||||
c.Write([]byte(response))
|
||||
}
|
||||
}
|
||||
|
||||
func echo(w http.ResponseWriter, r *http.Request) {
|
||||
rh := make(map[string]string)
|
||||
for key, _ := range r.Header {
|
||||
rh[key] = r.Header.Get(key)
|
||||
}
|
||||
rh["Host"] = r.Host
|
||||
rh["Path"] = r.URL.Path
|
||||
|
||||
data, err := json.Marshal(rh)
|
||||
if err != nil {
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
w.WriteHeader(http.StatusOK)
|
||||
w.Write(data)
|
||||
return
|
||||
}
|
||||
|
||||
var (
|
||||
upgrader = websocket.Upgrader{
|
||||
ReadBufferSize: 1024,
|
||||
WriteBufferSize: 1024,
|
||||
}
|
||||
)
|
||||
|
||||
func ws(w http.ResponseWriter, r *http.Request) {
|
||||
conn, err := upgrader.Upgrade(w, r, nil)
|
||||
if err != nil {
|
||||
if _, ok := err.(websocket.HandshakeError); !ok {
|
||||
fmt.Println(err)
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
go func() {
|
||||
for {
|
||||
_, data, err := conn.ReadMessage()
|
||||
if err != nil {
|
||||
fmt.Printf("reading message error: %v\n", err)
|
||||
}
|
||||
if err = conn.WriteMessage(websocket.TextMessage, data); err != nil {
|
||||
fmt.Printf("writing message error: %v\n", err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user