Skip to content

Commit 75005e3

Browse files
authored
Support customizing metafile limits (#8643)
1 parent dfbf03f commit 75005e3

File tree

5 files changed

+136
-12
lines changed

5 files changed

+136
-12
lines changed

.changeset/early-maps-make.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@cloudflare/workers-shared": minor
3+
---
4+
5+
Support customizing the metafile limits

packages/workers-shared/utils/configuration/parseHeaders.ts

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,13 @@ import type { HeadersRule, InvalidHeadersRule, ParsedHeaders } from "./types";
1212
// We do the proper validation in `validateUrl` anyway :)
1313
const LINE_IS_PROBABLY_A_PATH = new RegExp(/^([^\s]+:\/\/|^\/)/);
1414

15-
export function parseHeaders(input: string): ParsedHeaders {
15+
export function parseHeaders(
16+
input: string,
17+
{
18+
maxRules = MAX_HEADER_RULES,
19+
maxLineLength = MAX_LINE_LENGTH,
20+
}: { maxRules?: number; maxLineLength?: number } = {}
21+
): ParsedHeaders {
1622
const lines = input.split("\n");
1723
const rules: HeadersRule[] = [];
1824
const invalid: InvalidHeadersRule[] = [];
@@ -25,19 +31,19 @@ export function parseHeaders(input: string): ParsedHeaders {
2531
continue;
2632
}
2733

28-
if (line.length > MAX_LINE_LENGTH) {
34+
if (line.length > maxLineLength) {
2935
invalid.push({
3036
message: `Ignoring line ${
3137
i + 1
32-
} as it exceeds the maximum allowed length of ${MAX_LINE_LENGTH}.`,
38+
} as it exceeds the maximum allowed length of ${maxLineLength}.`,
3339
});
3440
continue;
3541
}
3642

3743
if (LINE_IS_PROBABLY_A_PATH.test(line)) {
38-
if (rules.length >= MAX_HEADER_RULES) {
44+
if (rules.length >= maxRules) {
3945
invalid.push({
40-
message: `Maximum number of rules supported is ${MAX_HEADER_RULES}. Skipping remaining ${
46+
message: `Maximum number of rules supported is ${maxRules}. Skipping remaining ${
4147
lines.length - i
4248
} lines of file.`,
4349
});

packages/workers-shared/utils/configuration/parseRedirects.ts

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,18 @@ import type {
1414
RedirectRule,
1515
} from "./types";
1616

17-
export function parseRedirects(input: string): ParsedRedirects {
17+
export function parseRedirects(
18+
input: string,
19+
{
20+
maxStaticRules = MAX_STATIC_REDIRECT_RULES,
21+
maxDynamicRules = MAX_DYNAMIC_REDIRECT_RULES,
22+
maxLineLength = MAX_LINE_LENGTH,
23+
}: {
24+
maxStaticRules?: number;
25+
maxDynamicRules?: number;
26+
maxLineLength?: number;
27+
} = {}
28+
): ParsedRedirects {
1829
const lines = input.split("\n");
1930
const rules: RedirectRule[] = [];
2031
const seen_paths = new Set<string>();
@@ -30,11 +41,11 @@ export function parseRedirects(input: string): ParsedRedirects {
3041
continue;
3142
}
3243

33-
if (line.length > MAX_LINE_LENGTH) {
44+
if (line.length > maxLineLength) {
3445
invalid.push({
3546
message: `Ignoring line ${
3647
i + 1
37-
} as it exceeds the maximum allowed length of ${MAX_LINE_LENGTH}.`,
48+
} as it exceeds the maximum allowed length of ${maxLineLength}.`,
3849
});
3950
continue;
4051
}
@@ -70,19 +81,19 @@ export function parseRedirects(input: string): ParsedRedirects {
7081
) {
7182
staticRules += 1;
7283

73-
if (staticRules > MAX_STATIC_REDIRECT_RULES) {
84+
if (staticRules > maxStaticRules) {
7485
invalid.push({
75-
message: `Maximum number of static rules supported is ${MAX_STATIC_REDIRECT_RULES}. Skipping line.`,
86+
message: `Maximum number of static rules supported is ${maxStaticRules}. Skipping line.`,
7687
});
7788
continue;
7889
}
7990
} else {
8091
dynamicRules += 1;
8192
canCreateStaticRule = false;
8293

83-
if (dynamicRules > MAX_DYNAMIC_REDIRECT_RULES) {
94+
if (dynamicRules > maxDynamicRules) {
8495
invalid.push({
85-
message: `Maximum number of dynamic rules supported is ${MAX_DYNAMIC_REDIRECT_RULES}. Skipping remaining ${
96+
message: `Maximum number of dynamic rules supported is ${maxDynamicRules}. Skipping remaining ${
8697
lines.length - i
8798
} lines of file.`,
8899
});

packages/workers-shared/utils/tests/parseHeaders.valid.test.ts

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,3 +137,40 @@ test("parseHeaders should add unset headers", () => {
137137
invalid: [],
138138
});
139139
});
140+
141+
test("parseHeaders should support custom limits", () => {
142+
const aaa = Array(1001).fill("a").join("");
143+
const bbb = Array(1001).fill("b").join("");
144+
const huge_line = `${aaa}: ${bbb}`;
145+
let input = `
146+
# Valid entry
147+
/a
148+
Name: Value
149+
# Jumbo comment line OK, ignored as normal
150+
${Array(1001).fill("#").join("")}
151+
# Huge path names rejected
152+
/b
153+
Name: Value
154+
${huge_line}
155+
`;
156+
let result = parseHeaders(input, { maxLineLength: 3000 });
157+
expect(result).toEqual({
158+
rules: [
159+
{ path: "/a", headers: { name: "Value" }, unsetHeaders: [] },
160+
{ path: "/b", headers: { name: "Value", [aaa]: bbb }, unsetHeaders: [] },
161+
],
162+
invalid: [],
163+
});
164+
165+
input = `
166+
# COMMENTS DON'T COUNT TOWARDS TOTAL VALID RULES
167+
${Array(150)
168+
.fill(undefined)
169+
.map((_, i) => `/a/${i}\nx-index: ${i}`)
170+
.join("\n")}
171+
# BUT DO GET COUNTED AS TOTAL LINES SKIPPED
172+
`;
173+
result = parseHeaders(input, { maxRules: 200 });
174+
expect(result.rules.length).toBe(150);
175+
expect(result.invalid.length).toBe(0);
176+
});

packages/workers-shared/utils/tests/parseRedirects.valid.test.ts

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -207,3 +207,68 @@ test("parseRedirects should accept relative URLs that don't point to .html files
207207
invalid: [],
208208
});
209209
});
210+
211+
test("parseRedirects should support custom limits", () => {
212+
const aaa = Array(1001).fill("a").join("");
213+
const bbb = Array(1001).fill("b").join("");
214+
const huge_line = `/${aaa} /${bbb} 301`;
215+
let input = `
216+
# Valid entry
217+
/a /b
218+
# Jumbo comment line OK, ignored as normal
219+
${Array(1001).fill("#").join("")}
220+
# Huge path names rejected
221+
${huge_line}
222+
`;
223+
let result = parseRedirects(input, { maxLineLength: 3000 });
224+
expect(result).toEqual({
225+
rules: [
226+
{ from: "/a", status: 302, to: "/b", lineNumber: 3 },
227+
{ from: `/${aaa}`, status: 301, to: `/${bbb}`, lineNumber: 7 },
228+
],
229+
invalid: [],
230+
});
231+
232+
input = `
233+
# COMMENTS DON'T COUNT TOWARDS TOTAL VALID RULES
234+
${Array(150)
235+
.fill(undefined)
236+
.map((_, i) => `/a/${i}/* /b/${i}/:splat`)
237+
.join("\n")}
238+
# BUT DO GET COUNTED AS TOTAL LINES SKIPPED
239+
`;
240+
result = parseRedirects(input, { maxDynamicRules: 200 });
241+
expect(result.rules.length).toBe(150);
242+
expect(result.invalid.length).toBe(0);
243+
244+
input = `
245+
# COMMENTS DON'T COUNT TOWARDS TOTAL VALID RULES
246+
${Array(2050)
247+
.fill(undefined)
248+
.map((_, i) => `/a/${i} /b/${i}`)
249+
.join("\n")}
250+
# BUT DO GET COUNTED AS TOTAL LINES SKIPPED
251+
`;
252+
result = parseRedirects(input, { maxStaticRules: 3000 });
253+
expect(result.rules.length).toBe(2050);
254+
expect(result.invalid.length).toBe(0);
255+
256+
input = `
257+
# COMMENTS DON'T COUNT TOWARDS TOTAL VALID RULES
258+
${Array(2050)
259+
.fill(undefined)
260+
.map((_, i) => `/a/${i} /b/${i}`)
261+
.join("\n")}
262+
${Array(150)
263+
.fill(undefined)
264+
.map((_, i) => `/a/${i}/* /b/${i}/:splat`)
265+
.join("\n")}
266+
# BUT DO GET COUNTED AS TOTAL LINES SKIPPED
267+
`;
268+
result = parseRedirects(input, {
269+
maxDynamicRules: 200,
270+
maxStaticRules: 3000,
271+
});
272+
expect(result.rules.length).toBe(2200);
273+
expect(result.invalid.length).toBe(0);
274+
});

0 commit comments

Comments
 (0)