@cloudflare/pages-shared 0.3.4 → 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/asset-server/handler.ts
CHANGED
|
@@ -192,38 +192,47 @@ export async function generateHandler<
|
|
|
192
192
|
staticRedirectsMatcher() || generateRedirectsMatcher()({ request })[0];
|
|
193
193
|
|
|
194
194
|
if (match) {
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
195
|
+
if (match.status === 200) {
|
|
196
|
+
// A 200 redirect means that we are proxying to a different asset, for example,
|
|
197
|
+
// a request with url /users/12345 could be pointed to /users/id.html. In order to
|
|
198
|
+
// do this, we overwrite the pathname, and instead match for assets with that url,
|
|
199
|
+
// and importantly, do not use the regular redirect handler - as the url visible to
|
|
200
|
+
// the user does not change
|
|
201
|
+
pathname = new URL(match.to, request.url).pathname;
|
|
202
|
+
} else {
|
|
203
|
+
const { status, to } = match;
|
|
204
|
+
const destination = new URL(to, request.url);
|
|
205
|
+
const location =
|
|
206
|
+
destination.origin === new URL(request.url).origin
|
|
207
|
+
? `${destination.pathname}${destination.search || search}${
|
|
208
|
+
destination.hash
|
|
209
|
+
}`
|
|
210
|
+
: `${destination.href}${destination.search ? "" : search}${
|
|
211
|
+
destination.hash
|
|
212
|
+
}`;
|
|
213
|
+
switch (status) {
|
|
214
|
+
case 301:
|
|
215
|
+
return new MovedPermanentlyResponse(location, undefined, {
|
|
216
|
+
preventLeadingDoubleSlash: false,
|
|
217
|
+
});
|
|
218
|
+
case 303:
|
|
219
|
+
return new SeeOtherResponse(location, undefined, {
|
|
220
|
+
preventLeadingDoubleSlash: false,
|
|
221
|
+
});
|
|
222
|
+
case 307:
|
|
223
|
+
return new TemporaryRedirectResponse(location, undefined, {
|
|
224
|
+
preventLeadingDoubleSlash: false,
|
|
225
|
+
});
|
|
226
|
+
case 308:
|
|
227
|
+
return new PermanentRedirectResponse(location, undefined, {
|
|
228
|
+
preventLeadingDoubleSlash: false,
|
|
229
|
+
});
|
|
230
|
+
case 302:
|
|
231
|
+
default:
|
|
232
|
+
return new FoundResponse(location, undefined, {
|
|
233
|
+
preventLeadingDoubleSlash: false,
|
|
234
|
+
});
|
|
235
|
+
}
|
|
227
236
|
}
|
|
228
237
|
}
|
|
229
238
|
|
|
@@ -3,7 +3,7 @@ export const HEADERS_VERSION = 2;
|
|
|
3
3
|
export const ANALYTICS_VERSION = 1;
|
|
4
4
|
export const ROUTES_JSON_VERSION = 1;
|
|
5
5
|
|
|
6
|
-
export const PERMITTED_STATUS_CODES = new Set([301, 302, 303, 307, 308]);
|
|
6
|
+
export const PERMITTED_STATUS_CODES = new Set([200, 301, 302, 303, 307, 308]);
|
|
7
7
|
export const HEADER_SEPARATOR = ":";
|
|
8
8
|
export const MAX_LINE_LENGTH = 2000;
|
|
9
9
|
export const MAX_HEADER_RULES = 100;
|
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
SPLAT_REGEX,
|
|
7
7
|
PLACEHOLDER_REGEX,
|
|
8
8
|
} from "./constants";
|
|
9
|
-
import { validateUrl } from "./validateURL";
|
|
9
|
+
import { validateUrl, urlHasHost } from "./validateURL";
|
|
10
10
|
import type {
|
|
11
11
|
InvalidRedirectRule,
|
|
12
12
|
ParsedRedirects,
|
|
@@ -104,7 +104,20 @@ export function parseRedirects(input: string): ParsedRedirects {
|
|
|
104
104
|
invalid.push({
|
|
105
105
|
line,
|
|
106
106
|
lineNumber: i + 1,
|
|
107
|
-
message: `Valid status codes are 301, 302 (default), 303, 307, or 308. Got ${str_status}.`,
|
|
107
|
+
message: `Valid status codes are 200, 301, 302 (default), 303, 307, or 308. Got ${str_status}.`,
|
|
108
|
+
});
|
|
109
|
+
continue;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// We want to always block the `/* /index.html` redirect - this will cause TOO_MANY_REDIRECTS errors as
|
|
113
|
+
// the asset server will redirect it back to `/`, removing the `/index.html`. This is the case for regular
|
|
114
|
+
// redirects, as well as proxied (200) rewrites. We only want to run this on relative urls
|
|
115
|
+
if (/\/\*?$/.test(from) && /\/index(.html)?$/.test(to) && !urlHasHost(to)) {
|
|
116
|
+
invalid.push({
|
|
117
|
+
line,
|
|
118
|
+
lineNumber: i + 1,
|
|
119
|
+
message:
|
|
120
|
+
"Infinite loop detected in this rule and has been ignored. This will cause a redirect to strip `.html` or `/index` and end up triggering this rule again. Please fix or remove this rule to silence this warning.",
|
|
108
121
|
});
|
|
109
122
|
continue;
|
|
110
123
|
}
|
|
@@ -119,6 +132,17 @@ export function parseRedirects(input: string): ParsedRedirects {
|
|
|
119
132
|
}
|
|
120
133
|
seen_paths.add(from);
|
|
121
134
|
|
|
135
|
+
if (status === 200) {
|
|
136
|
+
if (urlHasHost(to)) {
|
|
137
|
+
invalid.push({
|
|
138
|
+
line,
|
|
139
|
+
lineNumber: i + 1,
|
|
140
|
+
message: `Proxy (200) redirects can only point to relative paths. Got ${to}`,
|
|
141
|
+
});
|
|
142
|
+
continue;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
122
146
|
rules.push({ from, to, status, lineNumber: i + 1 });
|
|
123
147
|
}
|
|
124
148
|
|
|
@@ -55,3 +55,8 @@ export const validateUrl = (
|
|
|
55
55
|
: 'URLs should either be relative (e.g. begin with a forward-slash), or use HTTPS (e.g. begin with "https://").',
|
|
56
56
|
];
|
|
57
57
|
};
|
|
58
|
+
|
|
59
|
+
export function urlHasHost(token: string): boolean {
|
|
60
|
+
const host = URL_REGEX.exec(token);
|
|
61
|
+
return Boolean(host && host.groups && host.groups.host);
|
|
62
|
+
}
|