diff --git a/fixtures/asset-config/html-handling.test.ts b/fixtures/asset-config/html-handling.test.ts
index 274d69b0b574..e024bfd956cc 100644
--- a/fixtures/asset-config/html-handling.test.ts
+++ b/fixtures/asset-config/html-handling.test.ts
@@ -3,6 +3,8 @@ import { afterEach, beforeEach, describe, expect, it, vi } from "vitest";
import { applyConfigurationDefaults } from "../../packages/workers-shared/asset-worker/src/configuration";
import Worker from "../../packages/workers-shared/asset-worker/src/index";
import { getAssetWithMetadataFromKV } from "../../packages/workers-shared/asset-worker/src/utils/kv";
+import { encodingTestCases } from "./test-cases/encoding-test-cases";
+import { htmlHandlingTestCases } from "./test-cases/html-handling-test-cases";
import type { AssetMetadata } from "../../packages/workers-shared/asset-worker/src/utils/kv";
const IncomingRequest = Request;
@@ -20,7 +22,7 @@ const existsMock = (fileList: Set) => {
};
const BASE_URL = "http://example.com";
-type TestCase = {
+export type TestCase = {
title: string;
files: string[];
requestPath: string;
@@ -28,756 +30,18 @@ type TestCase = {
finalPath?: string;
};
-const testCases: {
- html_handling:
- | "auto-trailing-slash"
- | "drop-trailing-slash"
- | "force-trailing-slash"
- | "none";
- cases: TestCase[];
-}[] = [
+const testSuites = [
{
- html_handling: "auto-trailing-slash",
- cases: [
- {
- title: "/ -> 200 (with /index.html)",
- files: ["/index.html"],
- requestPath: "/index.html",
- matchedFile: "/index.html",
- finalPath: "/",
- },
- {
- title: "/index -> / 307 (with /index.html)",
- files: ["/index.html"],
- requestPath: "/index",
- matchedFile: "/index.html",
- finalPath: "/",
- },
- {
- title: "/index.html -> / 307 (with /index.html)",
- files: ["/index.html"],
- requestPath: "/index.html",
- matchedFile: "/index.html",
- finalPath: "/",
- },
- {
- title: "/both -> 200 (with /both.html)",
- files: ["/both.html", "/both/index.html"],
- requestPath: "/both",
- matchedFile: "/both.html",
- finalPath: "/both",
- },
- {
- title: "/both.html -> /both 307 (with /both.html)",
- files: ["/both.html", "/both/index.html"],
- requestPath: "/both.html",
- matchedFile: "/both.html",
- finalPath: "/both",
- },
- {
- title: "/both/ -> 200 (with /both/index.html)",
- files: ["/both.html", "/both/index.html"],
- requestPath: "/both/",
- matchedFile: "/both/index.html",
- finalPath: "/both/",
- },
- {
- title: "/both/index.html -> /both/ 307 (with /both/index.html)",
- files: ["/both.html", "/both/index.html"],
- requestPath: "/both/index.html",
- matchedFile: "/both/index.html",
- finalPath: "/both/",
- },
- {
- title: "/both/index -> /both/ 307 (with /both/index.html)",
- files: ["/both.html", "/both/index.html"],
- requestPath: "/both/index",
- matchedFile: "/both/index.html",
- finalPath: "/both/",
- },
- {
- title: "/file -> 200 (with file.html)",
- files: ["/file.html"],
- requestPath: "/file",
- matchedFile: "/file.html",
- finalPath: "/file",
- },
- {
- title: "/file.html -> /file 307 (with file.html)",
- files: ["/file.html"],
- requestPath: "/file.html",
- matchedFile: "/file.html",
- finalPath: "/file",
- },
- {
- title: "/file/ -> /file 307 (with file.html)",
- files: ["/file.html"],
- requestPath: "/file/",
- matchedFile: "/file.html",
- finalPath: "/file",
- },
- {
- title: "/file/index -> /file 307 (with file.html)",
- files: ["/file.html"],
- requestPath: "/file/index",
- matchedFile: "/file.html",
- finalPath: "/file",
- },
- {
- title: "/file/index.html -> /file 307 (with file.html)",
- files: ["/file.html"],
- requestPath: "/file/index.html",
- matchedFile: "/file.html",
- finalPath: "/file",
- },
- {
- title: "/folder -> /folder/ 307 (with /folder/index.html)",
- files: ["/folder/index.html"],
- requestPath: "/folder",
- matchedFile: "/folder/index.html",
- finalPath: "/folder/",
- },
- {
- title: "/folder.html -> /folder/ 307 (with /folder/index.html)",
- files: ["/folder/index.html"],
- requestPath: "/folder.html",
- matchedFile: "/folder/index.html",
- finalPath: "/folder/",
- },
- {
- title: "/folder/ -> 200 (with /folder/index.html)",
- files: ["/folder/index.html"],
- requestPath: "/folder/",
- matchedFile: "/folder/index.html",
- finalPath: "/folder/",
- },
- {
- title: "/folder/index -> /folder/ 307 (with /folder/index.html)",
- files: ["/folder/index.html"],
- requestPath: "/folder/index",
- matchedFile: "/folder/index.html",
- finalPath: "/folder/",
- },
- {
- title: "/folder/index.html -> /folder/ 307 (with /folder/index.html)",
- files: ["/folder/index.html"],
- requestPath: "/folder/index.html",
- matchedFile: "/folder/index.html",
- finalPath: "/folder/",
- },
- {
- title: "/bin -> /bin/ 307 (with /bin/index.html)",
- files: ["/bin%2F", "/bin/index.html"],
- requestPath: "/bin",
- matchedFile: "/bin/index.html",
- finalPath: "/bin/",
- },
- {
- title: "/bin.html -> /bin/ 307 (with /bin/index.html)",
- files: ["/bin%2F", "/bin/index.html"],
- requestPath: "/bin.html",
- matchedFile: "/bin/index.html",
- finalPath: "/bin/",
- },
- {
- title: "/bin%2F -> 200 (with /bin%2F)",
- files: ["/bin%2F", "/bin/index.html"],
- requestPath: "/bin%2F",
- matchedFile: "/bin%2F",
- finalPath: "/bin%2F",
- },
- {
- title: "/bin/ -> 200 (with /bin/index.html not /bin%2F",
- files: ["/bin%2F", "/bin/index.html"],
- requestPath: "/bin/",
- matchedFile: "/bin/index.html",
- finalPath: "/bin/",
- },
- {
- title: "/bin/index -> 307 /bin/ (with /bin/index.html)",
- files: ["/bin%2F", "/bin/index.html"],
- requestPath: "/bin/index",
- matchedFile: "/bin/index.html",
- finalPath: "/bin/",
- },
- {
- title: "/bin/index.html -> 307 /bin/ (with /bin/index.html)",
- files: ["/bin%2F", "/bin/index.html"],
- requestPath: "/bin/index.html",
- matchedFile: "/bin/index.html",
- finalPath: "/bin/",
- },
- // prefers exact match
- {
- title: "/file-bin -> 200 ",
- files: ["/file-bin", "/file-bin.html"],
- requestPath: "/file-bin",
- matchedFile: "/file-bin",
- finalPath: "/file-bin",
- },
- // (doesn't rewrite if resulting path would match another asset)
- {
- title: "/file-bin.html -> 200 ",
- files: ["/file-bin", "/file-bin.html"],
- requestPath: "/file-bin.html",
- matchedFile: "/file-bin.html",
- finalPath: "/file-bin.html",
- },
- // (finds file-bin.html --rewrite--> /file-bin, but /file-bin exists)
- {
- title: "/file-bin/ -> 404 ",
- files: ["/file-bin", "/file-bin.html"],
- requestPath: "/file-bin/",
- },
- {
- title: "/file-bin/index -> 404 ",
- files: ["/file-bin", "/file-bin.html"],
- requestPath: "/file-bin/index",
- },
- {
- title: "/file-bin/index.html -> 404 ",
- files: ["/file-bin", "/file-bin.html"],
- requestPath: "/file-bin/index.html",
- },
- ],
+ title: "htmlHanding options",
+ suite: htmlHandlingTestCases,
},
{
- html_handling: "drop-trailing-slash",
- cases: [
- // note that we don't drop the "/" if that is the only path component
- {
- title: "/ -> 200 (with /index.html)",
- files: ["/index.html"],
- requestPath: "/index.html",
- matchedFile: "/index.html",
- finalPath: "/",
- },
- {
- title: "/index -> / 307 (with /index.html)",
- files: ["/index.html"],
- requestPath: "/index",
- matchedFile: "/index.html",
- finalPath: "/",
- },
- {
- title: "/index.html -> / 307 (with /index.html)",
- files: ["/index.html"],
- requestPath: "/index.html",
- matchedFile: "/index.html",
- finalPath: "/",
- },
- {
- title: "/both -> 200 (with /both.html)",
- files: ["/both.html", "/both/index.html"],
- requestPath: "/both",
- matchedFile: "/both.html",
- finalPath: "/both",
- },
- {
- title: "/both.html -> /both 307 (with /both.html)",
- files: ["/both.html", "/both/index.html"],
- requestPath: "/both.html",
- matchedFile: "/both.html",
- finalPath: "/both",
- },
- // drops trailing slash and so it tries /both.html first
- {
- title: "/both/ -> /both 307 (with /both.html)",
- files: ["/both.html", "/both/index.html"],
- requestPath: "/both/",
- matchedFile: "/both.html",
- finalPath: "/both",
- },
- {
- title: "/both/index -> 307 (with /both.html)",
- files: ["/both.html", "/both/index.html"],
- requestPath: "/both/index",
- matchedFile: "/both.html",
- finalPath: "/both",
- },
- // can't rewrite /both/index.html: would be /both/ -> /both -> /both.html
- // ie can only access /both/index.html by exact match
- {
- title: "/both/index.html -> 200 (with /both/index.html)",
- files: ["/both.html", "/both/index.html"],
- requestPath: "/both/index.html",
- matchedFile: "/both/index.html",
- finalPath: "/both/index.html",
- },
- {
- title: "/file -> 200 (with file.html)",
- files: ["/file.html"],
- requestPath: "/file",
- matchedFile: "/file.html",
- finalPath: "/file",
- },
- {
- title: "/file.html -> /file 307 (with file.html)",
- files: ["/file.html"],
- requestPath: "/file.html",
- matchedFile: "/file.html",
- finalPath: "/file",
- },
- {
- title: "/file/ -> /file 307 (with file.html)",
- files: ["/file.html"],
- requestPath: "/file/",
- matchedFile: "/file.html",
- finalPath: "/file",
- },
- {
- title: "/file/index -> /file 307 (with file.html)",
- files: ["/file.html"],
- requestPath: "/file/index",
- matchedFile: "/file.html",
- finalPath: "/file",
- },
- {
- title: "/file/index.html -> /file 307 (with file.html)",
- files: ["/file.html"],
- requestPath: "/file/index.html",
- matchedFile: "/file.html",
- finalPath: "/file",
- },
- {
- title: "/folder -> 200 (with /folder/index.html)",
- files: ["/folder/index.html"],
- requestPath: "/folder",
- matchedFile: "/folder/index.html",
- finalPath: "/folder",
- },
- {
- title: "/folder.html -> /folder 307 (with /folder/index.html)",
- files: ["/folder/index.html"],
- requestPath: "/folder.html",
- matchedFile: "/folder/index.html",
- finalPath: "/folder",
- },
- {
- title: "/folder/ -> /folder 307 (with /folder/index.html)",
- files: ["/folder/index.html"],
- requestPath: "/folder/",
- matchedFile: "/folder/index.html",
- finalPath: "/folder",
- },
- {
- title: "/folder/index -> /folder 307 (with /folder/index.html)",
- files: ["/folder/index.html"],
- requestPath: "/folder/index",
- matchedFile: "/folder/index.html",
- finalPath: "/folder",
- },
- {
- title: "/folder/index.html -> /folder 307 (with /folder/index.html)",
- files: ["/folder/index.html"],
- requestPath: "/folder/index.html",
- matchedFile: "/folder/index.html",
- finalPath: "/folder",
- },
- {
- title: "/bin -> 200 (with /bin/index.html)",
- files: ["/bin%2F", "/bin/index.html"],
- requestPath: "/bin",
- matchedFile: "/bin/index.html",
- finalPath: "/bin",
- },
- {
- title: "/bin.html -> /bin 307 (with /bin/index.html)",
- files: ["/bin%2F", "/bin/index.html"],
- requestPath: "/bin.html",
- matchedFile: "/bin/index.html",
- finalPath: "/bin",
- },
- {
- title: "/bin%2F -> 200 (with /bin%2F)",
- files: ["/bin%2F", "/bin/index.html"],
- requestPath: "/bin%2F",
- matchedFile: "/bin%2F",
- finalPath: "/bin%2F",
- },
- {
- title: "/bin/ -> /bin 307 (with /bin/index.html not /bin%2F",
- files: ["/bin%2F", "/bin/index.html"],
- requestPath: "/bin/",
- matchedFile: "/bin/index.html",
- finalPath: "/bin",
- },
- {
- title: "/bin/index -> /bin 307 (with /bin/index.html not /bin%2F",
- files: ["/bin%2F", "/bin/index.html"],
- requestPath: "/bin/index",
- matchedFile: "/bin/index.html",
- finalPath: "/bin",
- },
- {
- title: "/bin/index.html -> /bin 307 (with /bin/index.html not /bin%2F",
- files: ["/bin%2F", "/bin/index.html"],
- requestPath: "/bin/index.html",
- matchedFile: "/bin/index.html",
- finalPath: "/bin",
- },
- {
- title: "/file-bin -> 200",
- files: ["/file-bin", "/file-bin.html"],
- requestPath: "/file-bin",
- matchedFile: "/file-bin",
- finalPath: "/file-bin",
- },
- // doesn't redirect to /file-bin because that also exists
- {
- title: "/file-bin.html -> 200 (with /file-bin.html)",
- files: ["/file-bin", "/file-bin.html"],
- requestPath: "/file-bin.html",
- matchedFile: "/file-bin.html",
- finalPath: "/file-bin.html",
- },
- // 404s because ambiguity between /file-bin or /file-bin.html?
- {
- title: "/file-bin/ -> 404",
- files: ["/file-bin", "/file-bin.html"],
- requestPath: "/file-bin/",
- },
- {
- title: "/file-bin/index -> 404",
- files: ["/file-bin", "/file-bin.html"],
- requestPath: "/file-bin/index",
- },
- {
- title: "/file-bin/index.html -> 404",
- files: ["/file-bin", "/file-bin.html"],
- requestPath: "/file-bin/index.html",
- },
- ],
- },
- {
- html_handling: "force-trailing-slash",
- cases: [
- {
- title: "/ -> 200 (with /index.html)",
- files: ["/index.html"],
- requestPath: "/index.html",
- matchedFile: "/index.html",
- finalPath: "/",
- },
- {
- title: "/index -> / 307 (with /index.html)",
- files: ["/index.html"],
- requestPath: "/index",
- matchedFile: "/index.html",
- finalPath: "/",
- },
- {
- title: "/index.html -> / 307 (with /index.html)",
- files: ["/index.html"],
- requestPath: "/index.html",
- matchedFile: "/index.html",
- finalPath: "/",
- },
- // ie tries /both/index.html first
- {
- title: "/both -> /both/ 307 (with /both/index.html)",
- files: ["/both.html", "/both/index.html"],
- requestPath: "/both",
- matchedFile: "/both/index.html",
- finalPath: "/both/",
- },
- // can't rewrite /both.html: would be /both -> /both/ -> /both/index.html
- // ie can only access /both.html by exact match
- {
- title: "/both.html -> 200",
- files: ["/both.html", "/both/index.html"],
- requestPath: "/both.html",
- matchedFile: "/both.html",
- finalPath: "/both.html",
- },
- {
- title: "/both/ -> 200 (with /both/index.html)",
- files: ["/both.html", "/both/index.html"],
- requestPath: "/both/",
- matchedFile: "/both/index.html",
- finalPath: "/both/",
- },
- {
- title: "/both/index -> /both/ 307 (with /both/index.html)",
- files: ["/both.html", "/both/index.html"],
- requestPath: "/both/index",
- matchedFile: "/both/index.html",
- finalPath: "/both/",
- },
- {
- title: "/both/index.html -> /both/ 307 (with /both/index.html)",
- files: ["/both.html", "/both/index.html"],
- requestPath: "/both/index.html",
- matchedFile: "/both/index.html",
- finalPath: "/both/",
- },
- // always ends in a trailing slash
- {
- title: "/file -> /file/ 307 (with file.html)",
- files: ["/file.html"],
- requestPath: "/file",
- matchedFile: "/file.html",
- finalPath: "/file/",
- },
- {
- title: "/file.html -> /file/ 307 (with file.html)",
- files: ["/file.html"],
- requestPath: "/file.html",
- matchedFile: "/file.html",
- finalPath: "/file/",
- },
-
- {
- title: "/file/ -> 200 (with file.html)",
- files: ["/file.html"],
- requestPath: "/file/",
- matchedFile: "/file.html",
- finalPath: "/file/",
- },
- {
- title: "/file/index -> /file/ 307 (with file.html)",
- files: ["/file.html"],
- requestPath: "/file/index",
- matchedFile: "/file.html",
- finalPath: "/file/",
- },
- {
- title: "/file/index.html -> /file/ 307 (with file.html)",
- files: ["/file.html"],
- requestPath: "/file/index.html",
- matchedFile: "/file.html",
- finalPath: "/file/",
- },
- {
- title: "/folder -> /folder/ 307 (with /folder/index.html)",
- files: ["/folder/index.html"],
- requestPath: "/folder",
- matchedFile: "/folder/index.html",
- finalPath: "/folder/",
- },
- {
- title: "/folder.html -> /folder/ 307 (with /folder/index.html)",
- files: ["/folder/index.html"],
- requestPath: "/folder.html",
- matchedFile: "/folder/index.html",
- finalPath: "/folder/",
- },
- {
- title: "/folder/ -> 200 (with /folder/index.html)",
- files: ["/folder/index.html"],
- requestPath: "/folder/",
- matchedFile: "/folder/index.html",
- finalPath: "/folder/",
- },
- {
- title: "/folder/index -> /folder/ 307 (with /folder/index.html)",
- files: ["/folder/index.html"],
- requestPath: "/folder/index",
- matchedFile: "/folder/index.html",
- finalPath: "/folder/",
- },
- {
- title: "/folder/index.html -> /folder/ 307 (with /folder/index.html)",
- files: ["/folder/index.html"],
- requestPath: "/folder/index.html",
- matchedFile: "/folder/index.html",
- finalPath: "/folder/",
- },
- {
- title: "/bin -> /bin/ 307 (with /bin/index.html)",
- files: ["/bin%2F", "/bin/index.html"],
- requestPath: "/bin",
- matchedFile: "/bin/index.html",
- finalPath: "/bin/",
- },
- {
- title: "/bin.html -> /bin/ 307 (with /bin/index.html)",
- files: ["/bin%2F", "/bin/index.html"],
- requestPath: "/bin.html",
- matchedFile: "/bin/index.html",
- finalPath: "/bin/",
- },
- {
- title: "/bin%2F -> 200 (with /bin%2F)",
- files: ["/bin%2F", "/bin/index.html"],
- requestPath: "/bin%2F",
- matchedFile: "/bin%2F",
- finalPath: "/bin%2F",
- },
- {
- title: "/bin/ -> 200 (with /bin/index.html not /bin%2F",
- files: ["/bin%2F", "/bin/index.html"],
- requestPath: "/bin/",
- matchedFile: "/bin/index.html",
- finalPath: "/bin/",
- },
- {
- title: "/bin/index -> /bin/ 307 (with /bin/index.html)",
- files: ["/bin%2F", "/bin/index.html"],
- requestPath: "/bin/index",
- matchedFile: "/bin/index.html",
- finalPath: "/bin/",
- },
- {
- title: "/bin/index.html -> /bin/ 307 (with /bin/index.html)",
- files: ["/bin%2F", "/bin/index.html"],
- requestPath: "/bin/index.html",
- matchedFile: "/bin/index.html",
- finalPath: "/bin/",
- },
- // doesn't force a trailing slash here because it would redirect to /file-bin.html
- {
- title: "/file-bin -> 200",
- files: ["/file-bin", "/file-bin.html"],
- requestPath: "/file-bin",
- matchedFile: "/file-bin",
- finalPath: "/file-bin",
- },
- {
- title: "/file-bin.html -> /file-bin/ 307 (with /file-bin.html)",
- files: ["/file-bin", "/file-bin.html"],
- requestPath: "/file-bin.html",
- matchedFile: "/file-bin.html",
- finalPath: "/file-bin/",
- },
- {
- title: "/file-bin/ -> 200",
- files: ["/file-bin", "/file-bin.html"],
- requestPath: "/file-bin/",
- matchedFile: "/file-bin.html",
- finalPath: "/file-bin/",
- },
- {
- title: "/file-bin/index -> /file-bin/ 307 (with /file-bin.html)",
- files: ["/file-bin", "/file-bin.html"],
- requestPath: "/file-bin/index",
- matchedFile: "/file-bin.html",
- finalPath: "/file-bin/",
- },
- {
- title: "/file-bin/index.html -> /file-bin/ 307 (with /file-bin.html)",
- files: ["/file-bin", "/file-bin.html"],
- requestPath: "/file-bin/index.html",
- matchedFile: "/file-bin.html",
- finalPath: "/file-bin/",
- },
- ],
- },
- {
- html_handling: "none",
- cases: [
- {
- title: "/ -> 404",
- files: ["/index.html"],
- requestPath: "/",
- },
- {
- title: "/index -> 404",
- files: ["/index.html"],
- requestPath: "/index",
- },
- {
- title: "/index.html -> 200",
- files: ["/index.html"],
- requestPath: "/index.html",
- matchedFile: "/index.html",
- finalPath: "/index.html",
- },
- {
- title: "/both -> 404",
- files: ["/both.html", "/both/index.html"],
- requestPath: "/both",
- },
- {
- title: "/both.html -> 200",
- files: ["/both.html", "/both/index.html"],
- requestPath: "/both.html",
- matchedFile: "/both.html",
- finalPath: "/both.html",
- },
- {
- title: "/both/ -> 404",
- files: ["/both.html", "/both/index.html"],
- requestPath: "/both/",
- },
- {
- title: "/both/index.html -> 200",
- files: ["/both.html", "/both/index.html"],
- requestPath: "/both/index.html",
- matchedFile: "/both/index.html",
- finalPath: "/both/index.html",
- },
- {
- title: "/file/index.html -> 404",
- files: ["/file.html"],
- requestPath: "/file/index.html",
- },
- {
- title: "/folder.html -> 404",
- files: ["/folder/index.html"],
- requestPath: "/folder.html",
- },
- {
- title: "/bin -> 404",
- files: ["/bin%2F", "/bin/index.html"],
- requestPath: "/bin",
- },
- {
- title: "/bin.html -> 404",
- files: ["/bin%2F", "/bin/index.html"],
- requestPath: "/bin.html",
- },
- {
- title: "/bin%2F -> 200",
- files: ["/bin%2F", "/bin/index.html"],
- requestPath: "/bin%2F",
- matchedFile: "/bin%2F",
- finalPath: "/bin%2F",
- },
- {
- title: "/bin/ -> 404",
- files: ["/bin%2F", "/bin/index.html"],
- requestPath: "/bin/",
- },
- {
- title: "/bin/index -> 404",
- files: ["/bin%2F", "/bin/index.html"],
- requestPath: "/bin/index",
- },
- {
- title: "/file-bin -> 200",
- files: ["/file-bin", "/file-bin.html"],
- requestPath: "/file-bin",
- matchedFile: "/file-bin",
- finalPath: "/file-bin",
- },
- {
- title: "/file-bin.html -> 200",
- files: ["/file-bin", "/file-bin.html"],
- requestPath: "/file-bin.html",
- matchedFile: "/file-bin.html",
- finalPath: "/file-bin.html",
- },
- {
- title: "/file-bin/ -> 404",
- files: ["/file-bin", "/file-bin.html"],
- requestPath: "/file-bin/",
- },
- {
- title: "/file-bin/index -> 404",
- files: ["/file-bin", "/file-bin.html"],
- requestPath: "/file-bin/index",
- },
- {
- title: "/file-bin/index.html -> 404",
- files: ["/file-bin", "/file-bin.html"],
- requestPath: "/file-bin/index.html",
- },
- ],
+ title: "encoding options",
+ suite: encodingTestCases,
},
];
-describe("htmlHanding options", () => {
+describe.each(testSuites)("$title", ({ title, suite }) => {
beforeEach(() => {
vi.mocked(getAssetWithMetadataFromKV).mockImplementation(
() =>
@@ -794,7 +58,7 @@ describe("htmlHanding options", () => {
afterEach(() => {
vi.mocked(getAssetWithMetadataFromKV).mockRestore();
});
- describe.each(testCases)(`$html_handling`, ({ html_handling, cases }) => {
+ describe.each(suite)(`$html_handling`, ({ html_handling, cases }) => {
beforeEach(() => {
vi.mocked(applyConfigurationDefaults).mockImplementation(() => {
return {
@@ -815,7 +79,6 @@ describe("htmlHanding options", () => {
undefined,
matchedFile
);
- console.dir(response.status);
expect(response.status).toBe(200);
expect(response.url).toBe(BASE_URL + finalPath);
// can't check intermediate 307 directly:
diff --git a/fixtures/asset-config/test-cases/encoding-test-cases.ts b/fixtures/asset-config/test-cases/encoding-test-cases.ts
new file mode 100644
index 000000000000..0da5719f1947
--- /dev/null
+++ b/fixtures/asset-config/test-cases/encoding-test-cases.ts
@@ -0,0 +1,631 @@
+import { TestCase } from "../html-handling.test";
+
+export const encodingTestCases: {
+ html_handling:
+ | "auto-trailing-slash"
+ | "drop-trailing-slash"
+ | "force-trailing-slash"
+ | "none";
+ cases: TestCase[];
+}[] = [
+ {
+ html_handling: "auto-trailing-slash",
+ cases: [
+ {
+ title: "/[boop] -> /%5Bboop%5D 307 (with /[boop].html)",
+ files: ["/[boop].html"],
+ requestPath: "/[boop]",
+ matchedFile: "/[boop].html",
+ finalPath: "/%5Bboop%5D",
+ },
+ {
+ title: "/%5Bboop%5D -> 200 (with /[boop].html)",
+ files: ["/[boop].html"],
+ requestPath: "/%5Bboop%5D",
+ matchedFile: "/[boop].html",
+ finalPath: "/%5Bboop%5D",
+ },
+ // auto-trailing-slash html handling still works
+ {
+ title: "/%5Bboop%5D.html -> /%5Bboop%5D 307 (with /[boop].html)",
+ files: ["/[boop].html"],
+ requestPath: "/%5Bboop%5D.html",
+ matchedFile: "/[boop].html",
+ finalPath: "/%5Bboop%5D",
+ },
+ {
+ title: "/[boop].html -> /%5Bboop%5D 307 (with /[boop].html)",
+ files: ["/[boop].html"],
+ requestPath: "/[boop].html",
+ matchedFile: "/[boop].html",
+ finalPath: "/%5Bboop%5D",
+ },
+ {
+ title: "/%5Bboop%5D/ -> /%5Bboop%5D 307 (with /[boop].html)",
+ files: ["/[boop].html"],
+ requestPath: "/%5Bboop%5D/",
+ matchedFile: "/[boop].html",
+ finalPath: "/%5Bboop%5D",
+ },
+ {
+ title: "/[boop]/ -> /%5Bboop%5D 307 (with /[boop].html)",
+ files: ["/[boop].html"],
+ requestPath: "/[boop]/",
+ matchedFile: "/[boop].html",
+ finalPath: "/%5Bboop%5D",
+ },
+ {
+ title: "/[boop] -> /%5Bboop%5D 307 (with /[boop].html)",
+ files: ["/[boop].html", "/[boop]/index.html"],
+ requestPath: "/[boop]",
+ matchedFile: "/[boop].html",
+ finalPath: "/%5Bboop%5D",
+ },
+ {
+ title: "/%5Bboop%5D -> 200 (with /[boop].html)",
+ files: ["/[boop].html", "/[boop]/index.html"],
+ requestPath: "/%5Bboop%5D",
+ matchedFile: "/[boop].html",
+ finalPath: "/%5Bboop%5D",
+ },
+ {
+ title: "/[boop].html -> /%5Bboop%5D 307 (with /[boop].html)",
+ files: ["/[boop].html", "/[boop]/index.html"],
+ requestPath: "/[boop].html",
+ matchedFile: "/[boop].html",
+ finalPath: "/%5Bboop%5D",
+ },
+ {
+ title: "/%5Bboop%5D.html -> /%5Bboop%5D 307 (with /[boop].html)",
+ files: ["/[boop].html", "/[boop]/index.html"],
+ requestPath: "/%5Bboop%5D.html",
+ matchedFile: "/[boop].html",
+ finalPath: "/%5Bboop%5D",
+ },
+ {
+ title: "/[boop]/ -> /%5Bboop%5D/ 307 (with /[boop]/index.html)",
+ files: ["/[boop].html", "/[boop]/index.html"],
+ requestPath: "/[boop]/",
+ matchedFile: "/[boop]/index.html",
+ finalPath: "/%5Bboop%5D/",
+ },
+ {
+ title: "/%5Bboop%5D/ -> 200 (with /[boop]/index.html)",
+ files: ["/[boop].html", "/[boop]/index.html"],
+ requestPath: "/%5Bboop%5D/",
+ matchedFile: "/[boop]/index.html",
+ finalPath: "/%5Bboop%5D/",
+ },
+ {
+ title:
+ "/[boop]/index.html -> /%5Bboop%5D/ 307 (with /[boop]/index.html)",
+ files: ["/[boop].html", "/[boop]/index.html"],
+ requestPath: "/[boop]/index.html",
+ matchedFile: "/[boop]/index.html",
+ finalPath: "/%5Bboop%5D/",
+ },
+ {
+ title:
+ "/%5Bboop%5D/index.html -> /%5Bboop%5D/ 307 (with /[boop]/index.html)",
+ files: ["/[boop].html", "/[boop]/index.html"],
+ requestPath: "/%5Bboop%5D/index.html",
+ matchedFile: "/[boop]/index.html",
+ finalPath: "/%5Bboop%5D/",
+ },
+ // paths with a mix of encoded and unencoded characters
+ {
+ title:
+ "/beep/[b%C3%B2op] -> /beep/%5Bb%C3%B2op%5D 307 (with /beep/[bòop].html)",
+ files: ["/beep/[bòop].html"],
+ requestPath: "/beep/[b%C3%B2op]",
+ matchedFile: "/beep/[bòop].html",
+ finalPath: "/beep/%5Bb%C3%B2op%5D",
+ },
+ // user-encoded paths should only be accessible at the (double) encoded path
+ {
+ title: "/[boop] -> /%5Bboop%5D 307 (with /[boop].html)",
+ files: ["/%5Bboop%5D.html", "/[boop].html"],
+ requestPath: "/[boop]",
+ matchedFile: "/[boop].html",
+ finalPath: "/%5Bboop%5D",
+ },
+ {
+ title: "/[boop].html -> /%5Bboop%5D 307 (with /[boop].html)",
+ files: ["/%5Bboop%5D.html", "/[boop].html"],
+ requestPath: "/[boop].html",
+ matchedFile: "/[boop].html",
+ finalPath: "/%5Bboop%5D",
+ },
+ {
+ title: "/%5Bboop%5D -> 200 (with /[boop].html)",
+ files: ["/%5Bboop%5D.html", "/[boop].html"],
+ requestPath: "/%5Bboop%5D",
+ matchedFile: "/[boop].html",
+ finalPath: "/%5Bboop%5D",
+ },
+ {
+ title: "/%5Bboop%5D.html -> /%5Bboop%5D 307 (with /[boop].html)",
+ files: ["/%5Bboop%5D.html", "/[boop].html"],
+ requestPath: "/%5Bboop%5D.html",
+ matchedFile: "/[boop].html",
+ finalPath: "/%5Bboop%5D",
+ },
+ {
+ title: "/%5Bboop%5D -> 200 (with /[boop].html)",
+ files: ["/%5Bboop%5D.html", "/[boop].html"],
+ requestPath: "/%5Bboop%5D",
+ matchedFile: "/[boop].html",
+ finalPath: "/%5Bboop%5D",
+ },
+ {
+ title: "/%255Bboop%255D -> 200 (with /%5Bboop%5D.html)",
+ files: ["/%5Bboop%5D.html", "/[boop].html"],
+ requestPath: "/%255Bboop%255D",
+ matchedFile: "/%5Bboop%5D.html",
+ finalPath: "/%255Bboop%255D",
+ },
+ {
+ title:
+ "/%255Bboop%255D.html -> /%255Bboop%255D 307 (with /%5Bboop%5D.html)",
+ files: ["/%5Bboop%5D.html", "/[boop].html"],
+ requestPath: "/%255Bboop%255D.html",
+ matchedFile: "/%5Bboop%5D.html",
+ finalPath: "/%255Bboop%255D",
+ },
+ {
+ title: "/beep?boop -> 404",
+ files: ["/beep?boop.html"],
+ requestPath: "/beep?boop",
+ },
+ {
+ title: "/beep%3Fboop -> 200 (with /beep?boop.html)",
+ files: ["/beep?boop.html"],
+ requestPath: "/beep%3Fboop",
+ matchedFile: "/beep?boop.html",
+ finalPath: "/beep%3Fboop",
+ },
+ {
+ title: "/beep%3Fboop/ -> /beep%3Fboop 307 (with /beep?boop.html)",
+ files: ["/beep?boop.html"],
+ requestPath: "/beep%3Fboop/",
+ matchedFile: "/beep?boop.html",
+ finalPath: "/beep%3Fboop",
+ },
+ ],
+ },
+ {
+ html_handling: "drop-trailing-slash",
+ cases: [
+ {
+ title: "/[boop] -> /%5Bboop%5D 307 (with /[boop].html)",
+ files: ["/[boop].html"],
+ requestPath: "/[boop]",
+ matchedFile: "/[boop].html",
+ finalPath: "/%5Bboop%5D",
+ },
+ {
+ title: "/%5Bboop%5D -> 200 (with /[boop].html)",
+ files: ["/[boop].html"],
+ requestPath: "/%5Bboop%5D",
+ matchedFile: "/[boop].html",
+ finalPath: "/%5Bboop%5D",
+ },
+ // drop-trailing-slash html handling still works
+ {
+ title: "/%5Bboop%5D.html -> /%5Bboop%5D 307 (with /[boop].html)",
+ files: ["/[boop].html"],
+ requestPath: "/%5Bboop%5D.html",
+ matchedFile: "/[boop].html",
+ finalPath: "/%5Bboop%5D",
+ },
+ {
+ title: "/[boop].html -> /%5Bboop%5D 307 (with /[boop].html)",
+ files: ["/[boop].html"],
+ requestPath: "/[boop].html",
+ matchedFile: "/[boop].html",
+ finalPath: "/%5Bboop%5D",
+ },
+ {
+ title: "/%5Bboop%5D/ -> /%5Bboop%5D 307 (with /[boop].html)",
+ files: ["/[boop].html"],
+ requestPath: "/%5Bboop%5D/",
+ matchedFile: "/[boop].html",
+ finalPath: "/%5Bboop%5D",
+ },
+ {
+ title: "/[boop]/ -> /%5Bboop%5D 307 (with /[boop].html)",
+ files: ["/[boop].html"],
+ requestPath: "/[boop]/",
+ matchedFile: "/[boop].html",
+ finalPath: "/%5Bboop%5D",
+ },
+ {
+ title: "/[boop] -> /%5Bboop%5D 307 (with /[boop].html)",
+ files: ["/[boop].html", "/[boop]/index.html"],
+ requestPath: "/[boop]",
+ matchedFile: "/[boop].html",
+ finalPath: "/%5Bboop%5D",
+ },
+ {
+ title: "/%5Bboop%5D -> 200 (with /[boop].html)",
+ files: ["/[boop].html", "/[boop]/index.html"],
+ requestPath: "/%5Bboop%5D",
+ matchedFile: "/[boop].html",
+ finalPath: "/%5Bboop%5D",
+ },
+ {
+ title: "/[boop].html -> /%5Bboop%5D 307 (with /[boop].html)",
+ files: ["/[boop].html", "/[boop]/index.html"],
+ requestPath: "/[boop].html",
+ matchedFile: "/[boop].html",
+ finalPath: "/%5Bboop%5D",
+ },
+ {
+ title: "/%5Bboop%5D.html -> /%5Bboop%5D 307 (with /[boop].html)",
+ files: ["/[boop].html", "/[boop]/index.html"],
+ requestPath: "/%5Bboop%5D.html",
+ matchedFile: "/[boop].html",
+ finalPath: "/%5Bboop%5D",
+ },
+ {
+ title: "/[boop]/ -> /%5Bboop%5D 307 (with /[boop].html)",
+ files: ["/[boop].html", "/[boop]/index.html"],
+ requestPath: "/[boop]/",
+ matchedFile: "/[boop].html",
+ finalPath: "/%5Bboop%5D",
+ },
+ {
+ title: "/%5Bboop%5D/ -> /%5Bboop%5D 307 (with /[boop].html)",
+ files: ["/[boop].html", "/[boop]/index.html"],
+ requestPath: "/%5Bboop%5D/",
+ matchedFile: "/[boop].html",
+ finalPath: "/%5Bboop%5D",
+ },
+ {
+ title:
+ "/[boop]/index.html -> /%5Bboop%5D/index.html 307 (with /[boop]/index.html)",
+ files: ["/[boop].html", "/[boop]/index.html"],
+ requestPath: "/[boop]/index.html",
+ matchedFile: "/[boop]/index.html",
+ finalPath: "/%5Bboop%5D/index.html",
+ },
+ {
+ title: "/%5Bboop%5D/index.html -> 200 (with /[boop]/index.html)",
+ files: ["/[boop].html", "/[boop]/index.html"],
+ requestPath: "/%5Bboop%5D/index.html",
+ matchedFile: "/[boop]/index.html",
+ finalPath: "/%5Bboop%5D/index.html",
+ },
+ // paths with a mix of encoded and unencoded characters
+ {
+ title:
+ "/beep/[b%C3%B2op] -> /beep/%5Bb%C3%B2op%5D 307 (with /beep/[bòop].html)",
+ files: ["/beep/[bòop].html"],
+ requestPath: "/beep/[b%C3%B2op]",
+ matchedFile: "/beep/[bòop].html",
+ finalPath: "/beep/%5Bb%C3%B2op%5D",
+ },
+ // user-encoded paths should only be accessible at the (double) encoded path
+ {
+ title: "/[boop] -> /%5Bboop%5D 307 (with /[boop].html)",
+ files: ["/%5Bboop%5D.html", "/[boop].html"],
+ requestPath: "/[boop]",
+ matchedFile: "/[boop].html",
+ finalPath: "/%5Bboop%5D",
+ },
+ {
+ title: "/[boop].html -> /%5Bboop%5D 307 (with /[boop].html)",
+ files: ["/%5Bboop%5D.html", "/[boop].html"],
+ requestPath: "/[boop].html",
+ matchedFile: "/[boop].html",
+ finalPath: "/%5Bboop%5D",
+ },
+ {
+ title: "/%5Bboop%5D -> 200 (with /[boop].html)",
+ files: ["/%5Bboop%5D.html", "/[boop].html"],
+ requestPath: "/%5Bboop%5D",
+ matchedFile: "/[boop].html",
+ finalPath: "/%5Bboop%5D",
+ },
+ {
+ title: "/%5Bboop%5D.html -> /%5Bboop%5D 307 (with /[boop].html)",
+ files: ["/%5Bboop%5D.html", "/[boop].html"],
+ requestPath: "/%5Bboop%5D.html",
+ matchedFile: "/[boop].html",
+ finalPath: "/%5Bboop%5D",
+ },
+ {
+ title: "/%5Bboop%5D -> 200 (with /[boop].html)",
+ files: ["/%5Bboop%5D.html", "/[boop].html"],
+ requestPath: "/%5Bboop%5D",
+ matchedFile: "/[boop].html",
+ finalPath: "/%5Bboop%5D",
+ },
+ {
+ title: "/%255Bboop%255D -> 200 (with /%5Bboop%5D.html)",
+ files: ["/%5Bboop%5D.html", "/[boop].html"],
+ requestPath: "/%255Bboop%255D",
+ matchedFile: "/%5Bboop%5D.html",
+ finalPath: "/%255Bboop%255D",
+ },
+ {
+ title:
+ "/%255Bboop%255D.html -> /%255Bboop%255D 307 (with /%5Bboop%5D.html)",
+ files: ["/%5Bboop%5D.html", "/[boop].html"],
+ requestPath: "/%255Bboop%255D.html",
+ matchedFile: "/%5Bboop%5D.html",
+ finalPath: "/%255Bboop%255D",
+ },
+ {
+ title: "/beep?boop -> 404",
+ files: ["/beep?boop.html"],
+ requestPath: "/beep?boop",
+ },
+ {
+ title: "/beep%3Fboop -> 200 (with /beep?boop.html)",
+ files: ["/beep?boop.html"],
+ requestPath: "/beep%3Fboop",
+ matchedFile: "/beep?boop.html",
+ finalPath: "/beep%3Fboop",
+ },
+ {
+ title: "/beep%3Fboop/ -> /beep%3Fboop 307 (with /beep?boop.html)",
+ files: ["/beep?boop.html"],
+ requestPath: "/beep%3Fboop/",
+ matchedFile: "/beep?boop.html",
+ finalPath: "/beep%3Fboop",
+ },
+ ],
+ },
+ {
+ html_handling: "force-trailing-slash",
+ cases: [
+ {
+ title: "/%5Bboop%5D/ -> 200 (with /[boop].html)",
+ files: ["/[boop].html"],
+ requestPath: "/%5Bboop%5D/",
+ matchedFile: "/[boop].html",
+ finalPath: "/%5Bboop%5D/",
+ },
+ {
+ title: "/[boop]/ -> /%5Bboop%5D/ 307 (with /[boop].html)",
+ files: ["/[boop].html"],
+ requestPath: "/[boop]/",
+ matchedFile: "/[boop].html",
+ finalPath: "/%5Bboop%5D/",
+ },
+ // force-trailing-slash html handling still works
+ {
+ title: "/[boop] -> /%5Bboop%5D/ 307 (with /[boop]/index.html)",
+ files: ["/[boop].html", "/[boop]/index.html"],
+ requestPath: "/[boop]",
+ matchedFile: "/[boop]/index.html",
+ finalPath: "/%5Bboop%5D/",
+ },
+ {
+ title: "/%5Bboop%5D -> /%5Bboop%5D/ 307 (with /[boop]/index.html)",
+ files: ["/[boop].html", "/[boop]/index.html"],
+ requestPath: "/%5Bboop%5D",
+ matchedFile: "/[boop]/index.html",
+ finalPath: "/%5Bboop%5D/",
+ },
+ {
+ title: "/[boop].html -> /%5Bboop%5D.html 307 (with /[boop].html)",
+ files: ["/[boop].html", "/[boop]/index.html"],
+ requestPath: "/[boop].html",
+ matchedFile: "/[boop].html",
+ finalPath: "/%5Bboop%5D.html",
+ },
+ {
+ title: "/%5Bboop%5D.html -> 200 (with /[boop].html)",
+ files: ["/[boop].html", "/[boop]/index.html"],
+ requestPath: "/%5Bboop%5D.html",
+ matchedFile: "/[boop].html",
+ finalPath: "/%5Bboop%5D.html",
+ },
+ {
+ title: "/[boop]/ -> /%5Bboop%5D/ 307 (with /[boop]/index.html)",
+ files: ["/[boop].html", "/[boop]/index.html"],
+ requestPath: "/[boop]/",
+ matchedFile: "/[boop]/index.html",
+ finalPath: "/%5Bboop%5D/",
+ },
+ {
+ title: "/%5Bboop%5D/ -> 200 (with /[boop]/index.html)",
+ files: ["/[boop].html", "/[boop]/index.html"],
+ requestPath: "/%5Bboop%5D/",
+ matchedFile: "/[boop]/index.html",
+ finalPath: "/%5Bboop%5D/",
+ },
+ {
+ title:
+ "/[boop]/index.html -> /%5Bboop%5D/ 307 (with /[boop]/index.html)",
+ files: ["/[boop].html", "/[boop]/index.html"],
+ requestPath: "/[boop]/index.html",
+ matchedFile: "/[boop]/index.html",
+ finalPath: "/%5Bboop%5D/",
+ },
+ {
+ title:
+ "/%5Bboop%5D/index.html -> /%5Bboop%5D/ 307 (with /[boop]/index.html)",
+ files: ["/[boop].html", "/[boop]/index.html"],
+ requestPath: "/%5Bboop%5D/index.html",
+ matchedFile: "/[boop]/index.html",
+ finalPath: "/%5Bboop%5D/",
+ },
+ // paths with a mix of encoded and unencoded characters
+ {
+ title:
+ "/beep/[b%C3%B2op]/ -> /beep/%5Bb%C3%B2op%5D/ 307 (with /beep/[bòop].html)",
+ files: ["/beep/[bòop].html"],
+ requestPath: "/beep/[b%C3%B2op]/",
+ matchedFile: "/beep/[bòop].html",
+ finalPath: "/beep/%5Bb%C3%B2op%5D/",
+ },
+ // user-encoded paths should only be accessible at the (double) encoded path
+ {
+ title: "/[boop] -> /%5Bboop%5D/ 307 (with /[boop].html)",
+ files: ["/%5Bboop%5D.html", "/[boop].html"],
+ requestPath: "/[boop]",
+ matchedFile: "/[boop].html",
+ finalPath: "/%5Bboop%5D/",
+ },
+ {
+ title: "/[boop].html -> /%5Bboop%5D/ 307 (with /[boop].html)",
+ files: ["/%5Bboop%5D.html", "/[boop].html"],
+ requestPath: "/[boop].html",
+ matchedFile: "/[boop].html",
+ finalPath: "/%5Bboop%5D/",
+ },
+ {
+ title: "/%5Bboop%5D -> /%5Bboop%5D/ 307 (with /[boop].html)",
+ files: ["/%5Bboop%5D.html", "/[boop].html"],
+ requestPath: "/%5Bboop%5D",
+ matchedFile: "/[boop].html",
+ finalPath: "/%5Bboop%5D/",
+ },
+ {
+ title: "/%5Bboop%5D.html -> /%5Bboop%5D/ 307 (with /[boop].html)",
+ files: ["/%5Bboop%5D.html", "/[boop].html"],
+ requestPath: "/%5Bboop%5D.html",
+ matchedFile: "/[boop].html",
+ finalPath: "/%5Bboop%5D/",
+ },
+ {
+ title: "/%5Bboop%5D -> /%5Bboop%5D/ 307 (with /[boop].html)",
+ files: ["/%5Bboop%5D.html", "/[boop].html"],
+ requestPath: "/%5Bboop%5D",
+ matchedFile: "/[boop].html",
+ finalPath: "/%5Bboop%5D/",
+ },
+ {
+ title:
+ "/%255Bboop%255D -> /%255Bboop%255D/ 307 (with /%5Bboop%5D.html)",
+ files: ["/%5Bboop%5D.html", "/[boop].html"],
+ requestPath: "/%255Bboop%255D",
+ matchedFile: "/%5Bboop%5D.html",
+ finalPath: "/%255Bboop%255D/",
+ },
+ {
+ title:
+ "/%255Bboop%255D.html -> /%255Bboop%255D/ 307 (with /%5Bboop%5D.html)",
+ files: ["/%5Bboop%5D.html", "/[boop].html"],
+ requestPath: "/%255Bboop%255D.html",
+ matchedFile: "/%5Bboop%5D.html",
+ finalPath: "/%255Bboop%255D/",
+ },
+ {
+ title: "/beep?boop/ -> 404",
+ files: ["/beep?boop.html"],
+ requestPath: "/beep?boop/",
+ },
+ {
+ title: "/beep%3Fboop -> /beep%3Fboop/ 307 (with /beep?boop.html)",
+ files: ["/beep?boop.html"],
+ requestPath: "/beep%3Fboop",
+ matchedFile: "/beep?boop.html",
+ finalPath: "/beep%3Fboop/",
+ },
+ {
+ title: "/beep%3Fboop/ -> 200 (with /beep?boop.html)",
+ files: ["/beep?boop.html"],
+ requestPath: "/beep%3Fboop/",
+ matchedFile: "/beep?boop.html",
+ finalPath: "/beep%3Fboop/",
+ },
+ ],
+ },
+ {
+ html_handling: "none",
+ cases: [
+ {
+ title: "/[boop] -> 404",
+ files: ["/[boop].html"],
+ requestPath: "/[boop]",
+ },
+ {
+ title: "/%5Bboop%5D -> 404",
+ files: ["/[boop].html"],
+ requestPath: "/%5Bboop%5D",
+ },
+ // encoding still operates when html_handling is set to 'none'
+ {
+ title: "/[boop].html -> /%5Bboop%5D.html 307 (with /[boop].html)",
+ files: ["/[boop].html"],
+ requestPath: "/[boop].html",
+ matchedFile: "/[boop].html",
+ finalPath: "/%5Bboop%5D.html",
+ },
+ {
+ title: "/%5Bboop%5D.html -> 200 (with /[boop].html)",
+ files: ["/[boop].html"],
+ requestPath: "/%5Bboop%5D.html",
+ matchedFile: "/[boop].html",
+ finalPath: "/%5Bboop%5D.html",
+ },
+ // mix of encoded and unencoded paths
+ {
+ title:
+ "/beep/[b%C3%B2op].html -> /beep/%5Bb%C3%B2op%5D.html 307 (with /beep/[bòop].html)",
+ files: ["/beep/[bòop].html"],
+ requestPath: "/beep/[b%C3%B2op].html",
+ matchedFile: "/beep/[bòop].html",
+ finalPath: "/beep/%5Bb%C3%B2op%5D.html",
+ },
+ // user-encoded paths should only be accessible at the (double) encoded path
+ {
+ title: "/[boop].html -> /%5Bboop%5D.html 307 (with /[boop].html)",
+ files: ["/%5Bboop%5D.html", "/[boop].html"],
+ requestPath: "/[boop].html",
+ matchedFile: "/[boop].html",
+ finalPath: "/%5Bboop%5D.html",
+ },
+ {
+ title: "/%5Bboop%5D.html -> 200 (with /[boop].html)",
+ files: ["/%5Bboop%5D.html", "/[boop].html"],
+ requestPath: "/%5Bboop%5D.html",
+ matchedFile: "/[boop].html",
+ finalPath: "/%5Bboop%5D.html",
+ },
+ {
+ title: "/[boop] -> 404",
+ files: ["/%5Bboop%5D.html", "/[boop].html"],
+ requestPath: "/[boop]",
+ },
+ {
+ title: "/%5Bboop%5D -> 404",
+ files: ["/%5Bboop%5D.html", "/[boop].html"],
+ requestPath: "/%5Bboop%5D",
+ },
+ {
+ title: "/%255Bboop%255D.html -> 200 (with /%5Bboop%5D.html)",
+ files: ["/%5Bboop%5D.html", "/[boop].html"],
+ requestPath: "/%255Bboop%255D.html",
+ matchedFile: "/%5Bboop%5D.html",
+ finalPath: "/%255Bboop%255D.html",
+ },
+ {
+ title: "/%255Bboop%255D -> 404",
+ files: ["/%5Bboop%5D.html", "/[boop].html"],
+ requestPath: "/%255Bboop%255D",
+ },
+ {
+ title: "/beep?boop/ -> 404",
+ files: ["/beep?boop.html"],
+ requestPath: "/beep?boop/",
+ },
+ {
+ title: "/beep%3Fboop.html -> 200 (with /beep?boop.html)",
+ files: ["/beep?boop.html"],
+ requestPath: "/beep%3Fboop.html",
+ matchedFile: "/beep?boop.html",
+ finalPath: "/beep%3Fboop.html",
+ },
+ {
+ title: "/beep%3Fboop -> 404",
+ files: ["/beep?boop.html"],
+ requestPath: "/beep%3Fboop",
+ },
+ ],
+ },
+];
diff --git a/fixtures/asset-config/test-cases/html-handling-test-cases.ts b/fixtures/asset-config/test-cases/html-handling-test-cases.ts
new file mode 100644
index 000000000000..8c65ebac26aa
--- /dev/null
+++ b/fixtures/asset-config/test-cases/html-handling-test-cases.ts
@@ -0,0 +1,788 @@
+import { TestCase } from "../html-handling.test";
+
+export const htmlHandlingTestCases: {
+ html_handling:
+ | "auto-trailing-slash"
+ | "drop-trailing-slash"
+ | "force-trailing-slash"
+ | "none";
+ cases: TestCase[];
+}[] = [
+ {
+ html_handling: "auto-trailing-slash",
+ cases: [
+ {
+ title: "/ -> 200 (with /index.html)",
+ files: ["/index.html"],
+ requestPath: "/index.html",
+ matchedFile: "/index.html",
+ finalPath: "/",
+ },
+ {
+ title: "/index -> / 307 (with /index.html)",
+ files: ["/index.html"],
+ requestPath: "/index",
+ matchedFile: "/index.html",
+ finalPath: "/",
+ },
+ {
+ title: "/index.html -> / 307 (with /index.html)",
+ files: ["/index.html"],
+ requestPath: "/index.html",
+ matchedFile: "/index.html",
+ finalPath: "/",
+ },
+ {
+ title: "/both -> 200 (with /both.html)",
+ files: ["/both.html", "/both/index.html"],
+ requestPath: "/both",
+ matchedFile: "/both.html",
+ finalPath: "/both",
+ },
+ {
+ title: "/both.html -> /both 307 (with /both.html)",
+ files: ["/both.html", "/both/index.html"],
+ requestPath: "/both.html",
+ matchedFile: "/both.html",
+ finalPath: "/both",
+ },
+ {
+ title: "/both/ -> 200 (with /both/index.html)",
+ files: ["/both.html", "/both/index.html"],
+ requestPath: "/both/",
+ matchedFile: "/both/index.html",
+ finalPath: "/both/",
+ },
+ {
+ title: "/both/index.html -> /both/ 307 (with /both/index.html)",
+ files: ["/both.html", "/both/index.html"],
+ requestPath: "/both/index.html",
+ matchedFile: "/both/index.html",
+ finalPath: "/both/",
+ },
+ {
+ title: "/both/index -> /both/ 307 (with /both/index.html)",
+ files: ["/both.html", "/both/index.html"],
+ requestPath: "/both/index",
+ matchedFile: "/both/index.html",
+ finalPath: "/both/",
+ },
+ {
+ title: "/file -> 200 (with file.html)",
+ files: ["/file.html"],
+ requestPath: "/file",
+ matchedFile: "/file.html",
+ finalPath: "/file",
+ },
+ {
+ title: "/file.html -> /file 307 (with file.html)",
+ files: ["/file.html"],
+ requestPath: "/file.html",
+ matchedFile: "/file.html",
+ finalPath: "/file",
+ },
+ {
+ title: "/file/ -> /file 307 (with file.html)",
+ files: ["/file.html"],
+ requestPath: "/file/",
+ matchedFile: "/file.html",
+ finalPath: "/file",
+ },
+ {
+ title: "/file/index -> /file 307 (with file.html)",
+ files: ["/file.html"],
+ requestPath: "/file/index",
+ matchedFile: "/file.html",
+ finalPath: "/file",
+ },
+ {
+ title: "/file/index.html -> /file 307 (with file.html)",
+ files: ["/file.html"],
+ requestPath: "/file/index.html",
+ matchedFile: "/file.html",
+ finalPath: "/file",
+ },
+ {
+ title: "/folder -> /folder/ 307 (with /folder/index.html)",
+ files: ["/folder/index.html"],
+ requestPath: "/folder",
+ matchedFile: "/folder/index.html",
+ finalPath: "/folder/",
+ },
+ {
+ title: "/folder.html -> /folder/ 307 (with /folder/index.html)",
+ files: ["/folder/index.html"],
+ requestPath: "/folder.html",
+ matchedFile: "/folder/index.html",
+ finalPath: "/folder/",
+ },
+ {
+ title: "/folder/ -> 200 (with /folder/index.html)",
+ files: ["/folder/index.html"],
+ requestPath: "/folder/",
+ matchedFile: "/folder/index.html",
+ finalPath: "/folder/",
+ },
+ {
+ title: "/folder/index -> /folder/ 307 (with /folder/index.html)",
+ files: ["/folder/index.html"],
+ requestPath: "/folder/index",
+ matchedFile: "/folder/index.html",
+ finalPath: "/folder/",
+ },
+ {
+ title: "/folder/index.html -> /folder/ 307 (with /folder/index.html)",
+ files: ["/folder/index.html"],
+ requestPath: "/folder/index.html",
+ matchedFile: "/folder/index.html",
+ finalPath: "/folder/",
+ },
+ // see encoding tests, but tldr only accessible at the (double) encoded path
+ {
+ title: "/bin -> /bin/ 307 (with /bin/index.html)",
+ files: ["/bin%2F", "/bin/index.html"],
+ requestPath: "/bin",
+ matchedFile: "/bin/index.html",
+ finalPath: "/bin/",
+ },
+ {
+ title: "/bin.html -> /bin/ 307 (with /bin/index.html)",
+ files: ["/bin%2F", "/bin/index.html"],
+ requestPath: "/bin.html",
+ matchedFile: "/bin/index.html",
+ finalPath: "/bin/",
+ },
+ // This is a bit rogue, but then so is the test case
+ {
+ title: "/bin%2F -> /bin 307 (with /bin/index.html)",
+ files: ["/bin%2F", "/bin/index.html"],
+ requestPath: "/bin%2F",
+ matchedFile: "/bin/index.html",
+ finalPath: "/bin/",
+ },
+ {
+ title: "/bin%252F -> 200 (with /bin%2F)",
+ files: ["/bin%2F", "/bin/index.html"],
+ requestPath: "/bin%252F",
+ matchedFile: "/bin%2F",
+ finalPath: "/bin%252F",
+ },
+ {
+ title: "/bin/ -> 200 (with /bin/index.html not /bin%2F",
+ files: ["/bin%2F", "/bin/index.html"],
+ requestPath: "/bin/",
+ matchedFile: "/bin/index.html",
+ finalPath: "/bin/",
+ },
+ {
+ title: "/bin/index -> 307 /bin/ (with /bin/index.html)",
+ files: ["/bin%2F", "/bin/index.html"],
+ requestPath: "/bin/index",
+ matchedFile: "/bin/index.html",
+ finalPath: "/bin/",
+ },
+ {
+ title: "/bin/index.html -> 307 /bin/ (with /bin/index.html)",
+ files: ["/bin%2F", "/bin/index.html"],
+ requestPath: "/bin/index.html",
+ matchedFile: "/bin/index.html",
+ finalPath: "/bin/",
+ },
+ // prefers exact match
+ {
+ title: "/file-bin -> 200 ",
+ files: ["/file-bin", "/file-bin.html"],
+ requestPath: "/file-bin",
+ matchedFile: "/file-bin",
+ finalPath: "/file-bin",
+ },
+ // (doesn't rewrite if resulting path would match another asset)
+ {
+ title: "/file-bin.html -> 200 ",
+ files: ["/file-bin", "/file-bin.html"],
+ requestPath: "/file-bin.html",
+ matchedFile: "/file-bin.html",
+ finalPath: "/file-bin.html",
+ },
+ // (finds file-bin.html --rewrite--> /file-bin, but /file-bin exists)
+ {
+ title: "/file-bin/ -> 404 ",
+ files: ["/file-bin", "/file-bin.html"],
+ requestPath: "/file-bin/",
+ },
+ {
+ title: "/file-bin/index -> 404 ",
+ files: ["/file-bin", "/file-bin.html"],
+ requestPath: "/file-bin/index",
+ },
+ {
+ title: "/file-bin/index.html -> 404 ",
+ files: ["/file-bin", "/file-bin.html"],
+ requestPath: "/file-bin/index.html",
+ },
+ ],
+ },
+ {
+ html_handling: "drop-trailing-slash",
+ cases: [
+ // note that we don't drop the "/" if that is the only path component
+ {
+ title: "/ -> 200 (with /index.html)",
+ files: ["/index.html"],
+ requestPath: "/index.html",
+ matchedFile: "/index.html",
+ finalPath: "/",
+ },
+ {
+ title: "/index -> / 307 (with /index.html)",
+ files: ["/index.html"],
+ requestPath: "/index",
+ matchedFile: "/index.html",
+ finalPath: "/",
+ },
+ {
+ title: "/index.html -> / 307 (with /index.html)",
+ files: ["/index.html"],
+ requestPath: "/index.html",
+ matchedFile: "/index.html",
+ finalPath: "/",
+ },
+ {
+ title: "/both -> 200 (with /both.html)",
+ files: ["/both.html", "/both/index.html"],
+ requestPath: "/both",
+ matchedFile: "/both.html",
+ finalPath: "/both",
+ },
+ {
+ title: "/both.html -> /both 307 (with /both.html)",
+ files: ["/both.html", "/both/index.html"],
+ requestPath: "/both.html",
+ matchedFile: "/both.html",
+ finalPath: "/both",
+ },
+ // drops trailing slash and so it tries /both.html first
+ {
+ title: "/both/ -> /both 307 (with /both.html)",
+ files: ["/both.html", "/both/index.html"],
+ requestPath: "/both/",
+ matchedFile: "/both.html",
+ finalPath: "/both",
+ },
+ {
+ title: "/both/index -> 307 (with /both.html)",
+ files: ["/both.html", "/both/index.html"],
+ requestPath: "/both/index",
+ matchedFile: "/both.html",
+ finalPath: "/both",
+ },
+ // can't rewrite /both/index.html: would be /both/ -> /both -> /both.html
+ // ie can only access /both/index.html by exact match
+ {
+ title: "/both/index.html -> 200 (with /both/index.html)",
+ files: ["/both.html", "/both/index.html"],
+ requestPath: "/both/index.html",
+ matchedFile: "/both/index.html",
+ finalPath: "/both/index.html",
+ },
+ {
+ title: "/file -> 200 (with file.html)",
+ files: ["/file.html"],
+ requestPath: "/file",
+ matchedFile: "/file.html",
+ finalPath: "/file",
+ },
+ {
+ title: "/file.html -> /file 307 (with file.html)",
+ files: ["/file.html"],
+ requestPath: "/file.html",
+ matchedFile: "/file.html",
+ finalPath: "/file",
+ },
+ {
+ title: "/file/ -> /file 307 (with file.html)",
+ files: ["/file.html"],
+ requestPath: "/file/",
+ matchedFile: "/file.html",
+ finalPath: "/file",
+ },
+ {
+ title: "/file/index -> /file 307 (with file.html)",
+ files: ["/file.html"],
+ requestPath: "/file/index",
+ matchedFile: "/file.html",
+ finalPath: "/file",
+ },
+ {
+ title: "/file/index.html -> /file 307 (with file.html)",
+ files: ["/file.html"],
+ requestPath: "/file/index.html",
+ matchedFile: "/file.html",
+ finalPath: "/file",
+ },
+ {
+ title: "/folder -> 200 (with /folder/index.html)",
+ files: ["/folder/index.html"],
+ requestPath: "/folder",
+ matchedFile: "/folder/index.html",
+ finalPath: "/folder",
+ },
+ {
+ title: "/folder.html -> /folder 307 (with /folder/index.html)",
+ files: ["/folder/index.html"],
+ requestPath: "/folder.html",
+ matchedFile: "/folder/index.html",
+ finalPath: "/folder",
+ },
+ {
+ title: "/folder/ -> /folder 307 (with /folder/index.html)",
+ files: ["/folder/index.html"],
+ requestPath: "/folder/",
+ matchedFile: "/folder/index.html",
+ finalPath: "/folder",
+ },
+ {
+ title: "/folder/index -> /folder 307 (with /folder/index.html)",
+ files: ["/folder/index.html"],
+ requestPath: "/folder/index",
+ matchedFile: "/folder/index.html",
+ finalPath: "/folder",
+ },
+ {
+ title: "/folder/index.html -> /folder 307 (with /folder/index.html)",
+ files: ["/folder/index.html"],
+ requestPath: "/folder/index.html",
+ matchedFile: "/folder/index.html",
+ finalPath: "/folder",
+ },
+ {
+ title: "/bin -> 200 (with /bin/index.html)",
+ files: ["/bin%2F", "/bin/index.html"],
+ requestPath: "/bin",
+ matchedFile: "/bin/index.html",
+ finalPath: "/bin",
+ },
+ {
+ title: "/bin.html -> /bin 307 (with /bin/index.html)",
+ files: ["/bin%2F", "/bin/index.html"],
+ requestPath: "/bin.html",
+ matchedFile: "/bin/index.html",
+ finalPath: "/bin",
+ },
+ // This is a bit rogue, but then so is the test case
+ {
+ title: "/bin%2F -> /bin 307 (with /bin/index.html)",
+ files: ["/bin%2F", "/bin/index.html"],
+ requestPath: "/bin%2F",
+ matchedFile: "/bin/index.html",
+ finalPath: "/bin",
+ },
+ {
+ title: "/bin%252F -> 200 (with /bin%2F)",
+ files: ["/bin%2F", "/bin/index.html"],
+ requestPath: "/bin%252F",
+ matchedFile: "/bin%2F",
+ finalPath: "/bin%252F",
+ },
+ {
+ title: "/bin/ -> /bin 307 (with /bin/index.html not /bin%2F",
+ files: ["/bin%2F", "/bin/index.html"],
+ requestPath: "/bin/",
+ matchedFile: "/bin/index.html",
+ finalPath: "/bin",
+ },
+ {
+ title: "/bin/index -> /bin 307 (with /bin/index.html not /bin%2F",
+ files: ["/bin%2F", "/bin/index.html"],
+ requestPath: "/bin/index",
+ matchedFile: "/bin/index.html",
+ finalPath: "/bin",
+ },
+ {
+ title: "/bin/index.html -> /bin 307 (with /bin/index.html not /bin%2F",
+ files: ["/bin%2F", "/bin/index.html"],
+ requestPath: "/bin/index.html",
+ matchedFile: "/bin/index.html",
+ finalPath: "/bin",
+ },
+ {
+ title: "/file-bin -> 200",
+ files: ["/file-bin", "/file-bin.html"],
+ requestPath: "/file-bin",
+ matchedFile: "/file-bin",
+ finalPath: "/file-bin",
+ },
+ // doesn't redirect to /file-bin because that also exists
+ {
+ title: "/file-bin.html -> 200 (with /file-bin.html)",
+ files: ["/file-bin", "/file-bin.html"],
+ requestPath: "/file-bin.html",
+ matchedFile: "/file-bin.html",
+ finalPath: "/file-bin.html",
+ },
+ // 404s because ambiguity between /file-bin or /file-bin.html?
+ {
+ title: "/file-bin/ -> 404",
+ files: ["/file-bin", "/file-bin.html"],
+ requestPath: "/file-bin/",
+ },
+ {
+ title: "/file-bin/index -> 404",
+ files: ["/file-bin", "/file-bin.html"],
+ requestPath: "/file-bin/index",
+ },
+ {
+ title: "/file-bin/index.html -> 404",
+ files: ["/file-bin", "/file-bin.html"],
+ requestPath: "/file-bin/index.html",
+ },
+ ],
+ },
+ {
+ html_handling: "force-trailing-slash",
+ cases: [
+ {
+ title: "/ -> 200 (with /index.html)",
+ files: ["/index.html"],
+ requestPath: "/index.html",
+ matchedFile: "/index.html",
+ finalPath: "/",
+ },
+ {
+ title: "/index -> / 307 (with /index.html)",
+ files: ["/index.html"],
+ requestPath: "/index",
+ matchedFile: "/index.html",
+ finalPath: "/",
+ },
+ {
+ title: "/index.html -> / 307 (with /index.html)",
+ files: ["/index.html"],
+ requestPath: "/index.html",
+ matchedFile: "/index.html",
+ finalPath: "/",
+ },
+ // ie tries /both/index.html first
+ {
+ title: "/both -> /both/ 307 (with /both/index.html)",
+ files: ["/both.html", "/both/index.html"],
+ requestPath: "/both",
+ matchedFile: "/both/index.html",
+ finalPath: "/both/",
+ },
+ // can't rewrite /both.html: would be /both -> /both/ -> /both/index.html
+ // ie can only access /both.html by exact match
+ {
+ title: "/both.html -> 200",
+ files: ["/both.html", "/both/index.html"],
+ requestPath: "/both.html",
+ matchedFile: "/both.html",
+ finalPath: "/both.html",
+ },
+ {
+ title: "/both/ -> 200 (with /both/index.html)",
+ files: ["/both.html", "/both/index.html"],
+ requestPath: "/both/",
+ matchedFile: "/both/index.html",
+ finalPath: "/both/",
+ },
+ {
+ title: "/both/index -> /both/ 307 (with /both/index.html)",
+ files: ["/both.html", "/both/index.html"],
+ requestPath: "/both/index",
+ matchedFile: "/both/index.html",
+ finalPath: "/both/",
+ },
+ {
+ title: "/both/index.html -> /both/ 307 (with /both/index.html)",
+ files: ["/both.html", "/both/index.html"],
+ requestPath: "/both/index.html",
+ matchedFile: "/both/index.html",
+ finalPath: "/both/",
+ },
+ // always ends in a trailing slash
+ {
+ title: "/file -> /file/ 307 (with file.html)",
+ files: ["/file.html"],
+ requestPath: "/file",
+ matchedFile: "/file.html",
+ finalPath: "/file/",
+ },
+ {
+ title: "/file.html -> /file/ 307 (with file.html)",
+ files: ["/file.html"],
+ requestPath: "/file.html",
+ matchedFile: "/file.html",
+ finalPath: "/file/",
+ },
+
+ {
+ title: "/file/ -> 200 (with file.html)",
+ files: ["/file.html"],
+ requestPath: "/file/",
+ matchedFile: "/file.html",
+ finalPath: "/file/",
+ },
+ {
+ title: "/file/index -> /file/ 307 (with file.html)",
+ files: ["/file.html"],
+ requestPath: "/file/index",
+ matchedFile: "/file.html",
+ finalPath: "/file/",
+ },
+ {
+ title: "/file/index.html -> /file/ 307 (with file.html)",
+ files: ["/file.html"],
+ requestPath: "/file/index.html",
+ matchedFile: "/file.html",
+ finalPath: "/file/",
+ },
+ {
+ title: "/folder -> /folder/ 307 (with /folder/index.html)",
+ files: ["/folder/index.html"],
+ requestPath: "/folder",
+ matchedFile: "/folder/index.html",
+ finalPath: "/folder/",
+ },
+ {
+ title: "/folder.html -> /folder/ 307 (with /folder/index.html)",
+ files: ["/folder/index.html"],
+ requestPath: "/folder.html",
+ matchedFile: "/folder/index.html",
+ finalPath: "/folder/",
+ },
+ {
+ title: "/folder/ -> 200 (with /folder/index.html)",
+ files: ["/folder/index.html"],
+ requestPath: "/folder/",
+ matchedFile: "/folder/index.html",
+ finalPath: "/folder/",
+ },
+ {
+ title: "/folder/index -> /folder/ 307 (with /folder/index.html)",
+ files: ["/folder/index.html"],
+ requestPath: "/folder/index",
+ matchedFile: "/folder/index.html",
+ finalPath: "/folder/",
+ },
+ {
+ title: "/folder/index.html -> /folder/ 307 (with /folder/index.html)",
+ files: ["/folder/index.html"],
+ requestPath: "/folder/index.html",
+ matchedFile: "/folder/index.html",
+ finalPath: "/folder/",
+ },
+ {
+ title: "/bin -> /bin/ 307 (with /bin/index.html)",
+ files: ["/bin%2F", "/bin/index.html"],
+ requestPath: "/bin",
+ matchedFile: "/bin/index.html",
+ finalPath: "/bin/",
+ },
+ {
+ title: "/bin.html -> /bin/ 307 (with /bin/index.html)",
+ files: ["/bin%2F", "/bin/index.html"],
+ requestPath: "/bin.html",
+ matchedFile: "/bin/index.html",
+ finalPath: "/bin/",
+ },
+ {
+ title: "/bin%2F -> /bin/ 307 (with /bin%2F)",
+ files: ["/bin%2F", "/bin/index.html"],
+ requestPath: "/bin%2F",
+ matchedFile: "/bin/index.html",
+ finalPath: "/bin/",
+ },
+ // This is a bit rogue, but then so is the test case
+ {
+ title: "/bin%2F -> /bin/ 307 (with /bin/index.html)",
+ files: ["/bin%2F", "/bin/index.html"],
+ requestPath: "/bin%2F",
+ matchedFile: "/bin/index.html",
+ finalPath: "/bin/",
+ },
+ {
+ title: "/bin%252F -> 200 (with /bin%2F)",
+ files: ["/bin%2F", "/bin/index.html"],
+ requestPath: "/bin%252F",
+ matchedFile: "/bin%2F",
+ finalPath: "/bin%252F",
+ },
+ {
+ title: "/bin/ -> 200 (with /bin/index.html not /bin%2F",
+ files: ["/bin%2F", "/bin/index.html"],
+ requestPath: "/bin/",
+ matchedFile: "/bin/index.html",
+ finalPath: "/bin/",
+ },
+ {
+ title: "/bin/index -> /bin/ 307 (with /bin/index.html)",
+ files: ["/bin%2F", "/bin/index.html"],
+ requestPath: "/bin/index",
+ matchedFile: "/bin/index.html",
+ finalPath: "/bin/",
+ },
+ {
+ title: "/bin/index.html -> /bin/ 307 (with /bin/index.html)",
+ files: ["/bin%2F", "/bin/index.html"],
+ requestPath: "/bin/index.html",
+ matchedFile: "/bin/index.html",
+ finalPath: "/bin/",
+ },
+ // doesn't force a trailing slash here because it would redirect to /file-bin.html
+ {
+ title: "/file-bin -> 200",
+ files: ["/file-bin", "/file-bin.html"],
+ requestPath: "/file-bin",
+ matchedFile: "/file-bin",
+ finalPath: "/file-bin",
+ },
+ {
+ title: "/file-bin.html -> /file-bin/ 307 (with /file-bin.html)",
+ files: ["/file-bin", "/file-bin.html"],
+ requestPath: "/file-bin.html",
+ matchedFile: "/file-bin.html",
+ finalPath: "/file-bin/",
+ },
+ {
+ title: "/file-bin/ -> 200",
+ files: ["/file-bin", "/file-bin.html"],
+ requestPath: "/file-bin/",
+ matchedFile: "/file-bin.html",
+ finalPath: "/file-bin/",
+ },
+ {
+ title: "/file-bin/index -> /file-bin/ 307 (with /file-bin.html)",
+ files: ["/file-bin", "/file-bin.html"],
+ requestPath: "/file-bin/index",
+ matchedFile: "/file-bin.html",
+ finalPath: "/file-bin/",
+ },
+ {
+ title: "/file-bin/index.html -> /file-bin/ 307 (with /file-bin.html)",
+ files: ["/file-bin", "/file-bin.html"],
+ requestPath: "/file-bin/index.html",
+ matchedFile: "/file-bin.html",
+ finalPath: "/file-bin/",
+ },
+ ],
+ },
+ {
+ html_handling: "none",
+ cases: [
+ {
+ title: "/ -> 404",
+ files: ["/index.html"],
+ requestPath: "/",
+ },
+ {
+ title: "/index -> 404",
+ files: ["/index.html"],
+ requestPath: "/index",
+ },
+ {
+ title: "/index.html -> 200",
+ files: ["/index.html"],
+ requestPath: "/index.html",
+ matchedFile: "/index.html",
+ finalPath: "/index.html",
+ },
+ {
+ title: "/both -> 404",
+ files: ["/both.html", "/both/index.html"],
+ requestPath: "/both",
+ },
+ {
+ title: "/both.html -> 200",
+ files: ["/both.html", "/both/index.html"],
+ requestPath: "/both.html",
+ matchedFile: "/both.html",
+ finalPath: "/both.html",
+ },
+ {
+ title: "/both/ -> 404",
+ files: ["/both.html", "/both/index.html"],
+ requestPath: "/both/",
+ },
+ {
+ title: "/both/index.html -> 200",
+ files: ["/both.html", "/both/index.html"],
+ requestPath: "/both/index.html",
+ matchedFile: "/both/index.html",
+ finalPath: "/both/index.html",
+ },
+ {
+ title: "/file/index.html -> 404",
+ files: ["/file.html"],
+ requestPath: "/file/index.html",
+ },
+ {
+ title: "/folder.html -> 404",
+ files: ["/folder/index.html"],
+ requestPath: "/folder.html",
+ },
+ {
+ title: "/bin -> 404",
+ files: ["/bin%2F", "/bin/index.html"],
+ requestPath: "/bin",
+ },
+ {
+ title: "/bin.html -> 404",
+ files: ["/bin%2F", "/bin/index.html"],
+ requestPath: "/bin.html",
+ },
+ // encoding is independent of html handling
+ {
+ title: "/bin%2F -> 404",
+ files: ["/bin%2F", "/bin/index.html"],
+ requestPath: "/bin%2F", // -> /bin/ -> 404
+ },
+ {
+ title: "/bin%252F -> 200",
+ files: ["/bin%2F", "/bin/index.html"],
+ requestPath: "/bin%252F",
+ matchedFile: "/bin%2F",
+ finalPath: "/bin%252F",
+ },
+ {
+ title: "/bin/ -> 404",
+ files: ["/bin%2F", "/bin/index.html"],
+ requestPath: "/bin/",
+ },
+ {
+ title: "/bin/index -> 404",
+ files: ["/bin%2F", "/bin/index.html"],
+ requestPath: "/bin/index",
+ },
+ {
+ title: "/file-bin -> 200",
+ files: ["/file-bin", "/file-bin.html"],
+ requestPath: "/file-bin",
+ matchedFile: "/file-bin",
+ finalPath: "/file-bin",
+ },
+ {
+ title: "/file-bin.html -> 200",
+ files: ["/file-bin", "/file-bin.html"],
+ requestPath: "/file-bin.html",
+ matchedFile: "/file-bin.html",
+ finalPath: "/file-bin.html",
+ },
+ {
+ title: "/file-bin/ -> 404",
+ files: ["/file-bin", "/file-bin.html"],
+ requestPath: "/file-bin/",
+ },
+ {
+ title: "/file-bin/index -> 404",
+ files: ["/file-bin", "/file-bin.html"],
+ requestPath: "/file-bin/index",
+ },
+ {
+ title: "/file-bin/index.html -> 404",
+ files: ["/file-bin", "/file-bin.html"],
+ requestPath: "/file-bin/index.html",
+ },
+ ],
+ },
+];