undo CL 6112054 / 2eec2501961c

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 <gustavo@niemeyer.net>
        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
diff --git a/src/pkg/net/http/request.go b/src/pkg/net/http/request.go
index f5bc6eb..219db48 100644
--- a/src/pkg/net/http/request.go
+++ b/src/pkg/net/http/request.go
@@ -732,12 +732,24 @@
 }
 
 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 196b1ac..1b4dd87 100644
--- a/src/pkg/net/http/serve_test.go
+++ b/src/pkg/net/http/serve_test.go
@@ -370,7 +370,7 @@
 	})
 }
 
-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 @@
 
 // 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 00daef4..727313d 100644
--- a/src/pkg/net/http/server.go
+++ b/src/pkg/net/http/server.go
@@ -303,8 +303,7 @@
 		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
 	}