diff --git a/fs/open_options.go b/fs/open_options.go index 268024b17..38a391fb9 100644 --- a/fs/open_options.go +++ b/fs/open_options.go @@ -138,6 +138,9 @@ func (o *RangeOption) Decode(size int64) (offset, limit int64) { // absolute fetch using the size passed in and makes sure the range does // not exceed filesize. Some remotes (e.g. Onedrive, Box) don't support // range requests which index from the end. +// +// It also adjusts any SeekOption~s, turning them into absolute +// RangeOption~s instead. func FixRangeOption(options []OpenOption, size int64) { if size == 0 { // if size 0 then remove RangeOption~s @@ -150,9 +153,9 @@ func FixRangeOption(options []OpenOption, size int64) { } return } - for i := range options { - option := options[i] - if x, ok := option.(*RangeOption); ok { + for i, option := range options { + switch x := option.(type) { + case *RangeOption: // If start is < 0 then fetch from the end if x.Start < 0 { x = &RangeOption{Start: size - x.End, End: -1} @@ -163,6 +166,8 @@ func FixRangeOption(options []OpenOption, size int64) { x = &RangeOption{Start: x.Start, End: size - 1} options[i] = x } + case *SeekOption: + options[i] = &RangeOption{Start: x.Offset, End: size - 1} } } } diff --git a/fs/open_options_test.go b/fs/open_options_test.go index 6327a8c9e..fefd1f906 100644 --- a/fs/open_options_test.go +++ b/fs/open_options_test.go @@ -207,6 +207,20 @@ func TestFixRangeOptions(t *testing.T) { }, size: 100, }, + { + name: "SeekOption", + in: []OpenOption{ + &HTTPOption{Key: "a", Value: "1"}, + &SeekOption{Offset: 10}, + &HTTPOption{Key: "b", Value: "2"}, + }, + want: []OpenOption{ + &HTTPOption{Key: "a", Value: "1"}, + &RangeOption{Start: 10, End: 99}, + &HTTPOption{Key: "b", Value: "2"}, + }, + size: 100, + }, } { FixRangeOption(test.in, test.size) assert.Equal(t, test.want, test.in, test.name)