diff --git a/internal/caches/partial_ranges.go b/internal/caches/partial_ranges.go index 5fa9a21..dad4841 100644 --- a/internal/caches/partial_ranges.go +++ b/internal/caches/partial_ranges.go @@ -188,6 +188,11 @@ func (this *PartialRanges) Reset() { this.Ranges = [][2]int64{} } +// IsCompleted 是否已下载完整 +func (this *PartialRanges) IsCompleted() bool { + return len(this.Ranges) == 1 && this.Ranges[0][0] == 0 && this.Ranges[0][1] == this.BodySize-1 +} + func (this *PartialRanges) merge(index int) { // forward var lastIndex = index diff --git a/internal/caches/reader_partial_file.go b/internal/caches/reader_partial_file.go index fa47895..d45c0cb 100644 --- a/internal/caches/reader_partial_file.go +++ b/internal/caches/reader_partial_file.go @@ -34,7 +34,7 @@ func (this *PartialFileReader) InitAutoDiscard(autoDiscard bool) error { this.header = this.openFile.header } - isOk := false + var isOk = false if autoDiscard { defer func() { @@ -54,9 +54,9 @@ func (this *PartialFileReader) InitAutoDiscard(autoDiscard bool) error { var buf = this.meta if len(buf) == 0 { buf = make([]byte, SizeMeta) - ok, err := this.readToBuff(this.fp, buf) - if err != nil { - return err + ok, readErr := this.readToBuff(this.fp, buf) + if readErr != nil { + return readErr } if !ok { return ErrNotFound @@ -73,10 +73,10 @@ func (this *PartialFileReader) InitAutoDiscard(autoDiscard bool) error { this.status = status // URL - urlLength := binary.BigEndian.Uint32(buf[SizeExpiresAt+SizeStatus : SizeExpiresAt+SizeStatus+SizeURLLength]) + var urlLength = binary.BigEndian.Uint32(buf[SizeExpiresAt+SizeStatus : SizeExpiresAt+SizeStatus+SizeURLLength]) // header - headerSize := int(binary.BigEndian.Uint32(buf[SizeExpiresAt+SizeStatus+SizeURLLength : SizeExpiresAt+SizeStatus+SizeURLLength+SizeHeaderLength])) + var headerSize = int(binary.BigEndian.Uint32(buf[SizeExpiresAt+SizeStatus+SizeURLLength : SizeExpiresAt+SizeStatus+SizeURLLength+SizeHeaderLength])) if headerSize == 0 { return nil } @@ -96,7 +96,7 @@ func (this *PartialFileReader) InitAutoDiscard(autoDiscard bool) error { if this.openFileCache != nil && len(this.header) == 0 { if headerSize > 0 && headerSize <= 512 { this.header = make([]byte, headerSize) - _, err := this.fp.Seek(this.headerOffset, io.SeekStart) + _, err = this.fp.Seek(this.headerOffset, io.SeekStart) if err != nil { return err } @@ -140,6 +140,10 @@ func (this *PartialFileReader) Ranges() *PartialRanges { return this.ranges } +func (this *PartialFileReader) IsCompleted() bool { + return this.ranges != nil && this.ranges.IsCompleted() +} + func (this *PartialFileReader) discard() error { _ = os.Remove(this.rangePath) return this.FileReader.discard() diff --git a/internal/nodes/http_request_cache.go b/internal/nodes/http_request_cache.go index d37e611..45f6db6 100644 --- a/internal/nodes/http_request_cache.go +++ b/internal/nodes/http_request_cache.go @@ -279,7 +279,7 @@ func (this *HTTPRequest) doCacheRead(useStale bool) (shouldStop bool) { } if len(rangeHeader) > 0 { - pReader, ranges := this.tryPartialReader(storage, key, useStale, rangeHeader) + pReader, ranges := this.tryPartialReader(storage, key, useStale, rangeHeader, this.cacheRef.ForcePartialContent) if pReader != nil { isPartialCache = true reader = pReader @@ -650,7 +650,7 @@ func (this *HTTPRequest) addExpiresHeader(expiresAt int64) { } // 尝试读取区间缓存 -func (this *HTTPRequest) tryPartialReader(storage caches.StorageInterface, key string, useStale bool, rangeHeader string) (caches.Reader, []rangeutils.Range) { +func (this *HTTPRequest) tryPartialReader(storage caches.StorageInterface, key string, useStale bool, rangeHeader string, forcePartialContent bool) (caches.Reader, []rangeutils.Range) { // 尝试读取Partial cache if len(rangeHeader) == 0 { return nil, nil @@ -678,15 +678,18 @@ func (this *HTTPRequest) tryPartialReader(storage caches.StorageInterface, key s } }() + // 检查是否已下载完整 + if !forcePartialContent && + len(ranges) > 0 && + ranges[0][0] == 0 && + ranges[0][1] < 0 && + !partialReader.IsCompleted() { + return nil, nil + } + // 检查范围 - //const maxFirstSpan = 16 << 20 // TODO 可以在缓存策略中设置此值 + // 这里 **切记不要** 为末尾位置指定一个中间值,因为部分软件客户端不支持 for index, r := range ranges { - // 没有指定结束位置时,自动指定一个 - /**if r.Start() >= 0 && r.End() == -1 { - if partialReader.MaxLength() > r.Start()+maxFirstSpan { - r[1] = r.Start() + maxFirstSpan - } - }**/ r1, ok := r.Convert(partialReader.MaxLength()) if !ok { return nil, nil