Skip to content

Commit bfaa5dc

Browse files
committed
refactor(chunk): optimize Link method for improved readability and performance
1 parent 6d538f0 commit bfaa5dc

File tree

1 file changed

+50
-61
lines changed

1 file changed

+50
-61
lines changed

drivers/chunk/driver.go

Lines changed: 50 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
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

Comments
 (0)