aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJoe Kyo <xunianzu@gmail.com>2017-08-09 03:26:45 +0100
committerTom Bergan <tombergan@google.com>2017-08-09 15:42:50 +0000
commit6a7c4d69cb72f857b21c36ef077de0b97d9dbd50 (patch)
tree8effdbaf8f7e2b796b5af40a43e84eb4e51633a6 /src
parentff560ee9507cb6b3da1405faf41d6ade637118b7 (diff)
downloadgo-6a7c4d69cb72f857b21c36ef077de0b97d9dbd50.tar.xz
net/http: check If-Range header when request method is HEAD
When If-Range does not match and the requested resource is available, server should return a "200 OK" response to client. Currently server returns "200 OK" when the request method is GET, but "206 Partial Content" when method is HEAD. This change fixed this inconsistency. Change-Id: I5ad979919f4f089baba54a4445b70ca38471a906 Reviewed-on: https://go-review.googlesource.com/54110 Run-TryBot: Tom Bergan <tombergan@google.com> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Tom Bergan <tombergan@google.com>
Diffstat (limited to 'src')
-rw-r--r--src/net/http/fs.go2
-rw-r--r--src/net/http/fs_test.go81
2 files changed, 50 insertions, 33 deletions
diff --git a/src/net/http/fs.go b/src/net/http/fs.go
index 5819334b5f..cda08b4a5b 100644
--- a/src/net/http/fs.go
+++ b/src/net/http/fs.go
@@ -445,7 +445,7 @@ func checkIfModifiedSince(r *Request, modtime time.Time) condResult {
}
func checkIfRange(w ResponseWriter, r *Request, modtime time.Time) condResult {
- if r.Method != "GET" {
+ if r.Method != "GET" && r.Method != "HEAD" {
return condNone
}
ir := r.Header.get("If-Range")
diff --git a/src/net/http/fs_test.go b/src/net/http/fs_test.go
index f1037c4b5c..798cb30b29 100644
--- a/src/net/http/fs_test.go
+++ b/src/net/http/fs_test.go
@@ -895,6 +895,17 @@ func TestServeContent(t *testing.T) {
wantContentRange: "bytes 0-4/8",
wantLastMod: "Wed, 25 Jun 2014 17:12:18 GMT",
},
+ "range_with_modtime_mismatch": {
+ file: "testdata/style.css",
+ modtime: time.Date(2014, 6, 25, 17, 12, 18, 0 /* nanos */, time.UTC),
+ reqHeader: map[string]string{
+ "Range": "bytes=0-4",
+ "If-Range": "Wed, 25 Jun 2014 17:12:19 GMT",
+ },
+ wantStatus: StatusOK,
+ wantContentType: "text/css; charset=utf-8",
+ wantLastMod: "Wed, 25 Jun 2014 17:12:18 GMT",
+ },
"range_with_modtime_nanos": {
file: "testdata/style.css",
modtime: time.Date(2014, 6, 25, 17, 12, 18, 123 /* nanos */, time.UTC),
@@ -982,40 +993,46 @@ func TestServeContent(t *testing.T) {
} else {
content = tt.content
}
+ for _, method := range []string{"GET", "HEAD"} {
+ //restore content in case it is consumed by previous method
+ if content, ok := content.(*strings.Reader); ok {
+ content.Seek(io.SeekStart, 0)
+ }
- servec <- serveParam{
- name: filepath.Base(tt.file),
- content: content,
- modtime: tt.modtime,
- etag: tt.serveETag,
- contentType: tt.serveContentType,
- }
- req, err := NewRequest("GET", ts.URL, nil)
- if err != nil {
- t.Fatal(err)
- }
- for k, v := range tt.reqHeader {
- req.Header.Set(k, v)
- }
+ servec <- serveParam{
+ name: filepath.Base(tt.file),
+ content: content,
+ modtime: tt.modtime,
+ etag: tt.serveETag,
+ contentType: tt.serveContentType,
+ }
+ req, err := NewRequest(method, ts.URL, nil)
+ if err != nil {
+ t.Fatal(err)
+ }
+ for k, v := range tt.reqHeader {
+ req.Header.Set(k, v)
+ }
- c := ts.Client()
- res, err := c.Do(req)
- if err != nil {
- t.Fatal(err)
- }
- io.Copy(ioutil.Discard, res.Body)
- res.Body.Close()
- if res.StatusCode != tt.wantStatus {
- t.Errorf("test %q: status = %d; want %d", testName, res.StatusCode, tt.wantStatus)
- }
- if g, e := res.Header.Get("Content-Type"), tt.wantContentType; g != e {
- t.Errorf("test %q: content-type = %q, want %q", testName, g, e)
- }
- if g, e := res.Header.Get("Content-Range"), tt.wantContentRange; g != e {
- t.Errorf("test %q: content-range = %q, want %q", testName, g, e)
- }
- if g, e := res.Header.Get("Last-Modified"), tt.wantLastMod; g != e {
- t.Errorf("test %q: last-modified = %q, want %q", testName, g, e)
+ c := ts.Client()
+ res, err := c.Do(req)
+ if err != nil {
+ t.Fatal(err)
+ }
+ io.Copy(ioutil.Discard, res.Body)
+ res.Body.Close()
+ if res.StatusCode != tt.wantStatus {
+ t.Errorf("test %q using %q: got status = %d; want %d", testName, method, res.StatusCode, tt.wantStatus)
+ }
+ if g, e := res.Header.Get("Content-Type"), tt.wantContentType; g != e {
+ t.Errorf("test %q using %q: got content-type = %q, want %q", testName, method, g, e)
+ }
+ if g, e := res.Header.Get("Content-Range"), tt.wantContentRange; g != e {
+ t.Errorf("test %q using %q: got content-range = %q, want %q", testName, method, g, e)
+ }
+ if g, e := res.Header.Get("Last-Modified"), tt.wantLastMod; g != e {
+ t.Errorf("test %q using %q: got last-modified = %q, want %q", testName, method, g, e)
+ }
}
}
}