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) <alexellis2@gmail.com>
This commit is contained in:
Alex Ellis (VMware)
2018-03-27 19:33:43 +01:00
parent a20534fb41
commit 58bd87c811
2 changed files with 80 additions and 2 deletions

View File

@ -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) copyHeaders(upstreamReq.Header, &r.Header)
upstreamReq.Header["X-Forwarded-For"] = []string{r.RemoteAddr} 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() defer r.Body.Close()
upstreamReq.Body = r.Body 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) ctx, cancel := context.WithTimeout(context.Background(), timeout)
defer cancel() defer cancel()

View File

@ -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()
}
}