diff --git a/api/handler/get.go b/api/handler/get.go index b7c3792a..6c1db9ea 100644 --- a/api/handler/get.go +++ b/api/handler/get.go @@ -28,6 +28,9 @@ func fetchRangeHeader(headers http.Header, fullSize uint64) (*layer.RangeParams, if len(rangeHeader) == 0 { return nil, nil } + if fullSize == 0 { + return nil, api.GetAPIError(api.ErrInvalidRange) + } if !strings.HasPrefix(rangeHeader, prefix) { return nil, fmt.Errorf("unknown unit in range header") } @@ -50,10 +53,13 @@ func fetchRangeHeader(headers http.Header, fullSize uint64) (*layer.RangeParams, } else { start, err0 = strconv.ParseUint(arr[0], base, bitSize) end, err1 = strconv.ParseUint(arr[1], base, bitSize) + if end > fullSize-1 { + end = fullSize - 1 + } } - if err0 != nil || err1 != nil || start > end { - return nil, fmt.Errorf("invalid Range header") + if err0 != nil || err1 != nil || start > end || start > fullSize { + return nil, api.GetAPIError(api.ErrInvalidRange) } return &layer.RangeParams{Start: start, End: end}, nil } @@ -165,7 +171,8 @@ func parseHTTPTime(data string) (*time.Time, error) { } func writeRangeHeaders(w http.ResponseWriter, params *layer.RangeParams, size int64) { - w.Header().Set("Accept-Ranges", "bytes") - w.Header().Set("Content-Range", fmt.Sprintf("bytes %d-%d/%d", params.Start, params.End, size)) + w.Header().Set(api.AcceptRanges, "bytes") + w.Header().Set(api.ContentRange, fmt.Sprintf("bytes %d-%d/%d", params.Start, params.End, size)) + w.Header().Set(api.ContentLength, strconv.FormatUint(params.End-params.Start+1, 10)) w.WriteHeader(http.StatusPartialContent) } diff --git a/api/handler/get_test.go b/api/handler/get_test.go index 94a5d31c..c303fa80 100644 --- a/api/handler/get_test.go +++ b/api/handler/get_test.go @@ -17,8 +17,9 @@ func TestFetchRangeHeader(t *testing.T) { fullSize uint64 err bool }{ - {header: "bytes=0-256", expected: &layer.RangeParams{Start: 0, End: 256}, err: false}, - {header: "bytes=0-0", expected: &layer.RangeParams{Start: 0, End: 0}, err: false}, + {header: "bytes=0-256", expected: &layer.RangeParams{Start: 0, End: 256}, fullSize: 257, err: false}, + {header: "bytes=0-0", expected: &layer.RangeParams{Start: 0, End: 0}, fullSize: 1, err: false}, + {header: "bytes=0-256", expected: &layer.RangeParams{Start: 0, End: 255}, fullSize: 256, err: false}, {header: "bytes=0-", expected: &layer.RangeParams{Start: 0, End: 99}, fullSize: 100, err: false}, {header: "bytes=-10", expected: &layer.RangeParams{Start: 90, End: 99}, fullSize: 100, err: false}, {header: "", err: false}, @@ -28,6 +29,8 @@ func TestFetchRangeHeader(t *testing.T) { {header: "bytes=0-string", err: true}, {header: "bytes:0-256", err: true}, {header: "bytes:-", err: true}, + {header: "bytes=0-0", fullSize: 0, err: true}, + {header: "bytes=10-20", fullSize: 5, err: true}, } { h := make(http.Header) h.Add("Range", tc.header)