@cloudflare/pages-shared 0.3.1 → 0.3.3
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 +34 -57
- package/asset-server/responses.ts +49 -5
- package/package.json +1 -1
- package/asset-server/url.ts +0 -8
package/asset-server/handler.ts
CHANGED
|
@@ -12,15 +12,12 @@ import {
|
|
|
12
12
|
TemporaryRedirectResponse,
|
|
13
13
|
} from "./responses";
|
|
14
14
|
import { generateRulesMatcher, replacer } from "./rulesEngine";
|
|
15
|
-
import { stringifyURLToRootRelativePathname } from "./url";
|
|
16
15
|
import type {
|
|
17
16
|
Metadata,
|
|
18
17
|
MetadataHeadersEntries,
|
|
19
18
|
MetadataHeadersRulesV2,
|
|
20
19
|
MetadataHeadersV1,
|
|
21
20
|
MetadataHeadersV2,
|
|
22
|
-
MetadataStaticRedirectEntry,
|
|
23
|
-
MetadataRedirectEntry,
|
|
24
21
|
} from "./metadata";
|
|
25
22
|
|
|
26
23
|
type BodyEncoding = "manual" | "automatic";
|
|
@@ -100,16 +97,7 @@ type FullHandlerContext<AssetEntry, ContentNegotiation, Asset> = {
|
|
|
100
97
|
waitUntil: (promise: Promise<unknown>) => void;
|
|
101
98
|
};
|
|
102
99
|
|
|
103
|
-
export type HandlerContext<
|
|
104
|
-
AssetEntry,
|
|
105
|
-
ContentNegotiation extends { encoding: string | null } = {
|
|
106
|
-
encoding: string | null;
|
|
107
|
-
},
|
|
108
|
-
Asset extends { body: ReadableStream | null; contentType: string } = {
|
|
109
|
-
body: ReadableStream | null;
|
|
110
|
-
contentType: string;
|
|
111
|
-
}
|
|
112
|
-
> =
|
|
100
|
+
export type HandlerContext<AssetEntry, ContentNegotiation, Asset> =
|
|
113
101
|
| FullHandlerContext<AssetEntry, ContentNegotiation, Asset>
|
|
114
102
|
| (Omit<
|
|
115
103
|
FullHandlerContext<AssetEntry, ContentNegotiation, Asset>,
|
|
@@ -204,7 +192,39 @@ export async function generateHandler<
|
|
|
204
192
|
staticRedirectsMatcher() || generateRedirectsMatcher()({ request })[0];
|
|
205
193
|
|
|
206
194
|
if (match) {
|
|
207
|
-
|
|
195
|
+
const { status, to } = match;
|
|
196
|
+
const destination = new URL(to, request.url);
|
|
197
|
+
const location =
|
|
198
|
+
destination.origin === new URL(request.url).origin
|
|
199
|
+
? `${destination.pathname}${destination.search || search}${
|
|
200
|
+
destination.hash
|
|
201
|
+
}`
|
|
202
|
+
: `${destination.href}${destination.search ? "" : search}${
|
|
203
|
+
destination.hash
|
|
204
|
+
}`;
|
|
205
|
+
switch (status) {
|
|
206
|
+
case 301:
|
|
207
|
+
return new MovedPermanentlyResponse(location, undefined, {
|
|
208
|
+
preventLeadingDoubleSlash: false,
|
|
209
|
+
});
|
|
210
|
+
case 303:
|
|
211
|
+
return new SeeOtherResponse(location, undefined, {
|
|
212
|
+
preventLeadingDoubleSlash: false,
|
|
213
|
+
});
|
|
214
|
+
case 307:
|
|
215
|
+
return new TemporaryRedirectResponse(location, undefined, {
|
|
216
|
+
preventLeadingDoubleSlash: false,
|
|
217
|
+
});
|
|
218
|
+
case 308:
|
|
219
|
+
return new PermanentRedirectResponse(location, undefined, {
|
|
220
|
+
preventLeadingDoubleSlash: false,
|
|
221
|
+
});
|
|
222
|
+
case 302:
|
|
223
|
+
default:
|
|
224
|
+
return new FoundResponse(location, undefined, {
|
|
225
|
+
preventLeadingDoubleSlash: false,
|
|
226
|
+
});
|
|
227
|
+
}
|
|
208
228
|
}
|
|
209
229
|
|
|
210
230
|
if (!request.method.match(/^(get|head)$/i)) {
|
|
@@ -572,49 +592,6 @@ export async function generateHandler<
|
|
|
572
592
|
}
|
|
573
593
|
}
|
|
574
594
|
|
|
575
|
-
/**
|
|
576
|
-
* Given a redirect match and the request URL, returns the response
|
|
577
|
-
* for the redirect. This function will convert the Location header
|
|
578
|
-
* to be a root-relative path URL if the request origin and destination
|
|
579
|
-
* origins are the same. This is so that if the project is served
|
|
580
|
-
* on multiple domains, the redirects won't take the client off of their current domain.
|
|
581
|
-
*/
|
|
582
|
-
export function getResponseFromMatch(
|
|
583
|
-
{
|
|
584
|
-
status,
|
|
585
|
-
to,
|
|
586
|
-
}: Pick<MetadataStaticRedirectEntry | MetadataRedirectEntry, "status" | "to">,
|
|
587
|
-
requestUrl: URL
|
|
588
|
-
) {
|
|
589
|
-
// Inherit origin from the request URL if not specified in _redirects
|
|
590
|
-
const destination = new URL(to, requestUrl);
|
|
591
|
-
// If _redirects doesn't specify a search, inherit from the request
|
|
592
|
-
destination.search = destination.search || requestUrl.search;
|
|
593
|
-
|
|
594
|
-
// If the redirect destination origin matches the incoming request origin
|
|
595
|
-
// we stringify destination to be a root-relative path, e.g.:
|
|
596
|
-
// https://example.com/foo/bar?baz=1 -> /foo/bar/?baz=1
|
|
597
|
-
// This way, the project can more easily be hosted on multiple domains
|
|
598
|
-
const location =
|
|
599
|
-
destination.origin === requestUrl.origin
|
|
600
|
-
? stringifyURLToRootRelativePathname(destination)
|
|
601
|
-
: destination.toString();
|
|
602
|
-
|
|
603
|
-
switch (status) {
|
|
604
|
-
case 301:
|
|
605
|
-
return new MovedPermanentlyResponse(location);
|
|
606
|
-
case 303:
|
|
607
|
-
return new SeeOtherResponse(location);
|
|
608
|
-
case 307:
|
|
609
|
-
return new TemporaryRedirectResponse(location);
|
|
610
|
-
case 308:
|
|
611
|
-
return new PermanentRedirectResponse(location);
|
|
612
|
-
case 302:
|
|
613
|
-
default:
|
|
614
|
-
return new FoundResponse(location);
|
|
615
|
-
}
|
|
616
|
-
}
|
|
617
|
-
|
|
618
595
|
// Parses a list such as "deflate, gzip;q=1.0, *;q=0.5" into
|
|
619
596
|
// {deflate: 1, gzip: 1, *: 0.5}
|
|
620
597
|
export function parseQualityWeightedList(list = "") {
|
|
@@ -10,6 +10,10 @@ function mergeHeaders(base: HeadersInit, extra: HeadersInit) {
|
|
|
10
10
|
});
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
+
export function stripLeadingDoubleSlashes(location: string) {
|
|
14
|
+
return location.replace(/^(\/|%2F|%2f)+(.*)/, "/$2");
|
|
15
|
+
}
|
|
16
|
+
|
|
13
17
|
export class OkResponse extends Response {
|
|
14
18
|
constructor(...[body, init]: ConstructorParameters<typeof Response>) {
|
|
15
19
|
super(body, {
|
|
@@ -23,8 +27,16 @@ export class OkResponse extends Response {
|
|
|
23
27
|
export class MovedPermanentlyResponse extends Response {
|
|
24
28
|
constructor(
|
|
25
29
|
location: string,
|
|
26
|
-
init?: ConstructorParameters<typeof Response>[1]
|
|
30
|
+
init?: ConstructorParameters<typeof Response>[1],
|
|
31
|
+
{
|
|
32
|
+
preventLeadingDoubleSlash = true,
|
|
33
|
+
}: { preventLeadingDoubleSlash: boolean } = {
|
|
34
|
+
preventLeadingDoubleSlash: true,
|
|
35
|
+
}
|
|
27
36
|
) {
|
|
37
|
+
location = preventLeadingDoubleSlash
|
|
38
|
+
? stripLeadingDoubleSlashes(location)
|
|
39
|
+
: location;
|
|
28
40
|
super(`Redirecting to ${location}`, {
|
|
29
41
|
...init,
|
|
30
42
|
status: 301,
|
|
@@ -39,8 +51,16 @@ export class MovedPermanentlyResponse extends Response {
|
|
|
39
51
|
export class FoundResponse extends Response {
|
|
40
52
|
constructor(
|
|
41
53
|
location: string,
|
|
42
|
-
init?: ConstructorParameters<typeof Response>[1]
|
|
54
|
+
init?: ConstructorParameters<typeof Response>[1],
|
|
55
|
+
{
|
|
56
|
+
preventLeadingDoubleSlash = true,
|
|
57
|
+
}: { preventLeadingDoubleSlash: boolean } = {
|
|
58
|
+
preventLeadingDoubleSlash: true,
|
|
59
|
+
}
|
|
43
60
|
) {
|
|
61
|
+
location = preventLeadingDoubleSlash
|
|
62
|
+
? stripLeadingDoubleSlashes(location)
|
|
63
|
+
: location;
|
|
44
64
|
super(`Redirecting to ${location}`, {
|
|
45
65
|
...init,
|
|
46
66
|
status: 302,
|
|
@@ -64,8 +84,16 @@ export class NotModifiedResponse extends Response {
|
|
|
64
84
|
export class PermanentRedirectResponse extends Response {
|
|
65
85
|
constructor(
|
|
66
86
|
location: string,
|
|
67
|
-
init?: ConstructorParameters<typeof Response>[1]
|
|
87
|
+
init?: ConstructorParameters<typeof Response>[1],
|
|
88
|
+
{
|
|
89
|
+
preventLeadingDoubleSlash = true,
|
|
90
|
+
}: { preventLeadingDoubleSlash: boolean } = {
|
|
91
|
+
preventLeadingDoubleSlash: true,
|
|
92
|
+
}
|
|
68
93
|
) {
|
|
94
|
+
location = preventLeadingDoubleSlash
|
|
95
|
+
? stripLeadingDoubleSlashes(location)
|
|
96
|
+
: location;
|
|
69
97
|
super(undefined, {
|
|
70
98
|
...init,
|
|
71
99
|
status: 308,
|
|
@@ -126,8 +154,16 @@ export class InternalServerErrorResponse extends Response {
|
|
|
126
154
|
export class SeeOtherResponse extends Response {
|
|
127
155
|
constructor(
|
|
128
156
|
location: string,
|
|
129
|
-
init?: ConstructorParameters<typeof Response>[1]
|
|
157
|
+
init?: ConstructorParameters<typeof Response>[1],
|
|
158
|
+
{
|
|
159
|
+
preventLeadingDoubleSlash = true,
|
|
160
|
+
}: { preventLeadingDoubleSlash: boolean } = {
|
|
161
|
+
preventLeadingDoubleSlash: true,
|
|
162
|
+
}
|
|
130
163
|
) {
|
|
164
|
+
location = preventLeadingDoubleSlash
|
|
165
|
+
? stripLeadingDoubleSlashes(location)
|
|
166
|
+
: location;
|
|
131
167
|
super(`Redirecting to ${location}`, {
|
|
132
168
|
...init,
|
|
133
169
|
status: 303,
|
|
@@ -140,8 +176,16 @@ export class SeeOtherResponse extends Response {
|
|
|
140
176
|
export class TemporaryRedirectResponse extends Response {
|
|
141
177
|
constructor(
|
|
142
178
|
location: string,
|
|
143
|
-
init?: ConstructorParameters<typeof Response>[1]
|
|
179
|
+
init?: ConstructorParameters<typeof Response>[1],
|
|
180
|
+
{
|
|
181
|
+
preventLeadingDoubleSlash = true,
|
|
182
|
+
}: { preventLeadingDoubleSlash: boolean } = {
|
|
183
|
+
preventLeadingDoubleSlash: true,
|
|
184
|
+
}
|
|
144
185
|
) {
|
|
186
|
+
location = preventLeadingDoubleSlash
|
|
187
|
+
? stripLeadingDoubleSlashes(location)
|
|
188
|
+
: location;
|
|
145
189
|
super(`Redirecting to ${location}`, {
|
|
146
190
|
...init,
|
|
147
191
|
status: 307,
|
package/package.json
CHANGED
package/asset-server/url.ts
DELETED
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Stringifies a URL instance to a root-relative path string
|
|
3
|
-
* @param url The URL to stringify
|
|
4
|
-
* @returns A root-relative path string
|
|
5
|
-
*/
|
|
6
|
-
export function stringifyURLToRootRelativePathname(url: URL): string {
|
|
7
|
-
return `${url.pathname}${url.search}${url.hash}`;
|
|
8
|
-
}
|