Skip to content

Commit 9dea07c

Browse files
WC-3583 Disable Sec-Fetch-Mode check when static routing is present
When the Router worker has static routing, the check against "Sec-Fetch-Mode: navigate" is unnecessary. We have explicit static routing to indicate whether or not we should go to a User worker or the Asset worker, and should not try and guess via usually-set browser headers This adds a new parameter to unstable_canFetch RPC method, which should be fine for backwards compatibility, and can be extended in the future if needed. This was necessary because the Asset worker checks the Request headers for Sec-Fetch-Mode to indicate if it can serve an asset (including an index.html or 404.html page based on not_found_handling), but static routing is only provided to the Router worker. Thus, we need to pass more information over RPC
1 parent 26314a1 commit 9dea07c

File tree

4 files changed

+108
-17
lines changed

4 files changed

+108
-17
lines changed

packages/workers-shared/asset-worker/src/configuration.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ export const normalizeConfiguration = (
2020
version: 2,
2121
rules: {},
2222
},
23+
has_static_routing: configuration?.has_static_routing ?? false,
2324
account_id: configuration?.account_id ?? -1,
2425
script_id: configuration?.script_id ?? -1,
2526
debug: configuration?.debug ?? false,

packages/workers-shared/asset-worker/src/handler.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -198,14 +198,14 @@ export const canFetch = async (
198198
configuration: Required<AssetConfig>,
199199
exists: typeof EntrypointType.prototype.unstable_exists
200200
): Promise<boolean> => {
201-
if (
202-
!(
203-
flagIsEnabled(
204-
configuration,
205-
SEC_FETCH_MODE_NAVIGATE_HEADER_PREFERS_ASSET_SERVING
206-
) && request.headers.get("Sec-Fetch-Mode") === "navigate"
207-
)
208-
) {
201+
const shouldKeepNotFoundHandling =
202+
configuration.has_static_routing ||
203+
(flagIsEnabled(
204+
configuration,
205+
SEC_FETCH_MODE_NAVIGATE_HEADER_PREFERS_ASSET_SERVING
206+
) &&
207+
request.headers.get("Sec-Fetch-Mode") === "navigate");
208+
if (!shouldKeepNotFoundHandling) {
209209
configuration = {
210210
...configuration,
211211
not_found_handling: "none",

packages/workers-shared/asset-worker/tests/handler.test.ts

Lines changed: 98 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { vi } from "vitest";
22
import { mockJaegerBinding } from "../../utils/tracing";
33
import { Analytics } from "../src/analytics";
4+
import { SEC_FETCH_MODE_NAVIGATE_HEADER_PREFERS_ASSET_SERVING } from "../src/compatibility-flags";
45
import { normalizeConfiguration } from "../src/configuration";
56
import { canFetch, handleRequest } from "../src/handler";
67
import type { AssetConfig } from "../../utils/types";
@@ -1124,6 +1125,80 @@ describe("[Asset Worker] `canFetch`", () => {
11241125
}
11251126
});
11261127

1128+
describe('should always return "true" for 404s or SPAs when static routing is present', async () => {
1129+
const exists = (pathname: string) => {
1130+
// only our special files are present
1131+
if (["/404.html", "/index.html"].includes(pathname)) {
1132+
return "some-etag";
1133+
}
1134+
1135+
return null;
1136+
};
1137+
1138+
for (const notFoundHandling of [
1139+
"single-page-application",
1140+
"404-page",
1141+
] as const) {
1142+
for (const headers of [{}, { "Sec-Fetch-Mode": "navigate" }] as Record<
1143+
string,
1144+
string
1145+
>[]) {
1146+
for (const flags of [
1147+
[SEC_FETCH_MODE_NAVIGATE_HEADER_PREFERS_ASSET_SERVING.disable],
1148+
[SEC_FETCH_MODE_NAVIGATE_HEADER_PREFERS_ASSET_SERVING.enable],
1149+
]) {
1150+
const config = normalizeConfiguration({
1151+
not_found_handling: notFoundHandling,
1152+
compatibility_flags: flags,
1153+
has_static_routing: true,
1154+
});
1155+
1156+
it(`notFoundHandling=${notFoundHandling} Sec-Fetch-Mode=${headers["Sec-Fetch-Mode"]} flags=${flags}`, async () => {
1157+
expect(
1158+
await canFetch(
1159+
new Request("https://example.com/foo", { headers }),
1160+
// @ts-expect-error Empty config default to using mocked jaeger
1161+
mockEnv,
1162+
config,
1163+
exists
1164+
)
1165+
).toBeTruthy();
1166+
1167+
expect(
1168+
await canFetch(
1169+
new Request("https://example.com/bar", { headers }),
1170+
// @ts-expect-error Empty config default to using mocked jaeger
1171+
mockEnv,
1172+
config,
1173+
exists
1174+
)
1175+
).toBeTruthy();
1176+
1177+
expect(
1178+
await canFetch(
1179+
new Request("https://example.com/", { headers }),
1180+
// @ts-expect-error Empty config default to using mocked jaeger
1181+
mockEnv,
1182+
config,
1183+
exists
1184+
)
1185+
).toBeTruthy();
1186+
1187+
expect(
1188+
await canFetch(
1189+
new Request("https://example.com/404", { headers }),
1190+
// @ts-expect-error Empty config default to using mocked jaeger
1191+
mockEnv,
1192+
config,
1193+
exists
1194+
)
1195+
).toBeTruthy();
1196+
});
1197+
}
1198+
}
1199+
}
1200+
});
1201+
11271202
it('should return "true" even for a bad method', async () => {
11281203
const exists = (pathname: string) => {
11291204
if (pathname === "/foo.html") {
@@ -1325,29 +1400,39 @@ describe("[Asset Worker] `canFetch`", () => {
13251400
[{ "Sec-Fetch-Mode": "cors" }, false],
13261401
] as const;
13271402

1403+
const hasStaticRoutingModes = [
1404+
[false, false],
1405+
[true, true],
1406+
] as const;
1407+
13281408
const matrix = [];
13291409
for (const compatibilityOptions of compatibilityOptionsModes) {
13301410
for (const notFoundHandling of notFoundHandlingModes) {
13311411
for (const headers of headersModes) {
1332-
matrix.push({
1333-
compatibilityDate: compatibilityOptions[0].compatibilityDate,
1334-
compatibilityFlags: compatibilityOptions[0].compatibilityFlags,
1335-
notFoundHandling: notFoundHandling[0],
1336-
headers: headers[0],
1337-
expected:
1338-
compatibilityOptions[1] && notFoundHandling[1] && headers[1],
1339-
});
1412+
for (const hasStaticRouting of hasStaticRoutingModes) {
1413+
matrix.push({
1414+
compatibilityDate: compatibilityOptions[0].compatibilityDate,
1415+
compatibilityFlags: compatibilityOptions[0].compatibilityFlags,
1416+
notFoundHandling: notFoundHandling[0],
1417+
headers: headers[0],
1418+
hasStaticRouting: hasStaticRouting[0],
1419+
expected:
1420+
(hasStaticRouting[1] && notFoundHandling[1]) ||
1421+
(compatibilityOptions[1] && notFoundHandling[1] && headers[1]),
1422+
});
1423+
}
13401424
}
13411425
}
13421426
}
13431427

13441428
it.each(matrix)(
1345-
"compatibility_date $compatibilityDate, compatibility_flags $compatibilityFlags, not_found_handling $notFoundHandling, headers: $headers -> $expected",
1429+
"compatibility_date $compatibilityDate, compatibility_flags $compatibilityFlags, not_found_handling $notFoundHandling, headers: $headers, hasStaticRouting $hasStaticRouting -> $expected",
13461430
async ({
13471431
compatibilityDate,
13481432
compatibilityFlags,
13491433
notFoundHandling,
13501434
headers,
1435+
hasStaticRouting,
13511436
expected,
13521437
}) => {
13531438
expect(
@@ -1359,6 +1444,7 @@ describe("[Asset Worker] `canFetch`", () => {
13591444
compatibility_date: compatibilityDate,
13601445
compatibility_flags: compatibilityFlags,
13611446
not_found_handling: notFoundHandling,
1447+
has_static_routing: hasStaticRouting,
13621448
}),
13631449
exists
13641450
)
@@ -1373,6 +1459,7 @@ describe("[Asset Worker] `canFetch`", () => {
13731459
compatibility_date: compatibilityDate,
13741460
compatibility_flags: compatibilityFlags,
13751461
not_found_handling: notFoundHandling,
1462+
has_static_routing: hasStaticRouting,
13761463
}),
13771464
exists
13781465
)
@@ -1387,6 +1474,7 @@ describe("[Asset Worker] `canFetch`", () => {
13871474
compatibility_date: compatibilityDate,
13881475
compatibility_flags: compatibilityFlags,
13891476
not_found_handling: notFoundHandling,
1477+
has_static_routing: hasStaticRouting,
13901478
}),
13911479
exists
13921480
)
@@ -1401,6 +1489,7 @@ describe("[Asset Worker] `canFetch`", () => {
14011489
compatibility_date: compatibilityDate,
14021490
compatibility_flags: compatibilityFlags,
14031491
not_found_handling: notFoundHandling,
1492+
has_static_routing: hasStaticRouting,
14041493
}),
14051494
exists
14061495
)

packages/workers-shared/utils/types.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ export const AssetConfigSchema = z.object({
7474
.optional(),
7575
redirects: RedirectsSchema,
7676
headers: HeadersSchema,
77+
has_static_routing: z.boolean().optional(),
7778
...InternalConfigSchema.shape,
7879
});
7980

0 commit comments

Comments
 (0)