From 3d03ec88963e93d15a9dec53b4ba61fda75c603b Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Tue, 22 May 2012 13:56:40 -0400 Subject: [PATCH] undo CL 6112054 / 2eec2501961c MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Now that we've fixed the Expect: test, this CL should be okay. ««« original CL description net/http: revert 97d027b3aa68 Revert the following change set: changeset: 13018:97d027b3aa68 user: Gustavo Niemeyer date: Mon Apr 23 22:00:16 2012 -0300 summary: net/http: allow clients to disable keep-alive This broke a test on Windows 64 and somebody else will have to check. R=golang-dev, r CC=golang-dev https://golang.org/cl/6112054 »»» Fixes #3540. R=golang-dev, bradfitz CC=golang-dev https://golang.org/cl/6228046 --- src/pkg/net/http/request.go | 16 ++++++++++++++-- src/pkg/net/http/serve_test.go | 15 +++++++++++---- src/pkg/net/http/server.go | 3 +-- 3 files changed, 26 insertions(+), 8 deletions(-) diff --git a/src/pkg/net/http/request.go b/src/pkg/net/http/request.go index f5bc6eb910..219db483b4 100644 --- a/src/pkg/net/http/request.go +++ b/src/pkg/net/http/request.go @@ -732,12 +732,24 @@ func (r *Request) FormFile(key string) (multipart.File, *multipart.FileHeader, e } func (r *Request) expectsContinue() bool { - return strings.ToLower(r.Header.Get("Expect")) == "100-continue" + return hasToken(r.Header.Get("Expect"), "100-continue") } func (r *Request) wantsHttp10KeepAlive() bool { if r.ProtoMajor != 1 || r.ProtoMinor != 0 { return false } - return strings.Contains(strings.ToLower(r.Header.Get("Connection")), "keep-alive") + return hasToken(r.Header.Get("Connection"), "keep-alive") +} + +func (r *Request) wantsClose() bool { + return hasToken(r.Header.Get("Connection"), "close") +} + +func hasToken(s, token string) bool { + if s == "" { + return false + } + // TODO This is a poor implementation of the RFC. See http://golang.org/issue/3535 + return strings.Contains(strings.ToLower(s), token) } diff --git a/src/pkg/net/http/serve_test.go b/src/pkg/net/http/serve_test.go index 196b1ac361..1b4dd8794d 100644 --- a/src/pkg/net/http/serve_test.go +++ b/src/pkg/net/http/serve_test.go @@ -370,7 +370,7 @@ func TestIdentityResponse(t *testing.T) { }) } -func testTcpConnectionCloses(t *testing.T, req string, h Handler) { +func testTCPConnectionCloses(t *testing.T, req string, h Handler) { s := httptest.NewServer(h) defer s.Close() @@ -410,21 +410,28 @@ func testTcpConnectionCloses(t *testing.T, req string, h Handler) { // TestServeHTTP10Close verifies that HTTP/1.0 requests won't be kept alive. func TestServeHTTP10Close(t *testing.T) { - testTcpConnectionCloses(t, "GET / HTTP/1.0\r\n\r\n", HandlerFunc(func(w ResponseWriter, r *Request) { + testTCPConnectionCloses(t, "GET / HTTP/1.0\r\n\r\n", HandlerFunc(func(w ResponseWriter, r *Request) { ServeFile(w, r, "testdata/file") })) } +// TestClientCanClose verifies that clients can also force a connection to close. +func TestClientCanClose(t *testing.T) { + testTCPConnectionCloses(t, "GET / HTTP/1.1\r\nConnection: close\r\n\r\n", HandlerFunc(func(w ResponseWriter, r *Request) { + // Nothing. + })) +} + // TestHandlersCanSetConnectionClose verifies that handlers can force a connection to close, // even for HTTP/1.1 requests. func TestHandlersCanSetConnectionClose11(t *testing.T) { - testTcpConnectionCloses(t, "GET / HTTP/1.1\r\n\r\n", HandlerFunc(func(w ResponseWriter, r *Request) { + testTCPConnectionCloses(t, "GET / HTTP/1.1\r\n\r\n", HandlerFunc(func(w ResponseWriter, r *Request) { w.Header().Set("Connection", "close") })) } func TestHandlersCanSetConnectionClose10(t *testing.T) { - testTcpConnectionCloses(t, "GET / HTTP/1.0\r\nConnection: keep-alive\r\n\r\n", HandlerFunc(func(w ResponseWriter, r *Request) { + testTCPConnectionCloses(t, "GET / HTTP/1.0\r\nConnection: keep-alive\r\n\r\n", HandlerFunc(func(w ResponseWriter, r *Request) { w.Header().Set("Connection", "close") })) } diff --git a/src/pkg/net/http/server.go b/src/pkg/net/http/server.go index 00daef434c..727313d630 100644 --- a/src/pkg/net/http/server.go +++ b/src/pkg/net/http/server.go @@ -303,8 +303,7 @@ func (w *response) WriteHeader(code int) { if !connectionHeaderSet { w.header.Set("Connection", "keep-alive") } - } else if !w.req.ProtoAtLeast(1, 1) { - // Client did not ask to keep connection alive. + } else if !w.req.ProtoAtLeast(1, 1) || w.req.wantsClose() { w.closeAfterReply = true }