forked from TrueCloudLab/frostfs-s3-gw
[#194] Fix range header handling
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
This commit is contained in:
parent
57f761d01a
commit
e5b1dae750
2 changed files with 16 additions and 6 deletions
|
@ -28,6 +28,9 @@ func fetchRangeHeader(headers http.Header, fullSize uint64) (*layer.RangeParams,
|
||||||
if len(rangeHeader) == 0 {
|
if len(rangeHeader) == 0 {
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
if fullSize == 0 {
|
||||||
|
return nil, api.GetAPIError(api.ErrInvalidRange)
|
||||||
|
}
|
||||||
if !strings.HasPrefix(rangeHeader, prefix) {
|
if !strings.HasPrefix(rangeHeader, prefix) {
|
||||||
return nil, fmt.Errorf("unknown unit in range header")
|
return nil, fmt.Errorf("unknown unit in range header")
|
||||||
}
|
}
|
||||||
|
@ -50,10 +53,13 @@ func fetchRangeHeader(headers http.Header, fullSize uint64) (*layer.RangeParams,
|
||||||
} else {
|
} else {
|
||||||
start, err0 = strconv.ParseUint(arr[0], base, bitSize)
|
start, err0 = strconv.ParseUint(arr[0], base, bitSize)
|
||||||
end, err1 = strconv.ParseUint(arr[1], base, bitSize)
|
end, err1 = strconv.ParseUint(arr[1], base, bitSize)
|
||||||
|
if end > fullSize-1 {
|
||||||
|
end = fullSize - 1
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err0 != nil || err1 != nil || start > end {
|
if err0 != nil || err1 != nil || start > end || start > fullSize {
|
||||||
return nil, fmt.Errorf("invalid Range header")
|
return nil, api.GetAPIError(api.ErrInvalidRange)
|
||||||
}
|
}
|
||||||
return &layer.RangeParams{Start: start, End: end}, nil
|
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) {
|
func writeRangeHeaders(w http.ResponseWriter, params *layer.RangeParams, size int64) {
|
||||||
w.Header().Set("Accept-Ranges", "bytes")
|
w.Header().Set(api.AcceptRanges, "bytes")
|
||||||
w.Header().Set("Content-Range", fmt.Sprintf("bytes %d-%d/%d", params.Start, params.End, size))
|
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)
|
w.WriteHeader(http.StatusPartialContent)
|
||||||
}
|
}
|
||||||
|
|
|
@ -17,8 +17,9 @@ func TestFetchRangeHeader(t *testing.T) {
|
||||||
fullSize uint64
|
fullSize uint64
|
||||||
err bool
|
err bool
|
||||||
}{
|
}{
|
||||||
{header: "bytes=0-256", expected: &layer.RangeParams{Start: 0, End: 256}, 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}, 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=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: "bytes=-10", expected: &layer.RangeParams{Start: 90, End: 99}, fullSize: 100, err: false},
|
||||||
{header: "", err: false},
|
{header: "", err: false},
|
||||||
|
@ -28,6 +29,8 @@ func TestFetchRangeHeader(t *testing.T) {
|
||||||
{header: "bytes=0-string", err: true},
|
{header: "bytes=0-string", err: true},
|
||||||
{header: "bytes:0-256", err: true},
|
{header: "bytes:0-256", err: true},
|
||||||
{header: "bytes:-", 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 := make(http.Header)
|
||||||
h.Add("Range", tc.header)
|
h.Add("Range", tc.header)
|
||||||
|
|
Loading…
Reference in a new issue