aboutsummaryrefslogtreecommitdiff
path: root/server_test.go
blob: 12e6a53c2cdd45047be46432c06623187748fbe7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
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.gob"
)

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.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.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)
}