fix(cdn): gate 206 on the request's Range header, not object.range

The previous fix only stopped passing range options for range-less
GETs, but current workerd reports a DEFINED full-span object.range even
for a plain get() with empty options — so every response still went out
206 + Content-Range and Firefox still refused to execute the editor
glue. Verified against local workerd (wrangler dev + seeded R2): the
206 branch must key off the REQUEST having asked for a range.
Plain GET now 200 with full body; Range requests still get proper 206s.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PmR6goSk7JC17h7fkgGvHG
This commit is contained in:
Gergő Törcsvári 2026-08-17 13:36:56 +02:00
commit 1ea35f72f6
No known key found for this signature in database
GPG key ID: 8E75F2CDE64E5322

View file

@ -41,16 +41,17 @@ export default {
); );
} }
// Only ask R2 for a range when the request actually sent one: passing the // 206 must be gated on the REQUEST asking for a range, not on
// headers unconditionally makes R2 report a DEFINED object.range (full // `object.range`: current workerd reports a DEFINED object.range (full
// span) even for range-less GETs, which stamped EVERY response 206 + // span) even for a range-less get() — with OR without range options — so
// Content-Range. Chrome shrugs at a 206 <script>; Firefox fires onload but // every plain GET went out as 206 + Content-Range. Chrome shrugs at a 206
// refuses to EXECUTE it, so on hosts with no masking edge cache (staging's // <script>; Firefox fires onload but refuses to EXECUTE it, so on hosts
// workers.dev) the editor glue never ran — "runtime did not initialize // with no masking edge cache (staging's workers.dev) the editor glue never
// (no FS) in 90s" on every Firefox boot. // ran — "runtime did not initialize (no FS) in 90s" on every Firefox boot.
const rangeRequested = request.headers.has("Range");
const object = await env.BUCKET.get( const object = await env.BUCKET.get(
key, key,
request.headers.has("Range") ? { range: request.headers } : {}, rangeRequested ? { range: request.headers } : {},
); );
if (!object) { if (!object) {
return new Response("Not Found", { status: 404, headers: baseHeaders() }); return new Response("Not Found", { status: 404, headers: baseHeaders() });
@ -66,7 +67,7 @@ export default {
} }
let status = 200; let status = 200;
if (object.range) { if (rangeRequested && object.range) {
const suffix = "suffix" in object.range ? object.range.suffix : undefined; const suffix = "suffix" in object.range ? object.range.suffix : undefined;
const length = suffix const length = suffix
? Math.min(suffix, object.size) ? Math.min(suffix, object.size)