net/http: deep copy Request.URL also in Request.WithContext's copy

Despite the previously known behavior of Request.WithContext
shallow copying a request, usage of the request inside server.ServeHTTP
mutates the request's URL. This CL implements deep copying of the URL.

Fixes #20068

Change-Id: I86857d7259e23ac624d196401bf12dde401c42af
Reviewed-on: https://go-review.googlesource.com/41308
Run-TryBot: Emmanuel Odeke <emm.odeke@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
Emmanuel Odeke 2017-04-21 11:49:19 -06:00 committed by Brad Fitzpatrick
parent 88a235042d
commit 3b69c3bbed
3 changed files with 62 additions and 0 deletions

View file

@ -698,3 +698,41 @@ func BenchmarkServeHTTP(b *testing.B) {
proxy.ServeHTTP(w, r)
}
}
func TestServeHTTPDeepCopy(t *testing.T) {
backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte("Hello Gopher!"))
}))
defer backend.Close()
backendURL, err := url.Parse(backend.URL)
if err != nil {
t.Fatal(err)
}
type result struct {
before, after string
}
resultChan := make(chan result, 1)
proxyHandler := NewSingleHostReverseProxy(backendURL)
frontend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
before := r.URL.String()
proxyHandler.ServeHTTP(w, r)
after := r.URL.String()
resultChan <- result{before: before, after: after}
}))
defer frontend.Close()
want := result{before: "/", after: "/"}
res, err := frontend.Client().Get(frontend.URL)
if err != nil {
t.Fatalf("Do: %v", err)
}
res.Body.Close()
got := <-resultChan
if got != want {
t.Errorf("got = %+v; want = %+v", got, want)
}
}