Commit 2ff75551 authored by Dmitri Shuralyov's avatar Dmitri Shuralyov Committed by Tom Bergan

net/http: set Content-Type header for HEAD as well

In CL 50510, the Content-Type header started to be set in Redirect when
request method is GET. (Prior to that, it wasn't set at all, which is
what said CL was fixing.) However, according to HTTP specification,
the expected response for a HEAD request is identical to that of a
GET request, but without the response body.

This CL updates the behavior to set the Content-Type header for HEAD
method in addition to GET.

This actually allows a simpler implementation than before. This change
largely reverts CL 50510, and applies the simpler implementation.

Add a test for Content-Type header and body for GET, HEAD requests.

Updates CL 50510.

Change-Id: If33ea3f4bbc5246bb5dc751458004828cfe681b9
Reviewed-on: https://go-review.googlesource.com/65190
Run-TryBot: Dmitri Shuralyov <shurcool@gmail.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarEmmanuel Odeke <emm.odeke@gmail.com>
Reviewed-by: default avatarTom Bergan <tombergan@google.com>
parent 66764cc5
......@@ -2506,6 +2506,37 @@ func TestRedirect(t *testing.T) {
}
}
// Test that Content-Type header is set for GET and HEAD requests.
func TestRedirectContentTypeAndBody(t *testing.T) {
var tests = []struct {
method string
wantCT string
wantBody string
}{
{MethodGet, "text/html; charset=utf-8", "<a href=\"/foo\">Found</a>.\n\n"},
{MethodHead, "text/html; charset=utf-8", ""},
{MethodPost, "", ""},
{MethodDelete, "", ""},
{"foo", "", ""},
}
for _, tt := range tests {
req := httptest.NewRequest(tt.method, "http://example.com/qux/", nil)
rec := httptest.NewRecorder()
Redirect(rec, req, "/foo", 302)
if got, want := rec.Header().Get("Content-Type"), tt.wantCT; got != want {
t.Errorf("Redirect(%q) generated Content-Type header %q; want %q", tt.method, got, want)
}
resp := rec.Result()
body, err := ioutil.ReadAll(resp.Body)
if err != nil {
t.Fatal(err)
}
if got, want := string(body), tt.wantBody; got != want {
t.Errorf("Redirect(%q) generated Body %q; want %q", tt.method, got, want)
}
}
}
// TestZeroLengthPostAndResponse exercises an optimization done by the Transport:
// when there is no body (either because the method doesn't permit a body, or an
// explicit Content-Length of zero is present), then the transport can re-use the
......
......@@ -2016,17 +2016,16 @@ func Redirect(w ResponseWriter, r *Request, url string, code int) {
}
}
// RFC 2616 recommends that a short note "SHOULD" be included in the
// response because older user agents may not understand 301/307.
// Shouldn't send the response for POST or HEAD; that leaves GET.
writeNote := r.Method == "GET"
w.Header().Set("Location", hexEscapeNonASCII(url))
if writeNote {
if r.Method == "GET" || r.Method == "HEAD" {
w.Header().Set("Content-Type", "text/html; charset=utf-8")
}
w.WriteHeader(code)
if writeNote {
// RFC 2616 recommends that a short note "SHOULD" be included in the
// response because older user agents may not understand 301/307.
// Shouldn't send the response for POST or HEAD; that leaves GET.
if r.Method == "GET" {
note := "<a href=\"" + htmlEscape(url) + "\">" + statusText[code] + "</a>.\n"
fmt.Fprintln(w, note)
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment