55 "errors"
66 "fmt"
77 "io"
8+ "net/http"
89 stdpath "path"
910 "regexp"
1011 "strings"
@@ -13,6 +14,7 @@ import (
1314 "github.com/OpenListTeam/OpenList/v4/internal/errs"
1415 "github.com/OpenListTeam/OpenList/v4/internal/fs"
1516 "github.com/OpenListTeam/OpenList/v4/internal/model"
17+ "github.com/OpenListTeam/OpenList/v4/internal/net"
1618 "github.com/OpenListTeam/OpenList/v4/internal/op"
1719 "github.com/OpenListTeam/OpenList/v4/internal/stream"
1820 "github.com/OpenListTeam/OpenList/v4/pkg/http_range"
@@ -140,6 +142,7 @@ func (d *Chunk) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (
140142 if err != nil {
141143 return nil , err
142144 }
145+ args .Redirect = false
143146 path := stdpath .Join (reqActualPath , file .GetPath ())
144147 links := make ([]* model.Link , 0 )
145148 rrfs := make ([]model.RangeReaderIF , 0 )
@@ -171,70 +174,56 @@ func (d *Chunk) Link(ctx context.Context, file model.Obj, args model.LinkArgs) (
171174 totalLength += l .ContentLength
172175 }
173176 mergedRrf := func (ctx context.Context , httpRange http_range.Range ) (io.ReadCloser , error ) {
174- if httpRange .Length < 0 || httpRange .Start + httpRange .Length > totalLength {
175- httpRange .Length = totalLength - httpRange .Start
177+ start := httpRange .Start
178+ length := httpRange .Length
179+ if length < 0 || start + length > totalLength {
180+ length = totalLength - start
176181 }
177- firstPartIdx := 0
178- firstPartStart := httpRange .Start
179- for firstPartIdx < len (links ) && firstPartStart > links [firstPartIdx ].ContentLength {
180- firstPartStart -= links [firstPartIdx ].ContentLength
181- firstPartIdx ++
182- }
183- if firstPartIdx == len (links ) {
184- return nil , io .EOF
185- }
186- if firstPartStart + httpRange .Length <= links [firstPartIdx ].ContentLength {
187- return rrfs [firstPartIdx ].RangeRead (ctx , http_range.Range {
188- Start : firstPartStart ,
189- Length : httpRange .Length ,
190- })
191- }
192-
193- lastPartIdx := firstPartIdx
194- tailLength := firstPartStart + httpRange .Length
195- for lastPartIdx < len (links ) && tailLength > links [lastPartIdx ].ContentLength {
196- tailLength -= links [lastPartIdx ].ContentLength
197- lastPartIdx ++
198- }
199- if lastPartIdx == len (links ) || tailLength == 0 {
200- lastPartIdx --
201- tailLength = links [lastPartIdx ].ContentLength
202- }
203-
204- rs := make ([]io.Reader , 0 , lastPartIdx - firstPartIdx + 1 )
205- cs := make (utils.Closers , 0 , lastPartIdx - firstPartIdx + 1 )
206- firstRc , err := rrfs [firstPartIdx ].RangeRead (ctx , http_range.Range {
207- Start : firstPartStart ,
208- Length : links [firstPartIdx ].ContentLength - firstPartStart ,
209- })
210- if err != nil {
211- return nil , err
212- }
213- rs = append (rs , firstRc )
214- cs = append (cs , firstRc )
215- partIdx := firstPartIdx + 1
216- for partIdx < lastPartIdx {
217- rc , err := rrfs [partIdx ].RangeRead (ctx , http_range.Range {Length : - 1 })
218- if err != nil {
219- return nil , err
182+ rs := make ([]io.Reader , 0 )
183+ cs := make (utils.Closers , 0 )
184+ var (
185+ rc io.ReadCloser
186+ err error
187+ readFrom bool
188+ )
189+ for idx , l := range links {
190+ if readFrom {
191+ newLength := length - l .ContentLength
192+ if newLength < 0 {
193+ rc , err = rrfs [idx ].RangeRead (ctx , http_range.Range {Length : length })
194+ } else {
195+ length = newLength
196+ rc , err = rrfs [idx ].RangeRead (ctx , http_range.Range {Length : - 1 })
197+ }
198+ if err != nil {
199+ _ = cs .Close ()
200+ return nil , err
201+ }
202+ rs = append (rs , rc )
203+ cs = append (cs , rc )
204+ if newLength <= 0 {
205+ return utils.ReadCloser {
206+ Reader : io .MultiReader (rs ... ),
207+ Closer : & cs ,
208+ }, nil
209+ }
210+ } else if newStart := start - l .ContentLength ; newStart < 0 {
211+ rc , err = rrfs [idx ].RangeRead (ctx , http_range.Range {Start : start , Length : - 1 })
212+ if err != nil {
213+ return nil , err
214+ }
215+ length -= l .ContentLength - start
216+ if length <= 0 {
217+ return rc , nil
218+ }
219+ rs = append (rs , rc )
220+ cs = append (cs , rc )
221+ readFrom = true
222+ } else {
223+ start = newStart
220224 }
221- rs = append (rs , rc )
222- cs = append (cs , rc )
223- partIdx ++
224225 }
225- lastRc , err := rrfs [lastPartIdx ].RangeRead (ctx , http_range.Range {
226- Start : 0 ,
227- Length : tailLength ,
228- })
229- if err != nil {
230- return nil , err
231- }
232- rs = append (rs , lastRc )
233- cs = append (cs , lastRc )
234- return utils.ReadCloser {
235- Reader : io .MultiReader (rs ... ),
236- Closer : & cs ,
237- }, nil
226+ return nil , fmt .Errorf ("invalid range: start=%d,length=%d,totalLength=%d, status: %w" , httpRange .Start , httpRange .Length , totalLength , net .ErrorHttpStatusCode (http .StatusRequestedRangeNotSatisfiable ))
238227 }
239228 linkClosers := make ([]io.Closer , 0 , len (links ))
240229 for _ , l := range links {
0 commit comments