当使用Range: bytes=0-访问分区文件缓存时,只有已缓存完整才会允许访问

防止有些客户端软件无法根据返回的Content-Range分段读取内容
This commit is contained in:
GoEdgeLab
2024-04-20 15:31:20 +08:00
parent c5d192fcdf
commit 1667fd175f
3 changed files with 28 additions and 16 deletions

View File

@@ -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

View File

@@ -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()

View File

@@ -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