Skip to content

Commit

Permalink
WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
GregBrimble committed Oct 17, 2024
1 parent ffe8d10 commit e3041ae
Show file tree
Hide file tree
Showing 7 changed files with 61 additions and 46 deletions.
27 changes: 10 additions & 17 deletions packages/pages-shared/asset-server/handler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -180,18 +180,7 @@ export async function generateHandler<
: {};

const staticRedirectsMatcher = () => {
const withHostMatch = staticRules[`https://${host}${pathname}`];
const withoutHostMatch = staticRules[pathname];

if (withHostMatch && withoutHostMatch) {
if (withHostMatch.lineNumber < withoutHostMatch.lineNumber) {
return withHostMatch;
} else {
return withoutHostMatch;
}
}

return withHostMatch || withoutHostMatch;
return staticRules[pathname];
};

const generateRedirectsMatcher = () =>
Expand Down Expand Up @@ -385,6 +374,7 @@ export async function generateHandler<
element(element) {
for (const [attributeName] of element.attributes) {
if (
!attributeName ||
!ALLOWED_EARLY_HINT_LINK_ATTRIBUTES.includes(
attributeName.toLowerCase()
)
Expand Down Expand Up @@ -448,8 +438,8 @@ export async function generateHandler<
headerRules,
({ set = {}, unset = [] }, replacements) => {
const replacedSet: Record<string, string> = {};
Object.keys(set).forEach((key) => {
replacedSet[key] = replacer(set[key], replacements);
Object.entries(set).forEach(([key, value]) => {
replacedSet[key] = replacer(value, replacements);
});
return {
set: replacedSet,
Expand All @@ -468,11 +458,11 @@ export async function generateHandler<
unset.forEach((key) => {
headers.delete(key);
});
Object.keys(set).forEach((key) => {
Object.entries(set).forEach(([key, value]) => {
if (setMap.has(key.toLowerCase())) {
headers.append(key, set[key]);
headers.append(key, value);
} else {
headers.set(key, set[key]);
headers.set(key, value);
setMap.add(key.toLowerCase());
}
});
Expand Down Expand Up @@ -747,6 +737,9 @@ export function parseQualityWeightedList(list = "") {
.split(",")
.forEach((el) => {
const [item, weight] = el.split(";q=");
if (!item) {
return;
}
items[item] = weight ? parseFloat(weight) : 1;
});

Expand Down
8 changes: 4 additions & 4 deletions packages/pages-shared/metadata-generator/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ export const ROUTES_JSON_VERSION = 1;

export const PERMITTED_STATUS_CODES = new Set([200, 301, 302, 303, 307, 308]);
export const HEADER_SEPARATOR = ":";
export const MAX_LINE_LENGTH = 2000;
export const MAX_HEADER_RULES = 100;
export const MAX_DYNAMIC_REDIRECT_RULES = 100;
export const MAX_STATIC_REDIRECT_RULES = 2000;
export const DEFAULT_MAX_LINE_LENGTH = 2000;
export const DEFAULT_MAX_HEADER_RULES = 100;
export const DEFAULT_MAX_DYNAMIC_REDIRECT_RULES = 100;
export const DEFAULT_MAX_STATIC_REDIRECT_RULES = 2000;
export const UNSET_OPERATOR = "! ";

export const SPLAT_REGEX = /\*/g;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import type { MetadataStaticRedirects } from "../asset-server/metadata";
import type {
Logger,
Metadata,
MetadataHeaderEntry,
MetadataHeaders,
MetadataRedirects,
ParsedHeaders,
Expand Down Expand Up @@ -182,14 +183,16 @@ function constructHeaders({

const rules: MetadataHeaders = {};
for (const rule of headers.rules) {
rules[rule.path] = {};
const entry: MetadataHeaderEntry = {};

if (Object.keys(rule.headers).length) {
rules[rule.path].set = rule.headers;
entry.set = rule.headers;
}
if (rule.unsetHeaders.length) {
rules[rule.path].unset = rule.unsetHeaders;
entry.unset = rule.unsetHeaders;
}

rules[rule.path] = entry;
}

return {
Expand Down
24 changes: 15 additions & 9 deletions packages/pages-shared/metadata-generator/parseHeaders.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {
DEFAULT_MAX_HEADER_RULES,
DEFAULT_MAX_LINE_LENGTH,
HEADER_SEPARATOR,
MAX_HEADER_RULES,
MAX_LINE_LENGTH,
UNSET_OPERATOR,
} from "./constants";
import { validateUrl } from "./validateURL";
Expand All @@ -12,32 +12,38 @@ import type { HeadersRule, InvalidHeadersRule, ParsedHeaders } from "./types";
// We do the proper validation in `validateUrl` anyway :)
const LINE_IS_PROBABLY_A_PATH = new RegExp(/^([^\s]+:\/\/|^\/)/);

export function parseHeaders(input: string): ParsedHeaders {
export function parseHeaders(
input: string,
{
maxLineLength = DEFAULT_MAX_LINE_LENGTH,
maxHeaderRules = DEFAULT_MAX_HEADER_RULES,
}: { maxLineLength?: number; maxHeaderRules?: number } = {}
): ParsedHeaders {
const lines = input.split("\n");
const rules: HeadersRule[] = [];
const invalid: InvalidHeadersRule[] = [];

let rule: (HeadersRule & { line: string }) | undefined = undefined;

for (let i = 0; i < lines.length; i++) {
const line = lines[i].trim();
const line = lines[i]?.trim() || "";
if (line.length === 0 || line.startsWith("#")) {
continue;
}

if (line.length > MAX_LINE_LENGTH) {
if (line.length > maxLineLength) {
invalid.push({
message: `Ignoring line ${
i + 1
} as it exceeds the maximum allowed length of ${MAX_LINE_LENGTH}.`,
} as it exceeds the maximum allowed length of ${maxLineLength}.`,
});
continue;
}

if (LINE_IS_PROBABLY_A_PATH.test(line)) {
if (rules.length >= MAX_HEADER_RULES) {
if (rules.length >= maxHeaderRules) {
invalid.push({
message: `Maximum number of rules supported is ${MAX_HEADER_RULES}. Skipping remaining ${
message: `Maximum number of rules supported is ${maxHeaderRules}. Skipping remaining ${
lines.length - i
} lines of file.`,
});
Expand Down Expand Up @@ -103,7 +109,7 @@ export function parseHeaders(input: string): ParsedHeaders {
}

const [rawName, ...rawValue] = line.split(HEADER_SEPARATOR);
const name = rawName.trim().toLowerCase();
const name = (rawName?.trim() || "").toLowerCase();

if (name.includes(" ")) {
invalid.push({
Expand Down
33 changes: 22 additions & 11 deletions packages/pages-shared/metadata-generator/parseRedirects.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {
MAX_DYNAMIC_REDIRECT_RULES,
MAX_LINE_LENGTH,
MAX_STATIC_REDIRECT_RULES,
DEFAULT_MAX_DYNAMIC_REDIRECT_RULES,
DEFAULT_MAX_LINE_LENGTH,
DEFAULT_MAX_STATIC_REDIRECT_RULES,
PERMITTED_STATUS_CODES,
PLACEHOLDER_REGEX,
SPLAT_REGEX,
Expand All @@ -14,7 +14,18 @@ import type {
RedirectRule,
} from "./types";

export function parseRedirects(input: string): ParsedRedirects {
export function parseRedirects(
input: string,
{
maxLineLength = DEFAULT_MAX_LINE_LENGTH,
maxStaticRedirectRules = DEFAULT_MAX_STATIC_REDIRECT_RULES,
maxDynamicRedirectRules = DEFAULT_MAX_DYNAMIC_REDIRECT_RULES,
}: {
maxLineLength?: number;
maxStaticRedirectRules?: number;
maxDynamicRedirectRules?: number;
} = {}
): ParsedRedirects {
const lines = input.split("\n");
const rules: RedirectRule[] = [];
const seen_paths = new Set<string>();
Expand All @@ -25,16 +36,16 @@ export function parseRedirects(input: string): ParsedRedirects {
let canCreateStaticRule = true;

for (let i = 0; i < lines.length; i++) {
const line = lines[i].trim();
const line = lines[i]?.trim() || "";
if (line.length === 0 || line.startsWith("#")) {
continue;
}

if (line.length > MAX_LINE_LENGTH) {
if (line.length > maxLineLength) {
invalid.push({
message: `Ignoring line ${
i + 1
} as it exceeds the maximum allowed length of ${MAX_LINE_LENGTH}.`,
} as it exceeds the maximum allowed length of ${maxLineLength}.`,
});
continue;
}
Expand Down Expand Up @@ -70,19 +81,19 @@ export function parseRedirects(input: string): ParsedRedirects {
) {
staticRules += 1;

if (staticRules > MAX_STATIC_REDIRECT_RULES) {
if (staticRules > maxStaticRedirectRules) {
invalid.push({
message: `Maximum number of static rules supported is ${MAX_STATIC_REDIRECT_RULES}. Skipping line.`,
message: `Maximum number of static rules supported is ${maxStaticRedirectRules}. Skipping line.`,
});
continue;
}
} else {
dynamicRules += 1;
canCreateStaticRule = false;

if (dynamicRules > MAX_DYNAMIC_REDIRECT_RULES) {
if (dynamicRules > maxDynamicRedirectRules) {
invalid.push({
message: `Maximum number of dynamic rules supported is ${MAX_DYNAMIC_REDIRECT_RULES}. Skipping remaining ${
message: `Maximum number of dynamic rules supported is ${maxDynamicRedirectRules}. Skipping remaining ${
lines.length - i
} lines of file.`,
});
Expand Down
2 changes: 1 addition & 1 deletion packages/pages-shared/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
],
"scripts": {
"check:lint": "eslint . --max-warnings=0",
"check:type": "tsc",
"check:type": "tsc asset-server/*",
"test": "vitest run",
"test:ci": "vitest run"
},
Expand Down
4 changes: 3 additions & 1 deletion packages/pages-shared/tsconfig.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
{
"extends": "@cloudflare/workers-tsconfig/tsconfig.json",
"compilerOptions": {
"module": "CommonJS"
"module": "CommonJS",
"strict": true,
"noUncheckedIndexedAccess": true
},
"include": ["**/*.ts"],
"exclude": []
Expand Down

0 comments on commit e3041ae

Please sign in to comment.