aboutsummaryrefslogtreecommitdiff
path: root/src/net/http/httputil/reverseproxy_test.go
diff options
context:
space:
mode:
authorBrad Fitzpatrick <bradfitz@golang.org>2016-01-04 20:38:20 +0000
committerBrad Fitzpatrick <bradfitz@golang.org>2016-01-05 04:39:11 +0000
commit4b0bc7c3a14ac446bc13d22098de8db382205401 (patch)
treebb2b2639674f6de7230d3116aaf5296c56b24d66 /src/net/http/httputil/reverseproxy_test.go
parent66f1f89dc058e98d4b118041cd8d571a505b43db (diff)
downloadgo-4b0bc7c3a14ac446bc13d22098de8db382205401.tar.gz
go-4b0bc7c3a14ac446bc13d22098de8db382205401.zip
net/http: relax recently-updated rules and behavior of CloseNotifier
The CloseNotifier implementation and documentation was substantially changed in https://golang.org/cl/17750 but it was a bit too aggressive. Issue #13666 highlighted that in addition to breaking external projects, even the standard library (httputil.ReverseProxy) didn't obey the new rules about not using CloseNotifier until the Request.Body is fully consumed. So, instead of fixing httputil.ReverseProxy, dial back the rules a bit. It's now okay to call CloseNotify before consuming the request body. The docs now say CloseNotifier may wait to fire before the request body is fully consumed, but doesn't say that the behavior is undefined anymore. Instead, we just wait until the request body is consumed and start watching for EOF from the client then. This CL also adds a test to ReverseProxy (using a POST request) that would've caught this earlier. Fixes #13666 Change-Id: Ib4e8c29c4bfbe7511f591cf9ffcda23a0f0b1269 Reviewed-on: https://go-review.googlesource.com/18144 Reviewed-by: Russ Cox <rsc@golang.org> Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
Diffstat (limited to 'src/net/http/httputil/reverseproxy_test.go')
-rw-r--r--src/net/http/httputil/reverseproxy_test.go42
1 files changed, 41 insertions, 1 deletions
diff --git a/src/net/http/httputil/reverseproxy_test.go b/src/net/http/httputil/reverseproxy_test.go
index 5f6fc56e07..a944e8e0f5 100644
--- a/src/net/http/httputil/reverseproxy_test.go
+++ b/src/net/http/httputil/reverseproxy_test.go
@@ -8,6 +8,7 @@ package httputil
import (
"bufio"
+ "bytes"
"io"
"io/ioutil"
"log"
@@ -104,7 +105,6 @@ func TestReverseProxy(t *testing.T) {
if g, e := res.Trailer.Get("X-Trailer"), "trailer_value"; g != e {
t.Errorf("Trailer(X-Trailer) = %q ; want %q", g, e)
}
-
}
func TestXForwardedFor(t *testing.T) {
@@ -384,3 +384,43 @@ func TestReverseProxyGetPutBuffer(t *testing.T) {
t.Errorf("Log events = %q; want %q", log, wantLog)
}
}
+
+func TestReverseProxy_Post(t *testing.T) {
+ const backendResponse = "I am the backend"
+ const backendStatus = 200
+ var requestBody = bytes.Repeat([]byte("a"), 1<<20)
+ backend := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
+ slurp, err := ioutil.ReadAll(r.Body)
+ if err != nil {
+ t.Error("Backend body read = %v", err)
+ }
+ if len(slurp) != len(requestBody) {
+ t.Errorf("Backend read %d request body bytes; want %d", len(slurp), len(requestBody))
+ }
+ if !bytes.Equal(slurp, requestBody) {
+ t.Error("Backend read wrong request body.") // 1MB; omitting details
+ }
+ w.Write([]byte(backendResponse))
+ }))
+ defer backend.Close()
+ backendURL, err := url.Parse(backend.URL)
+ if err != nil {
+ t.Fatal(err)
+ }
+ proxyHandler := NewSingleHostReverseProxy(backendURL)
+ frontend := httptest.NewServer(proxyHandler)
+ defer frontend.Close()
+
+ postReq, _ := http.NewRequest("POST", frontend.URL, bytes.NewReader(requestBody))
+ res, err := http.DefaultClient.Do(postReq)
+ if err != nil {
+ t.Fatalf("Do: %v", err)
+ }
+ if g, e := res.StatusCode, backendStatus; g != e {
+ t.Errorf("got res.StatusCode %d; expected %d", g, e)
+ }
+ bodyBytes, _ := ioutil.ReadAll(res.Body)
+ if g, e := string(bodyBytes), backendResponse; g != e {
+ t.Errorf("got body %q; expected %q", g, e)
+ }
+}