Skip to content

net/http: document that Etags in ServeContent must be RFC 7232 compliant #18054

@dsnet

Description

@dsnet

Change f386274 (CL/32014) caused a regression in the behavior of http.ServeContent such that explicitly setting the Etag no longer caused the server to return status 304 when the Etags match.

func Test(t *testing.T) {
	fs := http.FileServer(http.Dir("/tmp"))
	h := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		// Delete if-modified-since header so that ETags can be used instead of the standard cache policy.
		r.Header.Del("If-Modified-Since")

		// Set ETag to to uniquely identify the unchanged static asset.
		w.Header().Set("Etag", "6")

		fs.ServeHTTP(w, r)
	})
	ts := httptest.NewServer(h)

	// Ensure /tmp/test.txt exists.
	if err := ioutil.WriteFile("/tmp/test.txt", nil, 0664); err != nil {
		t.Fatal(err)
	}

	var c http.Client
	req, err := http.NewRequest("GET", ts.URL+"/test.txt", nil)
	if err != nil {
		t.Fatal(err)
	}
	req.Header.Add("If-None-Match", "6") // Same Etag as above
	resp, err := c.Do(req)
	if err != nil {
		t.Fatal(err)
	}
	if resp.StatusCode != 304 {
		t.Error()
	}
}

I believe this is a regression because the documentation for ServeContent explicitly says:

If the caller has set w's ETag header, ServeContent uses it to handle requests using If-Range and If-None-Match.

\cc @bradfitz

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions