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 {
1515 convertBodyToReadableStream ,
1616 getMiddlewareMatch ,
1717 isExternal ,
18+ normalizeLocationHeader ,
1819} from "./util.js" ;
1920
2021const middlewareManifest = MiddlewareManifest ;
@@ -94,6 +95,15 @@ export async function handleMiddleware(
9495 url,
9596 body : convertBodyToReadableStream ( internalEvent . method , internalEvent . body ) ,
9697 } 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+ }
97107 const statusCode = result . status ;
98108
99109 /* Apply override headers from middleware
Original file line number Diff line number Diff line change @@ -437,3 +437,23 @@ export async function invalidateCDNOnRequest(
437437 ] ) ;
438438 }
439439}
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 {
2828 dynamicRouteMatcher ,
2929 staticRouteMatcher ,
3030} from "./routing/routeMatcher" ;
31- import { constructNextUrl } from "./routing/util" ;
31+ import { constructNextUrl , normalizeLocationHeader } from "./routing/util" ;
3232
3333export const MIDDLEWARE_HEADER_PREFIX = "x-middleware-response-" ;
3434export const MIDDLEWARE_HEADER_PREFIX_LEN = MIDDLEWARE_HEADER_PREFIX . length ;
@@ -110,13 +110,13 @@ export default async function routingHandler(
110110 if ( redirect ) {
111111 // We need to encode the value in the Location header to make sure it is valid according to RFC
112112 // https://stackoverflow.com/a/7654605/16587222
113- redirect . headers . Location = new URL (
113+ redirect . headers . Location = normalizeLocationHeader (
114114 redirect . headers . Location as string ,
115- ) . href ;
115+ event . url ,
116+ ) ;
116117 debug ( "redirect" , redirect ) ;
117118 return redirect ;
118119 }
119-
120120 const middlewareEventOrResult = await handleMiddleware (
121121 eventOrResult ,
122122 // We need to pass the initial search without any decoding
You can’t perform that action at this time.
0 commit comments