mirror of
https://github.com/golang/go
synced 2024-11-23 05:10:09 -07:00
net/http: Fix Range off-by-one error
Given a file of size N, a request for "Range: bytes=N-*" should return a 416 [1]. Currently, it returns a 206 and a body of 0 bytes, with the illegal Content-Range of "bytes N-(N-1)/N" [2]. [1]: RFC 7233, sec 2.1: "If a valid byte-range-set includes at least one byte-range-spec with a first-byte-pos that is less than the current length of the representation, [...]". sec 3.1: "If all of the preconditions are true, the server supports the Range header field for the target resource, and the specified range(s) are invalid or unsatisfiable, the server SHOULD send a 416 (Range Not Satisfiable) response." [2]: RFC 7233, sec 4.2: "A Content-Range field value is invalid if it contains a byte-range-resp that has a last-byte-pos value less than its first-byte-pos value, [...]" Fixes #8988 Change-Id: If3e1134e7815f5d361efea01873b29aafe3de817 Reviewed-on: https://go-review.googlesource.com/1862 Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
This commit is contained in:
parent
640c0f3849
commit
474ce6903b
@ -503,7 +503,7 @@ func parseRange(s string, size int64) ([]httpRange, error) {
|
||||
r.length = size - r.start
|
||||
} else {
|
||||
i, err := strconv.ParseInt(start, 10, 64)
|
||||
if err != nil || i > size || i < 0 {
|
||||
if err != nil || i >= size || i < 0 {
|
||||
return nil, errors.New("invalid range")
|
||||
}
|
||||
r.start = i
|
||||
|
@ -50,15 +50,23 @@ var ServeFileRangeTests = []struct {
|
||||
{r: "bytes=2-", code: StatusPartialContent, ranges: []wantRange{{2, testFileLen}}},
|
||||
{r: "bytes=-5", code: StatusPartialContent, ranges: []wantRange{{testFileLen - 5, testFileLen}}},
|
||||
{r: "bytes=3-7", code: StatusPartialContent, ranges: []wantRange{{3, 8}}},
|
||||
{r: "bytes=20-", code: StatusRequestedRangeNotSatisfiable},
|
||||
{r: "bytes=0-0,-2", code: StatusPartialContent, ranges: []wantRange{{0, 1}, {testFileLen - 2, testFileLen}}},
|
||||
{r: "bytes=0-1,5-8", code: StatusPartialContent, ranges: []wantRange{{0, 2}, {5, 9}}},
|
||||
{r: "bytes=0-1,5-", code: StatusPartialContent, ranges: []wantRange{{0, 2}, {5, testFileLen}}},
|
||||
{r: "bytes=5-1000", code: StatusPartialContent, ranges: []wantRange{{5, testFileLen}}},
|
||||
{r: "bytes=0-,1-,2-,3-,4-", code: StatusOK}, // ignore wasteful range request
|
||||
{r: "bytes=0-" + itoa(testFileLen-2), code: StatusPartialContent, ranges: []wantRange{{0, testFileLen - 1}}},
|
||||
{r: "bytes=0-" + itoa(testFileLen-1), code: StatusPartialContent, ranges: []wantRange{{0, testFileLen}}},
|
||||
{r: "bytes=0-" + itoa(testFileLen), code: StatusPartialContent, ranges: []wantRange{{0, testFileLen}}},
|
||||
{r: "bytes=0-9", code: StatusPartialContent, ranges: []wantRange{{0, testFileLen - 1}}},
|
||||
{r: "bytes=0-10", code: StatusPartialContent, ranges: []wantRange{{0, testFileLen}}},
|
||||
{r: "bytes=0-11", code: StatusPartialContent, ranges: []wantRange{{0, testFileLen}}},
|
||||
{r: "bytes=10-11", code: StatusPartialContent, ranges: []wantRange{{testFileLen - 1, testFileLen}}},
|
||||
{r: "bytes=10-", code: StatusPartialContent, ranges: []wantRange{{testFileLen - 1, testFileLen}}},
|
||||
{r: "bytes=11-", code: StatusRequestedRangeNotSatisfiable},
|
||||
{r: "bytes=11-12", code: StatusRequestedRangeNotSatisfiable},
|
||||
{r: "bytes=12-12", code: StatusRequestedRangeNotSatisfiable},
|
||||
{r: "bytes=11-100", code: StatusRequestedRangeNotSatisfiable},
|
||||
{r: "bytes=12-100", code: StatusRequestedRangeNotSatisfiable},
|
||||
{r: "bytes=100-", code: StatusRequestedRangeNotSatisfiable},
|
||||
{r: "bytes=100-1000", code: StatusRequestedRangeNotSatisfiable},
|
||||
}
|
||||
|
||||
func TestServeFile(t *testing.T) {
|
||||
|
Loading…
Reference in New Issue
Block a user