[#194] Fix range header handling

Signed-off-by: Denis Kirillov <denis@nspcc.ru>
This commit is contained in:
Denis Kirillov 2021-08-06 12:59:28 +03:00 committed by Stanislav Bogatyrev
parent 57f761d01a
commit e5b1dae750
2 changed files with 16 additions and 6 deletions

View file

@ -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)
}

View file

@ -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)