mirror of
https://github.com/golang/go
synced 2024-11-26 05:37:57 -07:00
net/http: do not send redundant Connection: close header in HTTP/1.0 responses
HTTP/1.0 connections are closed implicitly, unless otherwise specified. Note that this change does not test or fix "request too large" responses. Reasoning: (a) it complicates tests and fixes, (b) they should be rare, and (c) this is just a minor wire optimization, and thus not really worth worrying about in this context. Fixes #5955. R=golang-dev, bradfitz CC=golang-dev https://golang.org/cl/12435043
This commit is contained in:
parent
ebe91d1105
commit
1535727e57
@ -1757,6 +1757,64 @@ func TestWriteAfterHijack(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// http://code.google.com/p/go/issues/detail?id=5955
|
||||||
|
// Note that this does not test the "request too large"
|
||||||
|
// exit path from the http server. This is intentional;
|
||||||
|
// not sending Connection: close is just a minor wire
|
||||||
|
// optimization and is pointless if dealing with a
|
||||||
|
// badly behaved client.
|
||||||
|
func TestHTTP10ConnectionHeader(t *testing.T) {
|
||||||
|
defer afterTest(t)
|
||||||
|
|
||||||
|
mux := NewServeMux()
|
||||||
|
mux.Handle("/", HandlerFunc(func(resp ResponseWriter, req *Request) {}))
|
||||||
|
ts := httptest.NewServer(mux)
|
||||||
|
defer ts.Close()
|
||||||
|
|
||||||
|
// net/http uses HTTP/1.1 for requests, so write requests manually
|
||||||
|
tests := []struct {
|
||||||
|
req string // raw http request
|
||||||
|
expect []string // expected Connection header(s)
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
req: "GET / HTTP/1.0\r\n\r\n",
|
||||||
|
expect: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
req: "OPTIONS * HTTP/1.0\r\n\r\n",
|
||||||
|
expect: nil,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
req: "GET / HTTP/1.0\r\nConnection: keep-alive\r\n\r\n",
|
||||||
|
expect: []string{"keep-alive"},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
conn, err := net.Dial("tcp", ts.Listener.Addr().String())
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("dial err:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
_, err = fmt.Fprint(conn, tt.req)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("conn write err:", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := ReadResponse(bufio.NewReader(conn), &Request{Method: "GET"})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal("ReadResponse err:", err)
|
||||||
|
}
|
||||||
|
conn.Close()
|
||||||
|
resp.Body.Close()
|
||||||
|
|
||||||
|
got := resp.Header["Connection"]
|
||||||
|
if !reflect.DeepEqual(got, tt.expect) {
|
||||||
|
t.Errorf("wrong Connection headers for request %q. Got %q expect %q", got, tt.expect)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func BenchmarkClientServer(b *testing.B) {
|
func BenchmarkClientServer(b *testing.B) {
|
||||||
b.ReportAllocs()
|
b.ReportAllocs()
|
||||||
b.StopTimer()
|
b.StopTimer()
|
||||||
|
@ -850,8 +850,10 @@ func (cw *chunkWriter) writeHeader(p []byte) {
|
|||||||
|
|
||||||
if w.closeAfterReply && !hasToken(cw.header.get("Connection"), "close") {
|
if w.closeAfterReply && !hasToken(cw.header.get("Connection"), "close") {
|
||||||
delHeader("Connection")
|
delHeader("Connection")
|
||||||
|
if w.req.ProtoAtLeast(1, 1) {
|
||||||
setHeader.connection = "close"
|
setHeader.connection = "close"
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
w.conn.buf.WriteString(statusLine(w.req, code))
|
w.conn.buf.WriteString(statusLine(w.req, code))
|
||||||
cw.header.WriteSubset(w.conn.buf, excludeHeader)
|
cw.header.WriteSubset(w.conn.buf, excludeHeader)
|
||||||
@ -1458,7 +1460,9 @@ func (mux *ServeMux) handler(host, path string) (h Handler, pattern string) {
|
|||||||
// pattern most closely matches the request URL.
|
// pattern most closely matches the request URL.
|
||||||
func (mux *ServeMux) ServeHTTP(w ResponseWriter, r *Request) {
|
func (mux *ServeMux) ServeHTTP(w ResponseWriter, r *Request) {
|
||||||
if r.RequestURI == "*" {
|
if r.RequestURI == "*" {
|
||||||
|
if r.ProtoAtLeast(1, 1) {
|
||||||
w.Header().Set("Connection", "close")
|
w.Header().Set("Connection", "close")
|
||||||
|
}
|
||||||
w.WriteHeader(StatusBadRequest)
|
w.WriteHeader(StatusBadRequest)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user