]> Cypherpunks repositories - gostls13.git/commitdiff
net/http: check If-Range header when request method is HEAD
authorJoe Kyo <xunianzu@gmail.com>
Wed, 9 Aug 2017 02:26:45 +0000 (03:26 +0100)
committerTom Bergan <tombergan@google.com>
Wed, 9 Aug 2017 15:42:50 +0000 (15:42 +0000)
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>
src/net/http/fs.go
src/net/http/fs_test.go

index 5819334b5f49093fc5e34f48fe7efb0018125223..cda08b4a5baea35d33c188673a1a4b107f1f9425 100644 (file)
@@ -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")
index f1037c4b5c5d433bd6841ad2abd2976aa186e69e..798cb30b2935fa8ede03f26388fd55e025f0b76a 100644 (file)
@@ -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)
+                       }
                }
        }
 }