@@ -8,7 +8,6 @@ import (
88 "fmt"
99 "io"
1010 "io/ioutil"
11− "net"
1211 "net/http"
1312 "net/http/httptest"
1413 "net/url"
@@ -24,11 +23,11 @@ import (
2423 "github.com/oauth2-proxy/oauth2-proxy/pkg/apis/sessions"
2524 "github.com/oauth2-proxy/oauth2-proxy/pkg/logger"
2625 sessionscookie "github.com/oauth2-proxy/oauth2-proxy/pkg/sessions/cookie"
26+ "github.com/oauth2-proxy/oauth2-proxy/pkg/upstream"
2727 "github.com/oauth2-proxy/oauth2-proxy/pkg/validation"
2828 "github.com/oauth2-proxy/oauth2-proxy/providers"
2929 "github.com/stretchr/testify/assert"
3030 "github.com/stretchr/testify/require"
31− "golang.org/x/net/websocket"
3231)
3332
3433const (
@@ -44,143 +43,6 @@ func init() {
4443 logger.SetFlags(logger.Lshortfile)
4544}
4645
47−type WebSocketOrRestHandler struct {
48− restHandler http.Handler
49− wsHandler http.Handler
50−}
51−
52−func (h *WebSocketOrRestHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
53− if r.Header.Get("Upgrade") == "websocket" {
54− h.wsHandler.ServeHTTP(w, r)
55− } else {
56− h.restHandler.ServeHTTP(w, r)
57− }
58−}
59−
60−func TestWebSocketProxy(t *testing.T) {
61− handler := WebSocketOrRestHandler{
62− restHandler: http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
63− w.WriteHeader(200)
64− hostname, _, _ := net.SplitHostPort(r.Host)
65− _, err := w.Write([]byte(hostname))
66− if err != nil {
67− t.Fatal(err)
68− }
69− }),
70− wsHandler: websocket.Handler(func(ws *websocket.Conn) {
71− defer func(t *testing.T) {
72− if err := ws.Close(); err != nil {
73− t.Fatal(err)
74− }
75− }(t)
76− var data []byte
77− err := websocket.Message.Receive(ws, &data)
78− if err != nil {
79− t.Fatal(err)
80− }
81− err = websocket.Message.Send(ws, data)
82− if err != nil {
83− t.Fatal(err)
84− }
85− }),
86− }
87− backend := httptest.NewServer(&handler)
88− t.Cleanup(backend.Close)
89−
90− backendURL, _ := url.Parse(backend.URL)
91−
92− opts := baseTestOptions()
93− var auth hmacauth.HmacAuth
94− opts.PassHostHeader = true
95− proxyHandler := NewWebSocketOrRestReverseProxy(backendURL, opts, auth)
96− frontend := httptest.NewServer(proxyHandler)
97− t.Cleanup(frontend.Close)
98−
99− frontendURL, _ := url.Parse(frontend.URL)
100− frontendWSURL := "ws://" + frontendURL.Host + "/"
101−
102− ws, err := websocket.Dial(frontendWSURL, "", "http://localhost/")
103− if err != nil {
104− t.Fatal(err)
105− }
106− request := []byte("hello, world!")
107− err = websocket.Message.Send(ws, request)
108− if err != nil {
109− t.Fatal(err)
110− }
111− var response = make([]byte, 1024)
112− err = websocket.Message.Receive(ws, &response)
113− if err != nil {
114− t.Fatal(err)
115− }
116− if g, e := string(request), string(response); g != e {
117− t.Errorf("got body %q; expected %q", g, e)
118− }
119−
120− getReq, _ := http.NewRequest("GET", frontend.URL, nil)
121− res, _ := http.DefaultClient.Do(getReq)
122− bodyBytes, _ := ioutil.ReadAll(res.Body)
123− backendHostname, _, _ := net.SplitHostPort(backendURL.Host)
124− if g, e := string(bodyBytes), backendHostname; g != e {
125− t.Errorf("got body %q; expected %q", g, e)
126− }
127−}
128−
129−func TestNewReverseProxy(t *testing.T) {
130− backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
131− w.WriteHeader(200)
132− hostname, _, _ := net.SplitHostPort(r.Host)
133− _, err := w.Write([]byte(hostname))
134− if err != nil {
135− t.Fatal(err)
136− }
137− }))
138− t.Cleanup(backend.Close)
139−
140− backendURL, _ := url.Parse(backend.URL)
141− backendHostname, backendPort, _ := net.SplitHostPort(backendURL.Host)
142− backendHost := net.JoinHostPort(backendHostname, backendPort)
143− proxyURL, _ := url.Parse(backendURL.Scheme + "://" + backendHost + "/")
144−
145− proxyHandler := NewReverseProxy(proxyURL, &options.Options{FlushInterval: time.Second})
146− setProxyUpstreamHostHeader(proxyHandler, proxyURL)
147− frontend := httptest.NewServer(proxyHandler)
148− t.Cleanup(frontend.Close)
149−
150− getReq, _ := http.NewRequest("GET", frontend.URL, nil)
151− res, _ := http.DefaultClient.Do(getReq)
152− bodyBytes, _ := ioutil.ReadAll(res.Body)
153− if g, e := string(bodyBytes), backendHostname; g != e {
154− t.Errorf("got body %q; expected %q", g, e)
155− }
156−}
157−
158−func TestEncodedSlashes(t *testing.T) {
159− var seen string
160− backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
161− w.WriteHeader(200)
162− seen = r.RequestURI
163− }))
164− t.Cleanup(backend.Close)
165−
166− b, _ := url.Parse(backend.URL)
167− proxyHandler := NewReverseProxy(b, &options.Options{FlushInterval: time.Second})
168− setProxyDirector(proxyHandler)
169− frontend := httptest.NewServer(proxyHandler)
170− t.Cleanup(frontend.Close)
171−
172− f, _ := url.Parse(frontend.URL)
173− encodedPath := "/a%2Fb/?c=1"
174− getReq := &http.Request{URL: &url.URL{Scheme: "http", Host: f.Host, Opaque: encodedPath}}
175− _, err := http.DefaultClient.Do(getReq)
176− if err != nil {
177− t.Fatal(err)
178− }
179− if seen != encodedPath {
180− t.Errorf("got bad request %q expected %q", seen, encodedPath)
181− }
182−}
183−
18446func TestRobotsTxt(t *testing.T) {
18547 opts := baseTestOptions()
18648 err := validation.Validate(opts)
@@ -562,7 +424,14 @@ func TestBasicAuthPassword(t *testing.T) {
562424 }
563425 }))
564426 opts := baseTestOptions()
565− opts.Upstreams = append(opts.Upstreams, providerServer.URL)
427+ opts.UpstreamServers = options.Upstreams{
428+ {
429+ ID: providerServer.URL,
430+ Path: "/",
431+ URI: providerServer.URL,
432+ },
433+ }
434+
566435 opts.Cookie.Secure = false
567436 opts.PassBasicAuth = true
568437 opts.SetBasicAuth = true
@@ -867,7 +736,7 @@ type PassAccessTokenTest struct {
867736
868737type PassAccessTokenTestOptions struct {
869738 PassAccessToken bool
870− ProxyUpstream string
739+ ProxyUpstream options.Upstream
871740}
872741
873742func NewPassAccessTokenTest(opts PassAccessTokenTestOptions) (*PassAccessTokenTest, error) {
@@ -893,10 +762,17 @@ func NewPassAccessTokenTest(opts PassAccessTokenTestOptions) (*PassAccessTokenTe
893762 }))
894763
895764 patt.opts = baseTestOptions()
896− patt.opts.Upstreams = append(patt.opts.Upstreams, patt.providerServer.URL)
897− if opts.ProxyUpstream != "" {
898− patt.opts.Upstreams = append(patt.opts.Upstreams, opts.ProxyUpstream)
765+ patt.opts.UpstreamServers = options.Upstreams{
766+ {
767+ ID: patt.providerServer.URL,
768+ Path: "/",
769+ URI: patt.providerServer.URL,
770+ },
899771 }
772+ if opts.ProxyUpstream.ID != "" {
773+ patt.opts.UpstreamServers = append(patt.opts.UpstreamServers, opts.ProxyUpstream)
774+ }
775+
900776 patt.opts.Cookie.Secure = false
901777 patt.opts.PassAccessToken = opts.PassAccessToken
902778 err := validation.Validate(patt.opts)
@@ -999,7 +875,11 @@ func TestForwardAccessTokenUpstream(t *testing.T) {
999875func TestStaticProxyUpstream(t *testing.T) {
1000876 patTest, err := NewPassAccessTokenTest(PassAccessTokenTestOptions{
1001877 PassAccessToken: true,
1002− ProxyUpstream: "static://200/static-proxy",
878+ ProxyUpstream: options.Upstream{
879+ ID: "static-proxy",
880+ Path: "/static-proxy",
881+ Static: true,
882+ },
1003883 })
1004884 if err != nil {
1005885 t.Fatal(err)
@@ -1572,7 +1452,13 @@ func TestAuthSkippedForPreflightRequests(t *testing.T) {
15721452 t.Cleanup(upstream.Close)
15731453
15741454 opts := baseTestOptions()
1575− opts.Upstreams = append(opts.Upstreams, upstream.URL)
1455+ opts.UpstreamServers = options.Upstreams{
1456+ {
1457+ ID: upstream.URL,
1458+ Path: "/",
1459+ URI: upstream.URL,
1460+ },
1461+ }
15761462 opts.SkipAuthPreflight = true
15771463 err := validation.Validate(opts)
15781464 assert.NoError(t, err)
@@ -1641,7 +1527,13 @@ func NewSignatureTest() (*SignatureTest, error) {
16411527 if err != nil {
16421528 return nil, err
16431529 }
1644− opts.Upstreams = append(opts.Upstreams, upstream.URL)
1530+ opts.UpstreamServers = options.Upstreams{
1531+ {
1532+ ID: upstream.URL,
1533+ Path: "/",
1534+ URI: upstream.URL,
1535+ },
1536+ }
16451537
16461538 providerHandler := func(w http.ResponseWriter, r *http.Request) {
16471539 _, err := w.Write([]byte(`{"access_token": "my_auth_token"}`))
@@ -1716,7 +1608,7 @@ func (st *SignatureTest) MakeRequestWithExpectedKey(method, body, key string) er
17161608 }
17171609 // This is used by the upstream to validate the signature.
17181610 st.authenticator.auth = hmacauth.NewHmacAuth(
1719− crypto.SHA1, []byte(key), SignatureHeader, SignatureHeaders)
1611+ crypto.SHA1, []byte(key), upstream.SignatureHeader, upstream.SignatureHeaders)
17201612 proxy.ServeHTTP(st.rw, req)
17211613
17221614 return nil
@@ -2110,7 +2002,13 @@ func Test_noCacheHeaders(t *testing.T) {
21102002 t.Cleanup(upstream.Close)
21112003
21122004 opts := baseTestOptions()
2113− opts.Upstreams = []string{upstream.URL}
2005+ opts.UpstreamServers = options.Upstreams{
2006+ {
2007+ ID: upstream.URL,
2008+ Path: "/",
2009+ URI: upstream.URL,
2010+ },
2011+ }
21142012 opts.SkipAuthRegex = []string{".*"}
21152013 err := validation.Validate(opts)
21162014 assert.NoError(t, err)
@@ -2335,7 +2233,13 @@ func TestTrustedIPs(t *testing.T) {
23352233 for _, tt := range tests {
23362234 t.Run(tt.name, func(t *testing.T) {
23372235 opts := baseTestOptions()
2338− opts.Upstreams = []string{"static://200"}
2236+ opts.UpstreamServers = options.Upstreams{
2237+ {
2238+ ID: "static",
2239+ Path: "/",
2240+ Static: true,
2241+ },
2242+ }
23392243 opts.TrustedIPs = tt.trustedIPs
23402244 opts.ReverseProxy = tt.reverseProxy
23412245 opts.RealClientIPHeader = tt.realClientIPHeader