@@ -16,94 +16,94 @@ import (
1616)
1717
1818var _ = Describe("Proxy Suite", func() {
19− var upstreamServer http.Handler
19+ type proxyTableInput struct {
20+ target string
21+ response testHTTPResponse
22+ upstream string
23+ upstreams options.UpstreamConfig
24+ }
2025
2126 Context("multiUpstreamProxy", func() {
22− BeforeEach(func() {
23− sigData := &options.SignatureData{Hash: crypto.SHA256, Key: "secret"}
24−
25− writer := &pagewriter.WriterFuncs{
26− ProxyErrorFunc: func(rw http.ResponseWriter, _ *http.Request, _ error) {
27− rw.WriteHeader(502)
28− rw.Write([]byte("Proxy Error"))
29− },
30− }
27+ DescribeTable("Proxy ServeHTTP",
28+ func(in *proxyTableInput) {
29+ sigData := &options.SignatureData{Hash: crypto.SHA256, Key: "secret"}
3130
32− ok := http.StatusOK
33− accepted := http.StatusAccepted
31+ writer := &pagewriter.WriterFuncs{
32+ ProxyErrorFunc: func(rw http.ResponseWriter, _ *http.Request, _ error) {
33+ rw.WriteHeader(502)
34+ rw.Write([]byte("Proxy Error"))
35+ },
36+ }
3437
35− upstreams := options.Upstreams{
36− {
37− ID: "http-backend",
38− Path: "/http/",
39− URI: serverAddr,
40− },
41− {
42− ID: "file-backend",
43− Path: "/files/",
44− URI: fmt.Sprintf("file:///%s", filesDir),
45− },
46− {
47− ID: "static-backend",
48− Path: "/static/",
49− Static: true,
50− StaticCode: &ok,
51− },
52− {
53− ID: "static-backend-no-trailing-slash",
54− Path: "/static",
55− Static: true,
56− StaticCode: &accepted,
57− },
58− {
59− ID: "static-backend-long",
60− Path: "/static/long",
61− Static: true,
62− StaticCode: &accepted,
63− },
64− {
65− ID: "bad-http-backend",
66− Path: "/bad-http/",
67− URI: "http://::1",
68− },
69− {
70− ID: "single-path-backend",
71− Path: "/single-path",
72− Static: true,
73− StaticCode: &ok,
74− },
75− {
76− ID: "backend-with-rewrite-prefix",
77− Path: "^/rewrite-prefix/(.*)",
78− RewriteTarget: "/different/backend/path/$1",
79− URI: serverAddr,
80− },
81− {
82− ID: "double-match-plain",
83− Path: "/double-match/",
84− URI: serverAddr,
85− },
86− {
87− ID: "double-match-rewrite",
88− Path: "^/double-match/(.*)",
89− RewriteTarget: "/double-match/rewrite/$1",
90− URI: serverAddr,
91− },
92− }
38+ ok := http.StatusOK
39+ accepted := http.StatusAccepted
9340
94− var err error
95− upstreamServer, err = NewProxy(upstreams, sigData, writer)
96− Expect(err).ToNot(HaveOccurred())
97− })
41+ // Allows for specifying settings and even individual upstreams for specific tests and uses the default upstreams/configs otherwise
42+ upstreams := in.upstreams
43+ if len(in.upstreams.Upstreams) == 0 {
44+ upstreams.Upstreams = []options.Upstream{
45+ {
46+ ID: "http-backend",
47+ Path: "/http/",
48+ URI: serverAddr,
49+ },
50+ {
51+ ID: "file-backend",
52+ Path: "/files/",
53+ URI: fmt.Sprintf("file:///%s", filesDir),
54+ },
55+ {
56+ ID: "static-backend",
57+ Path: "/static/",
58+ Static: true,
59+ StaticCode: &ok,
60+ },
61+ {
62+ ID: "static-backend-no-trailing-slash",
63+ Path: "/static",
64+ Static: true,
65+ StaticCode: &accepted,
66+ },
67+ {
68+ ID: "static-backend-long",
69+ Path: "/static/long",
70+ Static: true,
71+ StaticCode: &accepted,
72+ },
73+ {
74+ ID: "bad-http-backend",
75+ Path: "/bad-http/",
76+ URI: "http://::1",
77+ },
78+ {
79+ ID: "single-path-backend",
80+ Path: "/single-path",
81+ Static: true,
82+ StaticCode: &ok,
83+ },
84+ {
85+ ID: "backend-with-rewrite-prefix",
86+ Path: "^/rewrite-prefix/(.*)",
87+ RewriteTarget: "/different/backend/path/$1",
88+ URI: serverAddr,
89+ },
90+ {
91+ ID: "double-match-plain",
92+ Path: "/double-match/",
93+ URI: serverAddr,
94+ },
95+ {
96+ ID: "double-match-rewrite",
97+ Path: "^/double-match/(.*)",
98+ RewriteTarget: "/double-match/rewrite/$1",
99+ URI: serverAddr,
100+ },
101+ }
102+ }
98103
99− type proxyTableInput struct {
100− target string
101− response testHTTPResponse
102− upstream string
103− }
104+ upstreamServer, err := NewProxy(upstreams, sigData, writer)
105+ Expect(err).ToNot(HaveOccurred())
104106
105− DescribeTable("Proxy ServeHTTP",
106− func(in *proxyTableInput) {
107107 req := middlewareapi.AddRequestScope(
108108 httptest.NewRequest("", in.target, nil),
109109 &middlewareapi.RequestScope{},
@@ -131,10 +131,12 @@ var _ = Describe("Proxy Suite", func() {
131131 }
132132
133133 // Compare the reflected request to the upstream
134− request := testHTTPRequest{}
135− Expect(json.Unmarshal(body, &request)).To(Succeed())
136− testSanitizeRequestHeader(request.Header)
137− Expect(request).To(Equal(in.response.request))
134+ if body != nil {
135+ request := testHTTPRequest{}
136+ Expect(json.Unmarshal(body, &request)).To(Succeed())
137+ testSanitizeRequestHeader(request.Header)
138+ Expect(request).To(Equal(in.response.request))
139+ }
138140 },
139141 Entry("with a request to the HTTP service", &proxyTableInput{
140142 target: "http://example.localhost/http/1234",
@@ -310,33 +312,58 @@ var _ = Describe("Proxy Suite", func() {
310312 },
311313 upstream: "double-match-rewrite",
312314 }),
315+ Entry("containing an escaped '/' without ProxyRawPath", &proxyTableInput{
316+ target: "http://example.localhost/%2F/test1/%2F/test2",
317+ response: testHTTPResponse{
318+ code: 301,
319+ header: map[string][]string{
320+ "Location": {
321+ "http://example.localhost/test1/test2",
322+ },
323+ },
324+ },
325+ upstream: "",
326+ }),
327+ Entry("containing an escaped '/' with ProxyRawPath", &proxyTableInput{
328+ upstreams: options.UpstreamConfig{ProxyRawPath: true},
329+ target: "http://example.localhost/%2F/test1/%2F/test2",
330+ response: testHTTPResponse{
331+ code: 404,
332+ header: map[string][]string{
333+ "X-Content-Type-Options": {"nosniff"},
334+ contentType: {textPlainUTF8},
335+ },
336+ raw: "404 page not found\n",
337+ },
338+ upstream: "",
339+ }),
313340 )
314341 })
315342
316343 Context("sortByPathLongest", func() {
317344 type sortByPathLongestTableInput struct {
318− input options.Upstreams
319− expectedOutput options.Upstreams
345+ input []options.Upstream
346+ expectedOutput []options.Upstream
320347 }
321348
322− var httpPath = options.Upstream{
349+ httpPath := options.Upstream{
323350 Path: "/http/",
324351 }
325352
326− var httpSubPath = options.Upstream{
353+ httpSubPath := options.Upstream{
327354 Path: "/http/subpath/",
328355 }
329356
330− var longerPath = options.Upstream{
357+ longerPath := options.Upstream{
331358 Path: "/longer-than-http",
332359 }
333360
334− var shortPathWithRewrite = options.Upstream{
361+ shortPathWithRewrite := options.Upstream{
335362 Path: "^/h/(.*)",
336363 RewriteTarget: "/$1",
337364 }
338365
339− var shortSubPathWithRewrite = options.Upstream{
366+ shortSubPathWithRewrite := options.Upstream{
340367 Path: "^/h/bar/(.*)",
341368 RewriteTarget: "/$1",
342369 }
@@ -346,40 +373,40 @@ var _ = Describe("Proxy Suite", func() {
346373 Expect(sortByPathLongest(in.input)).To(Equal(in.expectedOutput))
347374 },
348375 Entry("with a mix of paths registered", sortByPathLongestTableInput{
349− input: options.Upstreams{httpPath, httpSubPath, shortSubPathWithRewrite, longerPath, shortPathWithRewrite},
350− expectedOutput: options.Upstreams{shortSubPathWithRewrite, shortPathWithRewrite, longerPath, httpSubPath, httpPath},
376+ input: []options.Upstream{httpPath, httpSubPath, shortSubPathWithRewrite, longerPath, shortPathWithRewrite},
377+ expectedOutput: []options.Upstream{shortSubPathWithRewrite, shortPathWithRewrite, longerPath, httpSubPath, httpPath},
351378 }),
352379 Entry("when a subpath is registered (in order)", sortByPathLongestTableInput{
353− input: options.Upstreams{httpSubPath, httpPath},
354− expectedOutput: options.Upstreams{httpSubPath, httpPath},
380+ input: []options.Upstream{httpSubPath, httpPath},
381+ expectedOutput: []options.Upstream{httpSubPath, httpPath},
355382 }),
356383 Entry("when a subpath is registered (out of order)", sortByPathLongestTableInput{
357− input: options.Upstreams{httpPath, httpSubPath},
358− expectedOutput: options.Upstreams{httpSubPath, httpPath},
384+ input: []options.Upstream{httpPath, httpSubPath},
385+ expectedOutput: []options.Upstream{httpSubPath, httpPath},
359386 }),
360387 Entry("when longer paths are registered (in order)", sortByPathLongestTableInput{
361− input: options.Upstreams{longerPath, httpPath},
362− expectedOutput: options.Upstreams{longerPath, httpPath},
388+ input: []options.Upstream{longerPath, httpPath},
389+ expectedOutput: []options.Upstream{longerPath, httpPath},
363390 }),
364391 Entry("when longer paths are registered (out of order)", sortByPathLongestTableInput{
365− input: options.Upstreams{httpPath, longerPath},
366− expectedOutput: options.Upstreams{longerPath, httpPath},
392+ input: []options.Upstream{httpPath, longerPath},
393+ expectedOutput: []options.Upstream{longerPath, httpPath},
367394 }),
368395 Entry("when a rewrite target is registered (in order)", sortByPathLongestTableInput{
369− input: options.Upstreams{shortPathWithRewrite, longerPath},
370− expectedOutput: options.Upstreams{shortPathWithRewrite, longerPath},
396+ input: []options.Upstream{shortPathWithRewrite, longerPath},
397+ expectedOutput: []options.Upstream{shortPathWithRewrite, longerPath},
371398 }),
372399 Entry("when a rewrite target is registered (out of order)", sortByPathLongestTableInput{
373− input: options.Upstreams{longerPath, shortPathWithRewrite},
374− expectedOutput: options.Upstreams{shortPathWithRewrite, longerPath},
400+ input: []options.Upstream{longerPath, shortPathWithRewrite},
401+ expectedOutput: []options.Upstream{shortPathWithRewrite, longerPath},
375402 }),
376403 Entry("with multiple rewrite targets registered (in order)", sortByPathLongestTableInput{
377− input: options.Upstreams{shortSubPathWithRewrite, shortPathWithRewrite},
378− expectedOutput: options.Upstreams{shortSubPathWithRewrite, shortPathWithRewrite},
404+ input: []options.Upstream{shortSubPathWithRewrite, shortPathWithRewrite},
405+ expectedOutput: []options.Upstream{shortSubPathWithRewrite, shortPathWithRewrite},
379406 }),
380407 Entry("with multiple rewrite targets registered (out of order)", sortByPathLongestTableInput{
381− input: options.Upstreams{shortPathWithRewrite, shortSubPathWithRewrite},
382− expectedOutput: options.Upstreams{shortSubPathWithRewrite, shortPathWithRewrite},
408+ input: []options.Upstream{shortPathWithRewrite, shortSubPathWithRewrite},
409+ expectedOutput: []options.Upstream{shortSubPathWithRewrite, shortPathWithRewrite},
383410 }),
384411 )
385412 })