From 662fa72e8c7bd52bad5c1200f9e7a9b07ee3b853 Mon Sep 17 00:00:00 2001 From: Fabian Stelzer Date: Mon, 9 Aug 2021 14:58:48 +0000 Subject: [PATCH] Add ProxyRawPath tests Refactor proxy_test to set mux/upstream options for each test individually and add tests for encoded urls with ProxyRawPath set and unset. --- pkg/upstream/proxy_test.go | 215 +++++++++++++++++++++---------------- 1 file changed, 120 insertions(+), 95 deletions(-) diff --git a/pkg/upstream/proxy_test.go b/pkg/upstream/proxy_test.go index ae73f489..2745e680 100644 --- a/pkg/upstream/proxy_test.go +++ b/pkg/upstream/proxy_test.go @@ -16,96 +16,94 @@ import ( ) var _ = Describe("Proxy Suite", func() { - var upstreamServer http.Handler + type proxyTableInput struct { + target string + response testHTTPResponse + upstream string + upstreams options.Upstreams + } Context("multiUpstreamProxy", func() { - BeforeEach(func() { - sigData := &options.SignatureData{Hash: crypto.SHA256, Key: "secret"} - - writer := &pagewriter.WriterFuncs{ - ProxyErrorFunc: func(rw http.ResponseWriter, _ *http.Request, _ error) { - rw.WriteHeader(502) - rw.Write([]byte("Proxy Error")) - }, - } - - ok := http.StatusOK - accepted := http.StatusAccepted - - upstreams := options.Upstreams{ - Configs: []options.Upstream{ - { - ID: "http-backend", - Path: "/http/", - URI: serverAddr, - }, - { - ID: "file-backend", - Path: "/files/", - URI: fmt.Sprintf("file:///%s", filesDir), - }, - { - ID: "static-backend", - Path: "/static/", - Static: true, - StaticCode: &ok, - }, - { - ID: "static-backend-no-trailing-slash", - Path: "/static", - Static: true, - StaticCode: &accepted, - }, - { - ID: "static-backend-long", - Path: "/static/long", - Static: true, - StaticCode: &accepted, - }, - { - ID: "bad-http-backend", - Path: "/bad-http/", - URI: "http://::1", - }, - { - ID: "single-path-backend", - Path: "/single-path", - Static: true, - StaticCode: &ok, - }, - { - ID: "backend-with-rewrite-prefix", - Path: "^/rewrite-prefix/(.*)", - RewriteTarget: "/different/backend/path/$1", - URI: serverAddr, - }, - { - ID: "double-match-plain", - Path: "/double-match/", - URI: serverAddr, - }, - { - ID: "double-match-rewrite", - Path: "^/double-match/(.*)", - RewriteTarget: "/double-match/rewrite/$1", - URI: serverAddr, - }, - }, - } - - var err error - upstreamServer, err = NewProxy(upstreams, sigData, writer) - Expect(err).ToNot(HaveOccurred()) - }) - - type proxyTableInput struct { - target string - response testHTTPResponse - upstream string - } - DescribeTable("Proxy ServeHTTP", func(in *proxyTableInput) { + sigData := &options.SignatureData{Hash: crypto.SHA256, Key: "secret"} + + writer := &pagewriter.WriterFuncs{ + ProxyErrorFunc: func(rw http.ResponseWriter, _ *http.Request, _ error) { + rw.WriteHeader(502) + rw.Write([]byte("Proxy Error")) + }, + } + + ok := http.StatusOK + accepted := http.StatusAccepted + + // Allows for specifying settings and even individual upstreams for specific tests and uses the default upstreams/configs otherwise + upstreams := in.upstreams + if len(in.upstreams.Configs) == 0 { + upstreams.Configs = []options.Upstream{ + { + ID: "http-backend", + Path: "/http/", + URI: serverAddr, + }, + { + ID: "file-backend", + Path: "/files/", + URI: fmt.Sprintf("file:///%s", filesDir), + }, + { + ID: "static-backend", + Path: "/static/", + Static: true, + StaticCode: &ok, + }, + { + ID: "static-backend-no-trailing-slash", + Path: "/static", + Static: true, + StaticCode: &accepted, + }, + { + ID: "static-backend-long", + Path: "/static/long", + Static: true, + StaticCode: &accepted, + }, + { + ID: "bad-http-backend", + Path: "/bad-http/", + URI: "http://::1", + }, + { + ID: "single-path-backend", + Path: "/single-path", + Static: true, + StaticCode: &ok, + }, + { + ID: "backend-with-rewrite-prefix", + Path: "^/rewrite-prefix/(.*)", + RewriteTarget: "/different/backend/path/$1", + URI: serverAddr, + }, + { + ID: "double-match-plain", + Path: "/double-match/", + URI: serverAddr, + }, + { + ID: "double-match-rewrite", + Path: "^/double-match/(.*)", + RewriteTarget: "/double-match/rewrite/$1", + URI: serverAddr, + }, + } + } + + upstreamServer, err := NewProxy(upstreams, sigData, writer) + Expect(err).ToNot(HaveOccurred()) + req := middlewareapi.AddRequestScope( httptest.NewRequest("", in.target, nil), &middlewareapi.RequestScope{}, @@ -133,10 +131,12 @@ var _ = Describe("Proxy Suite", func() { } // Compare the reflected request to the upstream - request := testHTTPRequest{} - Expect(json.Unmarshal(body, &request)).To(Succeed()) - testSanitizeRequestHeader(request.Header) - Expect(request).To(Equal(in.response.request)) + if body != nil { + request := testHTTPRequest{} + Expect(json.Unmarshal(body, &request)).To(Succeed()) + testSanitizeRequestHeader(request.Header) + Expect(request).To(Equal(in.response.request)) + } }, Entry("with a request to the HTTP service", &proxyTableInput{ target: "http://example.localhost/http/1234", @@ -312,6 +312,31 @@ var _ = Describe("Proxy Suite", func() { }, upstream: "double-match-rewrite", }), + Entry("containing an escaped '/' without ProxyRawPath", &proxyTableInput{ + target: "http://example.localhost/%2F/test1/%2F/test2", + response: testHTTPResponse{ + code: 301, + header: map[string][]string{ + "Location": { + "http://example.localhost/test1/test2", + }, + }, + }, + upstream: "", + }), + Entry("containing an escaped '/' with ProxyRawPath", &proxyTableInput{ + upstreams: options.Upstreams{ProxyRawPath: true}, + target: "http://example.localhost/%2F/test1/%2F/test2", + response: testHTTPResponse{ + code: 404, + header: map[string][]string{ + "X-Content-Type-Options": {"nosniff"}, + contentType: {textPlainUTF8}, + }, + raw: "404 page not found\n", + }, + upstream: "", + }), ) }) @@ -321,24 +346,24 @@ var _ = Describe("Proxy Suite", func() { expectedOutput []options.Upstream } - var httpPath = options.Upstream{ + httpPath := options.Upstream{ Path: "/http/", } - var httpSubPath = options.Upstream{ + httpSubPath := options.Upstream{ Path: "/http/subpath/", } - var longerPath = options.Upstream{ + longerPath := options.Upstream{ Path: "/longer-than-http", } - var shortPathWithRewrite = options.Upstream{ + shortPathWithRewrite := options.Upstream{ Path: "^/h/(.*)", RewriteTarget: "/$1", } - var shortSubPathWithRewrite = options.Upstream{ + shortSubPathWithRewrite := options.Upstream{ Path: "^/h/bar/(.*)", RewriteTarget: "/$1", }