denoland / denoland/std

parseCacheControl(): absent and malformed freshness directives are indistinguishable

Open
#7,256 0 comments 0 reactions 0 assignees View on GitHub
bug needs triage
Dominant language
TypeScript
Stars
3.6k
Forks
681
PR merge metrics
No merged PRs in 30d

Description

Since #7249, parseCacheControl() is lenient: a known directive with a malformed value is dropped instead of throwing. That was the right call for untrusted header bytes, but it erased a distinction RFC 9111 cares about. parseCacheControl("max-age=abc") and parseCacheControl("") both return {}.

Those two inputs call for different cache behavior:

- Absent max-age: fall back to heuristic freshness (§4.2.2).
Malformed max-age: treat the response as stale (§4.2.1).
- The module docs point implementers at the §4.2.1 advice, but the API gives them no signal to act on. Today the only way to tell the cases apart is to re-scan the raw header string yourself.

Flagged by @bartlomieju in the #7249 review as a decision to settle before stabilizing @std/http/unstable-cache-control, not a blocker while the module is unstable.

Options I can see:

1. Add an optional field to the result, e.g. invalid?: string[] with the directive names that failed to parse. Additive and cheap, but it puts parse metadata on a value type that otherwise round-trips through formatCacheControl().
2. Keep the API as-is and document that callers who need the distinction must check the raw header. Zero cost, pushes the work onto exactly the callers §4.2.1 was written for.
3. A strict option or separate strict entry point that restores throwing for trusted input.
I lean toward 1, with formatCacheControl() ignoring the field. Happy to PR whichever way this lands.

Contributor guide

Open the contributing guide

Research direction

Start with parseCacheControl() and formatCacheControl() in @std/http/unstable-cache-control, then read the module documentation and the RFC 9111 sections cited in the issue. Compare the three proposed API directions and determine how malformed directives should be signaled without breaking round-tripping. Done means the chosen behavior distinguishes absent from malformed freshness directives and is documented.

Written by the indexing model from the issue text.

Assessment

Tech stack
deno, typescript
Domain
api
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
35/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.