File tree Expand file tree Collapse file tree 3 files changed +34
-4
lines changed
packages/open-next/src/core Expand file tree Collapse file tree 3 files changed +34
-4
lines changed Original file line number Diff line number Diff line change @@ -15,6 +15,7 @@ import {
15
15
convertBodyToReadableStream ,
16
16
getMiddlewareMatch ,
17
17
isExternal ,
18
+ normalizeLocationHeader ,
18
19
} from "./util.js" ;
19
20
20
21
const middlewareManifest = MiddlewareManifest ;
@@ -94,6 +95,15 @@ export async function handleMiddleware(
94
95
url,
95
96
body : convertBodyToReadableStream ( internalEvent . method , internalEvent . body ) ,
96
97
} as unknown as Request ) ;
98
+ if ( result . headers . has ( "Location" ) ) {
99
+ result . headers . set (
100
+ "Location" ,
101
+ normalizeLocationHeader (
102
+ result . headers . get ( "Location" ) as string ,
103
+ internalEvent . url ,
104
+ ) ,
105
+ ) ;
106
+ }
97
107
const statusCode = result . status ;
98
108
99
109
/* Apply override headers from middleware
Original file line number Diff line number Diff line change @@ -437,3 +437,23 @@ export async function invalidateCDNOnRequest(
437
437
] ) ;
438
438
}
439
439
}
440
+
441
+ /**
442
+ * Normalizes the Location header to either be a relative path or a full URL.
443
+ * If the Location header is relative to the host, it will return a relative path.
444
+ * If it is an absolute URL, it will return the full URL.
445
+ * Both cases will ensure that the URL is properly encoded according to RFC
446
+ *
447
+ * @param location The Location header value
448
+ * @param url The original request URL
449
+ * @returns A normalized Location header value
450
+ */
451
+ export function normalizeLocationHeader ( location : string , url : string ) : string {
452
+ const locationUrl = new URL ( location ) ;
453
+ const host = new URL ( url ) . host ;
454
+ if ( locationUrl . host === host ) {
455
+ // If the location is relative to the host
456
+ return locationUrl . href . replace ( locationUrl . origin , "" ) ;
457
+ }
458
+ return locationUrl . href ;
459
+ }
Original file line number Diff line number Diff line change @@ -28,7 +28,7 @@ import {
28
28
dynamicRouteMatcher ,
29
29
staticRouteMatcher ,
30
30
} from "./routing/routeMatcher" ;
31
- import { constructNextUrl } from "./routing/util" ;
31
+ import { constructNextUrl , normalizeLocationHeader } from "./routing/util" ;
32
32
33
33
export const MIDDLEWARE_HEADER_PREFIX = "x-middleware-response-" ;
34
34
export const MIDDLEWARE_HEADER_PREFIX_LEN = MIDDLEWARE_HEADER_PREFIX . length ;
@@ -110,13 +110,13 @@ export default async function routingHandler(
110
110
if ( redirect ) {
111
111
// We need to encode the value in the Location header to make sure it is valid according to RFC
112
112
// https://stackoverflow.com/a/7654605/16587222
113
- redirect . headers . Location = new URL (
113
+ redirect . headers . Location = normalizeLocationHeader (
114
114
redirect . headers . Location as string ,
115
- ) . href ;
115
+ event . url ,
116
+ ) ;
116
117
debug ( "redirect" , redirect ) ;
117
118
return redirect ;
118
119
}
119
-
120
120
const middlewareEventOrResult = await handleMiddleware (
121
121
eventOrResult ,
122
122
// We need to pass the initial search without any decoding
You can’t perform that action at this time.
0 commit comments