From 584b67d571e7f7f4713c60eb6bdb0f6883a3c273 Mon Sep 17 00:00:00 2001 From: Jim Ma Date: Tue, 13 Aug 2024 19:34:58 +0800 Subject: [PATCH] fix: start with zero half-open interval range (#3431) Signed-off-by: Jim Ma --- client/daemon/peer/peertask_reuse.go | 10 ++++++++-- client/daemon/transport/transport.go | 6 +++++- 2 files changed, 13 insertions(+), 3 deletions(-) diff --git a/client/daemon/peer/peertask_reuse.go b/client/daemon/peer/peertask_reuse.go index 8ef3f558a..e837ba80d 100644 --- a/client/daemon/peer/peertask_reuse.go +++ b/client/daemon/peer/peertask_reuse.go @@ -21,6 +21,7 @@ import ( "fmt" "io" "os" + "strings" "time" "github.com/go-http-utils/headers" @@ -226,6 +227,10 @@ func (ptm *peerTaskManager) storePartialFile(ctx context.Context, request *FileT return nil } +func noRangeEnd(rg string) bool { + return strings.HasSuffix(rg, "-") +} + func (ptm *peerTaskManager) tryReuseStreamPeerTask(ctx context.Context, taskID string, request *StreamTaskRequest) (io.ReadCloser, map[string]string, bool) { var ( @@ -329,12 +334,13 @@ func (ptm *peerTaskManager) tryReuseStreamPeerTask(ctx context.Context, taskID s reuseRange.Start+reuseRange.Length-1, reuse.ContentLength) } else if request.Range != nil { // the length is from reuse task, ensure it equal with request - if length != request.Range.Length { + // skip check no range end case + if length != request.Range.Length && noRangeEnd(request.URLMeta.Range) { log.Errorf("target task length %d did not match range length %d", length, request.Range.Length) return nil, nil, false } attr[headers.ContentRange] = fmt.Sprintf("bytes %d-%d/*", request.Range.Start, - request.Range.Start+request.Range.Length-1) + request.Range.Start+length-1) } // TODO record time when file closed, need add a type to implement Close and WriteTo diff --git a/client/daemon/transport/transport.go b/client/daemon/transport/transport.go index 6ac6025b7..c86e594f9 100644 --- a/client/daemon/transport/transport.go +++ b/client/daemon/transport/transport.go @@ -269,6 +269,10 @@ func NeedUseDragonfly(req *http.Request) bool { return req.Method == http.MethodGet && layerReg.MatchString(req.URL.Path) } +func isRedundantRangeHeader(header string) bool { + return header == "bytes=0-" +} + // download uses dragonfly to download. // the ctx has span info from transport, did not use the ctx from request func (rt *transport) download(ctx context.Context, req *http.Request) (*http.Response, error) { @@ -289,7 +293,7 @@ func (rt *transport) download(ctx context.Context, req *http.Request) (*http.Res var rg *nethttp.Range // Set meta range's value - if rangeHeader := req.Header.Get("Range"); len(rangeHeader) > 0 { + if rangeHeader := req.Header.Get("Range"); !isRedundantRangeHeader(rangeHeader) && len(rangeHeader) > 0 { rgs, err := nethttp.ParseRange(rangeHeader, math.MaxInt64) if err != nil { span.RecordError(err)