Validate Content-Range for ranged requests in base downloads (by name and by ID)
维护者通常 1 天内回复
还没有人认领这个 Issue。
评估
调研方向
Start with base/base.go, especially downloadFile, newFileReaderWithMaxLength, and the FileReader definition. Trace the by-name and by-ID download tests, then inspect b2.Reader to see how it consumes the returned metadata. Done means ranged responses are validated, ignored ranges return a typed error, and tests cover valid and malformed 206 responses plus 200 responses at nonzero and zero offsets.
由索引模型根据 Issue 内容生成。
描述
Summary
base.(*Bucket).DownloadFileByName, DownloadFileByID and their WithSSEC variants all go through downloadFile, which sends a Range header whenever an offset or size is given. The response check accepts either 200 or 206 and never reads Content-Range. RFC 9110 allows a server or intermediary to ignore Range and return the full representation with 200; blazer then hands the caller the whole object as if it were the requested bytes. FileReader has no field that lets the caller notice.
B2's own endpoints honor Range. The problem appears when a caching proxy, a custom Transport or a B2-compatible test server sits in between. b2.Reader builds its range and chunked reads on these calls, so it needs the status and Content-Range from base to detect this case.
Current behavior
At a5e0d13:
- base/base.go:1803-1836:
downloadFilesetsRange(1826-1829) for by-name (1784-1789) and by-ID (1797-1801) downloads alike. - base/base.go:1843-1848:
newFileReaderWithMaxLengthaccepts any 200 or 206 and parses onlyContent-Length. - base/base.go:1758-1765:
FileReadercarriesContentLength,ContentType,SHA1,IDandInfo, but not the status, the returned range or the total size.
Reproduced locally at a5e0d13 with a server that ignores Range and answers 200 with 100 bytes: DownloadFileByName(ctx, "o", 50, 20, false) and DownloadFileByID(ctx, "id", 50, 20, false) both succeed and return ContentLength 100.
Through b2.Reader, with x/b2sim behind a Transport that removes the Range header (10-byte object):
Object.NewRangeReader(ctx, 2, 4), ChunkSize 2: 20 bytes ("0123456789" twice), no error
Object.NewReader, ChunkSize 4: the object repeated until the test's 64-byte cap
Without the Range removal, x/b2sim answers 206 with Content-Range and the range read returns "2345".
Expected behavior
A ranged download either returns exactly the requested bytes or returns an error.
Proposed change
When a Range header was sent:
- On 206, parse
Content-Range(bytes first-last/total), requirefirst == offset,lastno greater thanoffset+size-1whensizeis positive, andContent-Length == last-first+1; otherwise close the body and return an error. - On 200, accept only when
offset == 0; otherwise close the body and return a typed, non-retryable error such asbase.ErrRangeIgnored. - Add
Status,RangeStart,RangeEndandTotalSize(or aContentRangestruct) toFileReadersob2.Readercan stop at the known total.
Acceptance criteria
- A 200 answer to
offset=50,size=20returnsErrRangeIgnoredand closes the body, by name and by ID. - A 206 whose
Content-Rangestarts at the wrong offset, or whose length disagrees withContent-Length, returns an error. - A correct 206 (for example from x/b2sim) fills the new fields; a 200 to
offset=0reports the total size. - Existing 206 and 416 tests pass.
Related
Backblaze/blazer#57 (closed) bounded the reader's short-read retry loop. Backblaze/blazer#59 (open) is a different Reader wake-up bug. Backblaze/blazer#121 (merged) fixed exact range reads at a chunk boundary. Backblaze/blazer#146 (closed, fixed by Backblaze/blazer#155) was about a bounded reader requesting past the range, not about validating the response. Backblaze/blazer#147 (merged) added x/b2sim, which honors Range. Backblaze/blazer#158 (open) asks for a full Reader for DownloadFileByID, which would read through the same code path.
- 主要语言
- Go
- 星标
- 66
- 派生
- 18
- 平均合并
- 1 天 10 小时
- 30 天内合并 PR
- 132
环境准备
- 没有 Dockerfile 或 Docker Compose 文件
- 有 Pull Request 模板
- 阅读贡献指南
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
Backblaze/blazer 的其他 Issue
-
难度 2/5 1-3 小时 新手友好度 70/100
维护者通常 1 天内回复
-
bug
难度 2/5 1-3 小时 新手友好度 76/100
维护者通常 1 天内回复
-
Bucket.Attrs never returns ReplicationConfig: replication configuration is write-only可能重新可做 关联的 PR 已关闭且未合并。 未关闭bug
难度 2/5 1-3 小时 新手友好度 75/100
维护者通常 1 天内回复
-
bug
难度 2/5 1-3 小时 新手友好度 82/100
维护者通常 1 天内回复
-
test: skip the fuzz non-vacuity guard when replaying a single seed可能已有人在做 @ffumero2003 于 5 天前认领。 未关闭testing
Backblaze/blazer#330 · 已指派 1 人 ·
维护者通常 1 天内回复
相似的 Issue
-
needs-triage typo
难度 1/5 1 小时以内 新手友好度 88/100
llm-d-incubation/llm-d-scaling-manager#122 ·
维护者通常 1 天内回复
-
good first issue severity: low tech-debt
难度 2/5 半天 新手友好度 75/100
TMHSDigital/subenum#329 ·
维护者通常 1 天内回复
-
[Bug] Backend summarize min() / max() panics when a field has no numeric values可能已有人在做 @weng5e 今天认领。 未关闭
难度 2/5 1-3 小时 新手友好度 64/100
grafana/grafana-infinity-datasource#1832 ·
维护者通常 1 天内回复
-
tech-debt
难度 2/5 1-3 小时 新手友好度 82/100
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 62/100
GillMacedo/godebugdiff#13 ·