package goxy import ( "crypto/tls" "crypto/x509" "io" "io/ioutil" "log" "net/http" "net/http/httptest" "testing" ) type Cannary string const ( cannary = Cannary("hello from backend") dataFile = "test.json" wwwServer = "localhost:8080" tlsServer = "localhost:8443" rpcServer = "localhost:8000" cert = `-----BEGIN CERTIFICATE----- MIIBXjCCAQygAwIBAgIRAM03h8i2NyJ7sItcK4jU1eEwCgYIKoZIzj0EAwIwEjEQ MA4GA1UEChMHQWNtZSBDbzAeFw0xNjAzMzExMzU5NTlaFw0yNjAzMjkxMzU5NTla MBIxEDAOBgNVBAoTB0FjbWUgQ28wTjAQBgcqhkjOPQIBBgUrgQQAIQM6AATxB9y8 ZHzQayFNY2mrEaG7tgJKTSDOAvVSn8VsDldcZXwXuWEcNoi2LKAckCL9E2xc6bxz AlZGXaNOMEwwDgYDVR0PAQH/BAQDAgKkMBMGA1UdJQQMMAoGCCsGAQUFBwMBMA8G A1UdEwEB/wQFMAMBAf8wFAYDVR0RBA0wC4IJbG9jYWxob3N0MAoGCCqGSM49BAMC A0AAMD0CHQDQCcNis9uY0lGbQ4o8qJByjd9GY3Bon3wmt/ULAhwI78yOXxyeDR1T 77Q2+pF/GmcDtCbwrVt3KpmI -----END CERTIFICATE-----` key = `-----BEGIN EC PRIVATE KEY----- MGgCAQEEHHvI0aSaXHcCugwEWoBJ9R1swGVeDbTYlikuv4+gBwYFK4EEACGhPAM6 AATxB9y8ZHzQayFNY2mrEaG7tgJKTSDOAvVSn8VsDldcZXwXuWEcNoi2LKAckCL9 E2xc6bxzAlZGXQ== -----END EC PRIVATE KEY-----` ) var server Server func init() { server, err := NewServer(dataFile, wwwServer, tlsServer, rpcServer) if err != nil { log.Fatal(err) } go server.Start() } func get(uri string) (string, error) { caPool := x509.NewCertPool() caPool.AppendCertsFromPEM([]byte(cert)) client := http.Client{ Transport: &http.Transport{ TLSClientConfig: &tls.Config{ RootCAs: caPool, }, }, } resp, err := client.Get(uri) if err != nil { return "", err } defer resp.Body.Close() body, err := ioutil.ReadAll(resp.Body) if err != nil { return "", err } return string(body), nil } func add(e Entry) error { client, err := DialRPC(rpcServer) if err != nil { return err } defer client.Close() return client.Call("GoXY.Add", e, nil) } func del(host string) error { client, err := DialRPC(rpcServer) if err != nil { return err } defer client.Close() return client.Call("GoXY.Del", host, nil) } func (c Cannary) ServeHTTP(w http.ResponseWriter, _ *http.Request) { io.WriteString(w, string(c)) } func (c Cannary) Equal(s string) bool { return string(c) == s } func TestReverseProxy(t *testing.T) { backServer := httptest.NewServer(cannary) defer backServer.Close() t.Log("start", backServer.URL) e := Entry{ Host: "http://" + wwwServer, Upstream: backServer.URL, } if err := add(e); err != nil { t.Error(err) } t.Log("add", e) resp, err := get("http://" + wwwServer) if err != nil { t.Error(err) } if !cannary.Equal(resp) { t.Errorf("got %q expected %q", resp, cannary) } if err := del(wwwServer); err != nil { t.Error(err) } t.Log("del", wwwServer) } func TestReverseProxyTLS(t *testing.T) { backServer := httptest.NewServer(cannary) defer backServer.Close() t.Log("start", backServer.URL) e := Entry{ Host: "https://" + tlsServer, Upstream: backServer.URL, Cert: []byte(cert), Key: []byte(key), } if err := add(e); err != nil { t.Error(err) } t.Log("add", e) resp, err := get("https://" + tlsServer) if err != nil { t.Error(err) } if !cannary.Equal(resp) { t.Errorf("got %q expected %q", resp, cannary) } if err := del(tlsServer); err != nil { t.Error(err) } t.Log("del", tlsServer) } func TestWebsocketProxy(t *testing.T) { /* // Websocket echo server wsServer := httptest.NewServer(websocket.Handler(func(ws *websocket.Conn) { io.Copy(ws, ws) })) defer wsServer.Close() t.Log("start ws server @", wsServer.URL) */ } /* // Test WebSocket proxy e = Entry{ Host: frontServer.URL, Upstream: wsServer.URL, } if err := rpcClient.Call("GoXY.Add", e, nil); err != nil { t.Error(err) } frontServer.Config.Handler = server.wwwServer.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) */