Validate Content-Range for ranged requests in base downloads (by name and by ID)
Los mantenedores suelen responder en 1 día
Nadie ha tomado este issue todavía.
Evaluación
- Dificultad
- 4/5
- Tiempo estimado
- 3-5 días
- Aptitud para principiantes
- 56/100
Línea de trabajo
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.
Escrito por el modelo de indexación a partir del texto del issue.
Descripción
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.
- Lenguaje dominante
- Go
- Estrellas
- 66
- Forks
- 18
- Merge medio
- 1 d 10 h
- PR fusionados (30 d)
- 132
Preparar el entorno
- Sin Dockerfile ni archivo de Docker Compose
- Tiene una plantilla de pull request
- Leer la guía de contribución
Primeros pasos
- Lee el issue completo y luego la guía de contribución del proyecto.
- Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
- Haz un fork del repositorio y trabaja en una rama.
- Abre un pull request que haga referencia al número del issue.
Más de Backblaze/blazer
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 70/100
Los mantenedores suelen responder en 1 día
-
bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 76/100
Los mantenedores suelen responder en 1 día
-
Bucket.Attrs never returns ReplicationConfig: replication configuration is write-onlyQuizá libre de nuevo Un pull request para esta issue se cerró sin fusionarse. Abiertobug
Dificultad 2/5 1-3 horas Aptitud para principiantes 75/100
Los mantenedores suelen responder en 1 día
-
bug
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
Los mantenedores suelen responder en 1 día
-
test: skip the fuzz non-vacuity guard when replaying a single seedPosiblemente ocupada @ffumero2003 la tomó hace 5 días. Abiertotesting
Backblaze/blazer#330 · 1 asignado ·
Los mantenedores suelen responder en 1 día
Todos los issues de Backblaze/blazer
Issues similares
-
needs-triage typo
Dificultad 1/5 Menos de una hora Aptitud para principiantes 88/100
llm-d-incubation/llm-d-scaling-manager#122 ·
Los mantenedores suelen responder en 1 día
-
good first issue severity: low tech-debt
Dificultad 2/5 Medio día Aptitud para principiantes 75/100
TMHSDigital/subenum#329 ·
Los mantenedores suelen responder en 1 día
-
[Bug] Backend summarize min() / max() panics when a field has no numeric valuesPosiblemente ocupada @weng5e la tomó hoy. Abierto
Dificultad 2/5 1-3 horas Aptitud para principiantes 64/100
grafana/grafana-infinity-datasource#1832 ·
Los mantenedores suelen responder en 1 día
-
tech-debt
Dificultad 2/5 1-3 horas Aptitud para principiantes 82/100
Los mantenedores suelen responder en 1 día
-
Dificultad 2/5 1-3 horas Aptitud para principiantes 62/100
GillMacedo/godebugdiff#13 ·