package goxy import ( "bytes" "io" "io/ioutil" "net/http" "net/http/httptest" "net/url" "os" "testing" "golang.org/x/net/websocket" ) const ( cannary = "hello from backend" dataFile = "test.json" ) func TestReverseProxy(t *testing.T) { // Backend server backServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { io.WriteString(w, cannary) })) defer backServer.Close() // Websocket echo server wsServer := httptest.NewServer(websocket.Handler(func(ws *websocket.Conn) { io.Copy(ws, ws) })) defer wsServer.Close() wsURL, err := url.Parse(wsServer.URL) if err != nil { t.Error(err) } // RPC Server rpcServer := httptest.NewServer(nil) defer rpcServer.Close() rpcURL, err := url.Parse(rpcServer.URL) if err != nil { t.Error(err) } // Frontend server frontServer := httptest.NewServer(nil) defer frontServer.Close() frontURL, err := url.Parse(frontServer.URL) if err != nil { t.Error(err) } // Initialize proxy server server, err := NewServer(dataFile) if err != nil { t.Error(err) } defer os.Remove(dataFile) // Add routing entries rpcClient, err := DialRPC(rpcURL.Host) if err != nil { t.Error(err) } // Test HTTP proxy e := Entry{ Host: frontURL.Host, Upstream: backServer.URL, } if err := rpcClient.Call("GoXY.Add", e, nil); err != nil { t.Error(err) } frontServer.Config.Handler = server.httpServer.Handler resp, err := http.Get(frontServer.URL) if err != nil { t.Error(err) } defer resp.Body.Close() b, err := ioutil.ReadAll(resp.Body) if err != nil { t.Error(err) } if string(b) != cannary { t.Error("got", string(b), "expected", cannary) } rpcClient.Call("GoXY.Del", frontURL.Host, nil) // Test WebSocket proxy e = Entry{ Host: frontURL.Host, Upstream: "ws://" + wsURL.Host, } if err := rpcClient.Call("GoXY.Add", e, nil); err != nil { t.Error(err) } frontServer.Config.Handler = server.httpServer.Handler ws, err := websocket.Dial("ws://"+frontURL.Host, "", "http://localhost") if err != nil { t.Error(err) } if _, err := ws.Write([]byte(cannary)); err != nil { t.Error(err) } msg := make([]byte, len(cannary)) if _, err := ws.Read(msg); err != nil { t.Error(err) } if !bytes.Equal(msg, []byte(cannary)) { t.Error("got", string(msg), "expected", cannary) } rpcClient.Call("GoXY.Del", frontURL.Host, nil) }