mirror of
https://github.com/golang/go
synced 2024-11-18 11:34:45 -07:00
net/http: send an explicit zero Content-Length when Handler never Writes
Fixes #4004 R=golang-dev, r CC=golang-dev https://golang.org/cl/6472055
This commit is contained in:
parent
79473d6b1c
commit
49f29c9c22
@ -1207,6 +1207,38 @@ func TestCaseSensitiveMethod(t *testing.T) {
|
|||||||
res.Body.Close()
|
res.Body.Close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestContentLengthZero tests that for both an HTTP/1.0 and HTTP/1.1
|
||||||
|
// request (both keep-alive), when a Handler never writes any
|
||||||
|
// response, the net/http package adds a "Content-Length: 0" response
|
||||||
|
// header.
|
||||||
|
func TestContentLengthZero(t *testing.T) {
|
||||||
|
ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, req *Request) {}))
|
||||||
|
defer ts.Close()
|
||||||
|
|
||||||
|
for _, version := range []string{"HTTP/1.0", "HTTP/1.1"} {
|
||||||
|
conn, err := net.Dial("tcp", ts.Listener.Addr().String())
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("error dialing: %v", err)
|
||||||
|
}
|
||||||
|
_, err = fmt.Fprintf(conn, "GET / %v\r\nConnection: keep-alive\r\nHost: foo\r\n\r\n", version)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("error writing: %v", err)
|
||||||
|
}
|
||||||
|
req, _ := NewRequest("GET", "/", nil)
|
||||||
|
res, err := ReadResponse(bufio.NewReader(conn), req)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("error reading response: %v", err)
|
||||||
|
}
|
||||||
|
if te := res.TransferEncoding; len(te) > 0 {
|
||||||
|
t.Errorf("For version %q, Transfer-Encoding = %q; want none", version, te)
|
||||||
|
}
|
||||||
|
if cl := res.ContentLength; cl != 0 {
|
||||||
|
t.Errorf("For version %q, Content-Length = %v; want 0", version, cl)
|
||||||
|
}
|
||||||
|
conn.Close()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// goTimeout runs f, failing t if f takes more than ns to complete.
|
// goTimeout runs f, failing t if f takes more than ns to complete.
|
||||||
func goTimeout(t *testing.T, d time.Duration, f func()) {
|
func goTimeout(t *testing.T, d time.Duration, f func()) {
|
||||||
ch := make(chan bool, 2)
|
ch := make(chan bool, 2)
|
||||||
|
@ -512,8 +512,16 @@ func (w *response) Write(data []byte) (n int, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (w *response) finishRequest() {
|
func (w *response) finishRequest() {
|
||||||
// If this was an HTTP/1.0 request with keep-alive and we sent a Content-Length
|
// If the handler never wrote any bytes and never sent a Content-Length
|
||||||
// back, we can make this a keep-alive response ...
|
// response header, set the length explicitly to zero. This helps
|
||||||
|
// HTTP/1.0 clients keep their "keep-alive" connections alive, and for
|
||||||
|
// HTTP/1.1 clients is just as good as the alternative: sending a
|
||||||
|
// chunked response and immediately sending the zero-length EOF chunk.
|
||||||
|
if w.written == 0 && w.header.get("Content-Length") == "" {
|
||||||
|
w.header.Set("Content-Length", "0")
|
||||||
|
}
|
||||||
|
// If this was an HTTP/1.0 request with keep-alive and we sent a
|
||||||
|
// Content-Length back, we can make this a keep-alive response ...
|
||||||
if w.req.wantsHttp10KeepAlive() {
|
if w.req.wantsHttp10KeepAlive() {
|
||||||
sentLength := w.header.get("Content-Length") != ""
|
sentLength := w.header.get("Content-Length") != ""
|
||||||
if sentLength && w.header.get("Connection") == "keep-alive" {
|
if sentLength && w.header.get("Connection") == "keep-alive" {
|
||||||
|
Loading…
Reference in New Issue
Block a user