You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 131a2ea
Browse filesBrowse the repository at this point in the historyBrowse files
fix(dispatch): serve static assets with percent-encoded filenames (#225)
* fix(dispatch): serve static assets with percent-encoded filenames
Static-asset serving-manifest keys are the decoded on-disk path (a file
named `oxc masthead.riv` is keyed with a literal space), but dispatch
looked them up with `url.pathname`, which stays percent-encoded (`%20`).
Any filename containing a space / `#` / non-ASCII char returned 404 —
e.g. the oxc.rs hero `.riv`. Confirmed against the live prod manifest:
the key held a literal space and the bytes were present.
Decode the pathname before the manifest lookup at both sites
(`resolveStaticPath` and the hashed-asset fast path), trying the raw key
first then the decoded key. Serve-side, so it fixes already-deployed
sites with no redeploy.
Decoding is segment-safe: it is rejected when it would change the
`/`-segment count, so an encoded slash (`%2F`) can never alias
`/assets%2Fx` onto `/assets/x` and slip past the `/__void/*` block, the
hashed-prefix gate, or the header/redirect rules (all keyed on the raw
pathname).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(dispatch): reject over-encoded aliases in the decoded asset lookup
Addresses the P1 review comment. The prior segment-count guard only blocked
encoded slashes (`%2F`); it still let over-encoded ordinary path text through —
`/%61ssets/app.js` decoded to `/assets/app.js` and `/%5F%5Fvoid/secret.js` to
`/__void/secret.js`, serving the manifest entry while the raw-`url.pathname`
policy gates (the `/__void/*` reserved-route block, the hashed-asset prefix
gate, and the header/redirect rules) never fired.
Replace the segment-count check with a canonical round-trip: accept the decoded
key only when re-encoding it via the WHATWG URL pathname setter reproduces the
exact request path. That admits only the encodings a conformant URL must use
(space, `#`, non-ASCII) and rejects every over-encoded spelling of ordinary
text (`%2F`, `%61`, `%5F`, `%2e%2e`) a browser would never send. This subsumes
the old encoded-slash guard.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(dispatch): accept lower-case escapes and re-encode decoded redirects
Addresses two P2 review comments on the canonical decode guard:
- Exact string equality was too strict: it rejected valid lower-case percent
escapes (the URL encoder emits upper-case, so `%c3%a9` != `%C3%A9`). Compare
after normalizing escape letter case, so a lower-case-encoded request for a
non-ASCII filename still resolves. (A literal `%` in a filename remains
unsupported — the round-trip can't reproduce the double-escaped request; it
404'd before this change too, so it is not a regression.)
- A redirect Location produced from a decoded match was emitted decoded, e.g.
`force-trailing-slash` on `/docs/a%23b` (backed by `/docs/a#b/index.html`)
returned `Location: /docs/a#b/`, which a browser reads as fragment `b/`.
Serialize the Location back to a safe URL pathname (`/docs/a%23b/`).
Factor the WHATWG path re-encoder (`URL.pathname` setter) into a shared helper
used by both the decode guard and the redirect fix.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
0 commit comments