Conditional GET/HEAD: implement 412 for failed If-Match / If-Unmodified-Since (RFC 9110 §13.2.2)
- Dominant language
- Rust
- Stars
- 0
- Forks
- 0
- PR merge metrics
- No merged PRs in 30d
Description
## Summary
`conditional::evaluate_read` (the GET/HEAD read-precondition evaluator, added with the conditional-GET 304 feature on `main`) handles only `If-None-Match` → 304 and `If-Modified-Since` → 304. It does NOT evaluate `If-Match` / `If-Unmodified-Since` on GET/HEAD, and `serve_read` does not pass them. A `GET`/`HEAD` carrying a non-matching `If-Match` (or a satisfied `If-Unmodified-Since` failure) therefore proceeds to `200`/Range instead of returning **412 Precondition Failed** per RFC 9110 §13.2.2.
## Scope / provenance
- **Pre-existing on `main`** — this is a completeness gap in `main`'s conditional-GET feature, not a regression. `origin/main`'s `evaluate_read` and its `serve_read` call site are byte-identical to the current code (verified). Surfaced by codex/roborev during the PR #3 (existence-non-disclosure V1–V5) re-verification; deferred out of that security PR to keep it focused. (Note: a second codex run over the identical tree found no issues — the finding is a judgement call, but the gap is real.)
- **Not a security issue** — the write-path preconditions (`conditional::evaluate`) already implement `If-Match`/`If-None-Match` → 412 correctly for PUT/PATCH/DELETE. This is only the READ path's cache-validation completeness.
## Fix
Extend the GET/HEAD read-precondition evaluation to the full RFC 9110 §13.2.2 precedence chain:
1. `If-Match` — if present and no current representation matches (strong comparison) → **412** (evaluated first).
2. `If-Unmodified-Since` — only when `If-Match` absent; if the representation was modified after the date → **412**.
3. `If-None-Match` → 304 (existing behaviour).
4. `If-Modified-Since` — only when `If-None-Match` absent → 304 (existing behaviour).
Add a regression matrix for the `If-Match`/`If-Unmodified-Since` GET/HEAD 412 cases and the precedence interactions (e.g. a failing `If-Match` wins over a matching `If-None-Match`).
🤖 PSS agent — @jeswr's agent for `prod-solid-server` / the Solid app+Pod-Manager suite
Contributor guide
No contributing guide indexed for this repository
Research direction
Start at conditional::evaluate_read and its serve_read call site, then compare the existing GET/HEAD logic with the write-path conditional::evaluate implementation. Add the RFC 9110 precedence behavior for If-Match and If-Unmodified-Since, preserving the existing cache validators, and verify the regression matrix covers GET/HEAD 412 responses and precedence interactions.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- api, backend-api-design
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 68/100