From 58bd87c81121cbc3e431fb8ee24cdea0d8213466 Mon Sep 17 00:00:00 2001 From: "Alex Ellis (VMware)" Date: Tue, 27 Mar 2018 19:33:43 +0100 Subject: [PATCH] Update proxy to pass query-string HTTP proxy was not passing query-string upstream. This change reinstates the behaviour through TDD - adding test coverage and automated regression testing. Signed-off-by: Alex Ellis (VMware) --- gateway/handlers/forwarding_proxy.go | 14 ++++- gateway/handlers/forwarding_proxy_test.go | 68 +++++++++++++++++++++++ 2 files changed, 80 insertions(+), 2 deletions(-) create mode 100644 gateway/handlers/forwarding_proxy_test.go diff --git a/gateway/handlers/forwarding_proxy.go b/gateway/handlers/forwarding_proxy.go index 47af2ffa..c5a7d3b3 100644 --- a/gateway/handlers/forwarding_proxy.go +++ b/gateway/handlers/forwarding_proxy.go @@ -46,9 +46,13 @@ func MakeForwardingProxyHandler(proxy *types.HTTPClientReverseProxy, notifiers [ } } -func forwardRequest(w http.ResponseWriter, r *http.Request, proxyClient *http.Client, baseURL string, requestURL string, timeout time.Duration) (int, error) { +func buildUpstreamRequest(r *http.Request, url string) *http.Request { - upstreamReq, _ := http.NewRequest(r.Method, baseURL+requestURL, nil) + if len(r.URL.RawQuery) > 0 { + url = fmt.Sprintf("%s?%s", url, r.URL.RawQuery) + } + + upstreamReq, _ := http.NewRequest(r.Method, url, nil) copyHeaders(upstreamReq.Header, &r.Header) upstreamReq.Header["X-Forwarded-For"] = []string{r.RemoteAddr} @@ -57,6 +61,12 @@ func forwardRequest(w http.ResponseWriter, r *http.Request, proxyClient *http.Cl defer r.Body.Close() upstreamReq.Body = r.Body } + return upstreamReq +} + +func forwardRequest(w http.ResponseWriter, r *http.Request, proxyClient *http.Client, baseURL string, requestURL string, timeout time.Duration) (int, error) { + + upstreamReq := buildUpstreamRequest(r, baseURL+requestURL) ctx, cancel := context.WithTimeout(context.Background(), timeout) defer cancel() diff --git a/gateway/handlers/forwarding_proxy_test.go b/gateway/handlers/forwarding_proxy_test.go new file mode 100644 index 00000000..d6d72f9c --- /dev/null +++ b/gateway/handlers/forwarding_proxy_test.go @@ -0,0 +1,68 @@ +package handlers + +import ( + "bytes" + "io/ioutil" + "net/http" + "testing" +) + +func Test_buildUpstreamRequest_Body_Method_Query(t *testing.T) { + srcBytes := []byte("hello world") + + reader := bytes.NewReader(srcBytes) + request, _ := http.NewRequest(http.MethodPost, "/?code=1", reader) + request.Header.Set("X-Source", "unit-test") + + if request.URL.RawQuery != "code=1" { + t.Errorf("Query - want: %s, got: %s", "code=1", request.URL.RawQuery) + t.Fail() + } + + upstream := buildUpstreamRequest(request, "/") + + if request.Method != upstream.Method { + t.Errorf("Method - want: %s, got: %s", request.Method, upstream.Method) + t.Fail() + } + + upstreamBytes, _ := ioutil.ReadAll(upstream.Body) + + if string(upstreamBytes) != string(srcBytes) { + t.Errorf("Body - want: %s, got: %s", string(upstreamBytes), string(srcBytes)) + t.Fail() + } + + if request.Header.Get("X-Source") != upstream.Header.Get("X-Source") { + t.Errorf("Header X-Source - want: %s, got: %s", request.Header.Get("X-Source"), upstream.Header.Get("X-Source")) + t.Fail() + } + + if request.URL.RawQuery != upstream.URL.RawQuery { + t.Errorf("URL.RawQuery - want: %s, got: %s", request.URL.RawQuery, upstream.URL.RawQuery) + t.Fail() + } + +} + +func Test_buildUpstreamRequest_NoBody_GetMethod_NoQuery(t *testing.T) { + request, _ := http.NewRequest(http.MethodGet, "/", nil) + + upstream := buildUpstreamRequest(request, "/") + + if request.Method != upstream.Method { + t.Errorf("Method - want: %s, got: %s", request.Method, upstream.Method) + t.Fail() + } + + if upstream.Body != nil { + t.Errorf("Body - expected nil") + t.Fail() + } + + if request.URL.RawQuery != upstream.URL.RawQuery { + t.Errorf("URL.RawQuery - want: %s, got: %s", request.URL.RawQuery, upstream.URL.RawQuery) + t.Fail() + } + +}