]> Cypherpunks repositories - gostls13.git/commitdiff
net/http: enable Transfer-Encoding: identity without Content-Length for HTTP 1.1.
authorJames Tucker <raggi@google.com>
Mon, 29 Sep 2014 20:53:42 +0000 (13:53 -0700)
committerBrad Fitzpatrick <bradfitz@golang.org>
Mon, 29 Sep 2014 20:53:42 +0000 (13:53 -0700)
Use case is SSE recommended configuration: http://www.w3.org/TR/eventsource/#notes
Removes a TODO.

LGTM=bradfitz
R=golang-codereviews, bradfitz, tommi.virtanen
CC=golang-codereviews
https://golang.org/cl/100000044

src/net/http/serve_test.go
src/net/http/server.go

index a690ae46998be2169291cfd77b4ab0ba7419878f..702bffdc13624512809d9b4e86c3fc8c4dde65e7 100644 (file)
@@ -778,6 +778,35 @@ func TestChunkedResponseHeaders(t *testing.T) {
        }
 }
 
+func TestIdentityResponseHeaders(t *testing.T) {
+       defer afterTest(t)
+       log.SetOutput(ioutil.Discard) // is noisy otherwise
+       defer log.SetOutput(os.Stderr)
+
+       ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
+               w.Header().Set("Transfer-Encoding", "identity")
+               w.(Flusher).Flush()
+               fmt.Fprintf(w, "I am an identity response.")
+       }))
+       defer ts.Close()
+
+       res, err := Get(ts.URL)
+       if err != nil {
+               t.Fatalf("Get error: %v", err)
+       }
+       defer res.Body.Close()
+
+       if g, e := res.TransferEncoding, []string(nil); !reflect.DeepEqual(g, e) {
+               t.Errorf("expected TransferEncoding of %v; got %v", e, g)
+       }
+       if _, haveCL := res.Header["Content-Length"]; haveCL {
+               t.Errorf("Unexpected Content-Length")
+       }
+       if !res.Close {
+               t.Errorf("expected Connection: close; got %v", res.Close)
+       }
+}
+
 // Test304Responses verifies that 304s don't declare that they're
 // chunking in their response headers and aren't allowed to produce
 // output.
index 7ad0bcbc208d090d79f04b2b597dab285464690c..b5959f7321f464ad74eb97e35e219c68a5974e6c 100644 (file)
@@ -839,13 +839,20 @@ func (cw *chunkWriter) writeHeader(p []byte) {
        } else if hasCL {
                delHeader("Transfer-Encoding")
        } else if w.req.ProtoAtLeast(1, 1) {
-               // HTTP/1.1 or greater: use chunked transfer encoding
-               // to avoid closing the connection at EOF.
-               // TODO: this blows away any custom or stacked Transfer-Encoding they
-               // might have set.  Deal with that as need arises once we have a valid
-               // use case.
-               cw.chunking = true
-               setHeader.transferEncoding = "chunked"
+               // HTTP/1.1 or greater: Transfer-Encoding has been set to identity,  and no
+               // content-length has been provided. The connection must be closed after the
+               // reply is written, and no chunking is to be done. This is the setup
+               // recommended in the Server-Sent Events candidate recommendation 11,
+               // section 8.
+               if hasTE && te == "identity" {
+                       cw.chunking = false
+                       w.closeAfterReply = true
+               } else {
+                       // HTTP/1.1 or greater: use chunked transfer encoding
+                       // to avoid closing the connection at EOF.
+                       cw.chunking = true
+                       setHeader.transferEncoding = "chunked"
+               }
        } else {
                // HTTP version < 1.1: cannot do chunked transfer
                // encoding and we don't know the Content-Length so