Validate Content-Range for ranged requests in base downloads (by name and by ID)

Abierto
#175 0 comentarios 0 reacciones 0 asignados Ver en GitHub

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
Tipo de issue
Error
Claridad
Bien especificado
Estado de actividad
Activo
Stack tecnológico
go
Área
api, backend

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

bug

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: downloadFile sets Range (1826-1829) for by-name (1784-1789) and by-ID (1797-1801) downloads alike.
  • base/base.go:1843-1848: newFileReaderWithMaxLength accepts any 200 or 206 and parses only Content-Length.
  • base/base.go:1758-1765: FileReader carries ContentLength, ContentType, SHA1, ID and Info, 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), require first == offset, last no greater than offset+size-1 when size is positive, and Content-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 as base.ErrRangeIgnored.
  • Add Status, RangeStart, RangeEnd and TotalSize (or a ContentRange struct) to FileReader so b2.Reader can stop at the known total.

Acceptance criteria

  • A 200 answer to offset=50,size=20 returns ErrRangeIgnored and closes the body, by name and by ID.
  • A 206 whose Content-Range starts at the wrong offset, or whose length disagrees with Content-Length, returns an error.
  • A correct 206 (for example from x/b2sim) fills the new fields; a 200 to offset=0 reports 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

Primeros pasos

  1. Lee el issue completo y luego la guía de contribución del proyecto.
  2. Comenta en el issue que vas a ocuparte — evita que dos personas hagan lo mismo.
  3. Haz un fork del repositorio y trabaja en una rama.
  4. Abre un pull request que haga referencia al número del issue.

Más de Backblaze/blazer

Todos los issues de Backblaze/blazer

Issues similares

Más issues de Go

Recibe los nuevos issues en tu correo

Un resumen breve de issues de GitHub para principiantes.