summaryrefslogtreecommitdiff
path: root/src/net
diff options
context:
space:
mode:
authorJames Tucker <raggi@google.com>2014-09-29 13:53:42 -0700
committerJames Tucker <raggi@google.com>2014-09-29 13:53:42 -0700
commit9c8489424d379932d6f8acd1eec605cf2d484e13 (patch)
treeafc89aebe68249baf1e147a400b6ee96a0a40376 /src/net
parentc9dd39b8f116907ee759931e9df208071786ddf2 (diff)
downloadgo-9c8489424d379932d6f8acd1eec605cf2d484e13.tar.gz
net/http: enable Transfer-Encoding: identity without Content-Length for HTTP 1.1.
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://codereview.appspot.com/100000044 Committer: Brad Fitzpatrick <bradfitz@golang.org>
Diffstat (limited to 'src/net')
-rw-r--r--src/net/http/serve_test.go29
-rw-r--r--src/net/http/server.go21
2 files changed, 43 insertions, 7 deletions
diff --git a/src/net/http/serve_test.go b/src/net/http/serve_test.go
index a690ae469..702bffdc1 100644
--- a/src/net/http/serve_test.go
+++ b/src/net/http/serve_test.go
@@ -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.
diff --git a/src/net/http/server.go b/src/net/http/server.go
index 7ad0bcbc2..b5959f732 100644
--- a/src/net/http/server.go
+++ b/src/net/http/server.go
@@ -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