Implement format=auto (Accept-header content negotiation) #88

Open
opened 2026-08-09 03:50:49 +02:00 by clawbot · 0 comments
Collaborator

Verified against main at 61f42e6. This is the "auto format selection (format=auto based on Accept header)" item in TODO.md; confirmed missing — parseFormat (internal/imgcache/urlparser.go:241-258) has no auto case, and the client's Accept header is never read anywhere.

This is the feature that makes a proxy like pixa worth deploying: serve WebP or AVIF to clients that accept them, JPEG to those that do not, from a single URL. Without it, callers must know each client's capabilities at URL-construction time, which is exactly what they were trying to avoid.

Definition of done

  1. format=auto selects the best format the client accepts, preferring AVIF, then WebP, then falling back to the source format (or JPEG). The preference order is documented.
  2. Accept parsing handles quality values (q=) and wildcards (image/*, */*) correctly. A client sending no Accept gets the fallback.
  3. Vary: Accept is set on every negotiated response. Without it a shared cache will serve AVIF to a client that cannot render it — a correctness bug, not an optimization. See the related response-headers issue.
  4. The cache key includes the resolved format, not the literal auto, so negotiated variants do not collide.
  5. Signature interaction is decided explicitly: the signature covers format, so a URL signed for auto must validate against auto (the literal requested value) rather than the resolved one — otherwise the signature depends on the client's headers and becomes unverifiable. Add a test pinning this, and coordinate with the issue that adds q/fit to the signed payload.
  6. Repo rule: format=auto must never silently produce a format the client explicitly rejected. If nothing acceptable can be produced, return an error rather than guessing.
  7. Failing tests first, table-driven over Accept values: AVIF-capable, WebP-capable, neither, wildcard-only, absent, and a malformed header.
  8. README documents auto in the format list. make check green.
Verified against `main` at `61f42e6`. This is the "auto format selection (format=auto based on Accept header)" item in `TODO.md`; confirmed missing — `parseFormat` (`internal/imgcache/urlparser.go:241-258`) has no `auto` case, and the client's `Accept` header is never read anywhere. This is the feature that makes a proxy like pixa worth deploying: serve WebP or AVIF to clients that accept them, JPEG to those that do not, from a single URL. Without it, callers must know each client's capabilities at URL-construction time, which is exactly what they were trying to avoid. ## Definition of done 1. `format=auto` selects the best format the client accepts, preferring AVIF, then WebP, then falling back to the source format (or JPEG). The preference order is documented. 2. `Accept` parsing handles quality values (`q=`) and wildcards (`image/*`, `*/*`) correctly. A client sending no `Accept` gets the fallback. 3. **`Vary: Accept` is set on every negotiated response.** Without it a shared cache will serve AVIF to a client that cannot render it — a correctness bug, not an optimization. See the related response-headers issue. 4. The cache key includes the *resolved* format, not the literal `auto`, so negotiated variants do not collide. 5. Signature interaction is decided explicitly: the signature covers `format`, so a URL signed for `auto` must validate against `auto` (the literal requested value) rather than the resolved one — otherwise the signature depends on the client's headers and becomes unverifiable. Add a test pinning this, and coordinate with the issue that adds `q`/`fit` to the signed payload. 6. Repo rule: `format=auto` must never silently produce a format the client explicitly rejected. If nothing acceptable can be produced, return an error rather than guessing. 7. Failing tests first, table-driven over `Accept` values: AVIF-capable, WebP-capable, neither, wildcard-only, absent, and a malformed header. 8. README documents `auto` in the format list. `make check` green.
clawbot added this to the 1.0.0 milestone 2026-08-09 03:50:49 +02:00
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: sneak/pixa#88