aboutsummaryrefslogtreecommitdiff
path: root/src/net/http/serve_test.go
diff options
context:
space:
mode:
authorAnmol Sethi <hi@nhooyr.io>2020-10-24 00:40:41 +0000
committerBrad Fitzpatrick <bradfitz@golang.org>2020-12-01 19:47:12 +0000
commit50b16f9de590822a04ec8d6cbac476366c1bde32 (patch)
treefb46c24ff85b7588e475de44092b1284f58c46fa /src/net/http/serve_test.go
parent212d385a2f723a8dd5e7d2e83efb478ddd139349 (diff)
downloadgo-50b16f9de590822a04ec8d6cbac476366c1bde32.tar.gz
go-50b16f9de590822a04ec8d6cbac476366c1bde32.zip
net/http: allow upgrading non keepalive connections
If one was using http.Transport with DisableKeepAlives and trying to upgrade a connection against net/http's Server, the Server would not allow a "Connection: Upgrade" header to be written and instead override it to "Connection: Close" which would break the handshake. This change ensures net/http's Server does not override the connection header for successful protocol switch responses. Fixes #36381. Change-Id: I882aad8539e6c87ff5f37c20e20b3a7fa1a30357 GitHub-Last-Rev: dc0de83201dc26236527b68bd49dffc53dd0389b GitHub-Pull-Request: golang/go#36382 Reviewed-on: https://go-review.googlesource.com/c/go/+/213277 Trust: Emmanuel Odeke <emmanuel@orijtech.com> Trust: Brad Fitzpatrick <bradfitz@golang.org> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Diffstat (limited to 'src/net/http/serve_test.go')
-rw-r--r--src/net/http/serve_test.go53
1 files changed, 53 insertions, 0 deletions
diff --git a/src/net/http/serve_test.go b/src/net/http/serve_test.go
index ba54b31a29..b1bf8e6c5e 100644
--- a/src/net/http/serve_test.go
+++ b/src/net/http/serve_test.go
@@ -6448,3 +6448,56 @@ func BenchmarkResponseStatusLine(b *testing.B) {
}
})
}
+func TestDisableKeepAliveUpgrade(t *testing.T) {
+ if testing.Short() {
+ t.Skip("skipping in short mode")
+ }
+
+ setParallel(t)
+ defer afterTest(t)
+
+ s := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+ w.Header().Set("Connection", "Upgrade")
+ w.Header().Set("Upgrade", "someProto")
+ w.WriteHeader(StatusSwitchingProtocols)
+ c, _, err := w.(Hijacker).Hijack()
+ if err != nil {
+ return
+ }
+ defer c.Close()
+
+ io.Copy(c, c)
+ }))
+ s.Config.SetKeepAlivesEnabled(false)
+ s.Start()
+ defer s.Close()
+
+ cl := s.Client()
+ cl.Transport.(*Transport).DisableKeepAlives = true
+
+ resp, err := cl.Get(s.URL)
+ if err != nil {
+ t.Fatalf("failed to perform request: %v", err)
+ }
+ defer resp.Body.Close()
+
+ rwc, ok := resp.Body.(io.ReadWriteCloser)
+ if !ok {
+ t.Fatalf("Response.Body is not a io.ReadWriteCloser: %T", resp.Body)
+ }
+
+ _, err = rwc.Write([]byte("hello"))
+ if err != nil {
+ t.Fatalf("failed to write to body: %v", err)
+ }
+
+ b := make([]byte, 5)
+ _, err = io.ReadFull(rwc, b)
+ if err != nil {
+ t.Fatalf("failed to read from body: %v", err)
+ }
+
+ if string(b) != "hello" {
+ t.Fatalf("unexpected value read from body:\ngot: %q\nwant: %q", b, "hello")
+ }
+}