@@ -48,24 +48,31 @@ const geoHeaderToNextHeader = {
4848 "x-open-next-longitude" : "x-vercel-ip-longitude" ,
4949} ;
5050
51+ /**
52+ * Adds the middleware headers to an event or result.
53+ *
54+ * @param eventOrResult
55+ * @param middlewareHeaders
56+ */
5157function applyMiddlewareHeaders (
52- eventHeaders : Record < string , string | string [ ] > ,
58+ eventOrResult : InternalEvent | InternalResult ,
5359 middlewareHeaders : Record < string , string | string [ ] | undefined > ,
54- setPrefix = true ,
5560) {
56- const keyPrefix = setPrefix ? MIDDLEWARE_HEADER_PREFIX : "" ;
61+ // Use the `MIDDLEWARE_HEADER_PREFIX` prefix for events, they will be processed by the request handler later.
62+ // Results do not go through the request handler and should not be prefixed.
63+ const isResult = isInternalResult ( eventOrResult ) ;
64+ const headers = eventOrResult . headers ;
65+ const keyPrefix = isResult ? "" : MIDDLEWARE_HEADER_PREFIX ;
5766 Object . entries ( middlewareHeaders ) . forEach ( ( [ key , value ] ) => {
5867 if ( value ) {
59- eventHeaders [ keyPrefix + key ] = Array . isArray ( value )
60- ? value . join ( "," )
61- : value ;
68+ headers [ keyPrefix + key ] = Array . isArray ( value ) ? value . join ( "," ) : value ;
6269 }
6370 } ) ;
6471}
6572
6673export default async function routingHandler (
6774 event : InternalEvent ,
68- { assetResolver } : { assetResolver ?: AssetResolver } = { } ,
75+ { assetResolver } : { assetResolver ?: AssetResolver } ,
6976) : Promise < InternalResult | RoutingResult > {
7077 try {
7178 // Add Next geo headers
@@ -91,14 +98,13 @@ export default async function routingHandler(
9198
9299 const nextHeaders = getNextConfigHeaders ( event , ConfigHeaders ) ;
93100
94- const internalEventOrResult = fixDataPage ( event , BuildId ) ;
95- if ( "statusCode" in internalEventOrResult ) {
96- return internalEventOrResult ;
97- }
101+ let eventOrResult = fixDataPage ( event , BuildId ) ;
98102
99- let internalEvent : InternalEvent | InternalResult = internalEventOrResult ;
103+ if ( isInternalResult ( eventOrResult ) ) {
104+ return eventOrResult ;
105+ }
100106
101- const redirect = handleRedirects ( internalEvent , RoutesManifest . redirects ) ;
107+ const redirect = handleRedirects ( eventOrResult , RoutesManifest . redirects ) ;
102108 if ( redirect ) {
103109 // We need to encode the value in the Location header to make sure it is valid according to RFC
104110 // https://stackoverflow.com/a/7654605/16587222
@@ -110,68 +116,87 @@ export default async function routingHandler(
110116 }
111117
112118 const middlewareEventOrResult = await handleMiddleware (
113- internalEvent ,
119+ eventOrResult ,
114120 // We need to pass the initial search without any decoding
115121 // TODO: we'd need to refactor InternalEvent to include the initial querystring directly
116122 // Should be done in another PR because it is a breaking change
117123 new URL ( event . url ) . search ,
118124 ) ;
119- if ( "statusCode" in middlewareEventOrResult ) {
125+ if ( isInternalResult ( middlewareEventOrResult ) ) {
120126 return middlewareEventOrResult ;
121127 }
122128
123- const middlewareResponseHeaders = middlewareEventOrResult . responseHeaders ;
129+ const middlewareResponseHeaders = {
130+ ...middlewareEventOrResult . responseHeaders ,
131+ ...nextHeaders ,
132+ } ;
124133 let isExternalRewrite = middlewareEventOrResult . isExternalRewrite ?? false ;
125- internalEvent = middlewareEventOrResult ;
134+ eventOrResult = middlewareEventOrResult ;
126135
127136 if ( ! isExternalRewrite ) {
128137 // First rewrite to be applied
129- const beforeRewrites = handleRewrites (
130- internalEvent ,
138+ const beforeRewrite = handleRewrites (
139+ eventOrResult ,
131140 RoutesManifest . rewrites . beforeFiles ,
132141 ) ;
133- internalEvent = beforeRewrites . internalEvent ;
134- isExternalRewrite = beforeRewrites . isExternalRewrite ;
142+ eventOrResult = beforeRewrite . internalEvent ;
143+ isExternalRewrite = beforeRewrite . isExternalRewrite ;
144+ if ( ! isExternalRewrite ) {
145+ const assetResult =
146+ await assetResolver ?. getMaybeAssetResult ?.( eventOrResult ) ;
147+ if ( assetResult ) {
148+ applyMiddlewareHeaders ( assetResult , middlewareResponseHeaders ) ;
149+ return assetResult ;
150+ }
151+ }
135152 }
136- const foundStaticRoute = staticRouteMatcher ( internalEvent . rawPath ) ;
153+ const foundStaticRoute = staticRouteMatcher ( eventOrResult . rawPath ) ;
137154 const isStaticRoute = ! isExternalRewrite && foundStaticRoute . length > 0 ;
138155
139156 if ( ! ( isStaticRoute || isExternalRewrite ) ) {
140157 // Second rewrite to be applied
141- const afterRewrites = handleRewrites (
142- internalEvent ,
158+ const afterRewrite = handleRewrites (
159+ eventOrResult ,
143160 RoutesManifest . rewrites . afterFiles ,
144161 ) ;
145- internalEvent = afterRewrites . internalEvent ;
146- isExternalRewrite = afterRewrites . isExternalRewrite ;
162+ eventOrResult = afterRewrite . internalEvent ;
163+ isExternalRewrite = afterRewrite . isExternalRewrite ;
164+ if ( ! isExternalRewrite ) {
165+ const assetResult =
166+ await assetResolver ?. getMaybeAssetResult ?.( eventOrResult ) ;
167+ if ( assetResult ) {
168+ applyMiddlewareHeaders ( assetResult , middlewareResponseHeaders ) ;
169+ return assetResult ;
170+ }
171+ }
147172 }
148173
149174 let isISR = false ;
150175 // We want to run this just before the dynamic route check
151176 // We can skip it if its an external rewrite
152177 if ( ! isExternalRewrite ) {
153178 const fallbackResult = handleFallbackFalse (
154- internalEvent ,
179+ eventOrResult ,
155180 PrerenderManifest ,
156181 ) ;
157- internalEvent = fallbackResult . event ;
182+ eventOrResult = fallbackResult . event ;
158183 isISR = fallbackResult . isISR ;
159184 }
160185
161- const foundDynamicRoute = dynamicRouteMatcher ( internalEvent . rawPath ) ;
186+ const foundDynamicRoute = dynamicRouteMatcher ( eventOrResult . rawPath ) ;
162187 const isDynamicRoute = ! isExternalRewrite && foundDynamicRoute . length > 0 ;
163188
164189 if ( ! ( isDynamicRoute || isStaticRoute || isExternalRewrite ) ) {
165190 // Fallback rewrite to be applied
166191 const fallbackRewrites = handleRewrites (
167- internalEvent ,
192+ eventOrResult ,
168193 RoutesManifest . rewrites . fallback ,
169194 ) ;
170- internalEvent = fallbackRewrites . internalEvent ;
195+ eventOrResult = fallbackRewrites . internalEvent ;
171196 isExternalRewrite = fallbackRewrites . isExternalRewrite ;
172197 }
173198
174- const isNextImageRoute = internalEvent . rawPath . startsWith ( "/_next/image" ) ;
199+ const isNextImageRoute = eventOrResult . rawPath . startsWith ( "/_next/image" ) ;
175200
176201 const isRouteFoundBeforeAllRewrites =
177202 isStaticRoute || isDynamicRoute || isExternalRewrite ;
@@ -183,31 +208,23 @@ export default async function routingHandler(
183208 isRouteFoundBeforeAllRewrites ||
184209 isNextImageRoute ||
185210 // We need to check again once all rewrites have been applied
186- staticRouteMatcher ( internalEvent . rawPath ) . length > 0 ||
187- dynamicRouteMatcher ( internalEvent . rawPath ) . length > 0
211+ staticRouteMatcher ( eventOrResult . rawPath ) . length > 0 ||
212+ dynamicRouteMatcher ( eventOrResult . rawPath ) . length > 0
188213 )
189214 ) {
190- const assetEventOrResult =
191- await assetResolver ?. onRouteNotFound ( internalEvent ) ;
192-
193- if ( assetEventOrResult && "statusCode" in assetEventOrResult ) {
194- applyMiddlewareHeaders (
195- assetEventOrResult . headers ,
196- {
197- ...middlewareResponseHeaders ,
198- ...nextHeaders ,
199- } ,
200- false ,
201- ) ;
202- return assetEventOrResult ;
215+ const assetResult =
216+ await assetResolver ?. getMaybeAssetResult ?.( eventOrResult ) ;
217+ if ( assetResult ) {
218+ applyMiddlewareHeaders ( assetResult , middlewareResponseHeaders ) ;
219+ return assetResult ;
203220 }
204221
205- internalEvent = assetEventOrResult ?? {
206- ...internalEvent ,
222+ eventOrResult = {
223+ ...eventOrResult ,
207224 rawPath : "/404" ,
208- url : constructNextUrl ( internalEvent . url , "/404" ) ,
225+ url : constructNextUrl ( eventOrResult . url , "/404" ) ,
209226 headers : {
210- ...internalEvent . headers ,
227+ ...eventOrResult . headers ,
211228 "x-middleware-response-cache-control" :
212229 "private, no-cache, no-store, max-age=0, must-revalidate" ,
213230 } ,
@@ -216,28 +233,25 @@ export default async function routingHandler(
216233
217234 if (
218235 globalThis . openNextConfig . dangerous ?. enableCacheInterception &&
219- ! ( "statusCode" in internalEvent )
236+ ! isInternalResult ( eventOrResult )
220237 ) {
221238 debug ( "Cache interception enabled" ) ;
222- internalEvent = await cacheInterceptor ( internalEvent ) ;
223- if ( "statusCode" in internalEvent ) {
224- applyMiddlewareHeaders (
225- internalEvent . headers ,
226- {
227- ...middlewareResponseHeaders ,
228- ...nextHeaders ,
229- } ,
230- false ,
231- ) ;
232- return internalEvent ;
239+ eventOrResult = await cacheInterceptor ( eventOrResult ) ;
240+ if ( isInternalResult ( eventOrResult ) ) {
241+ applyMiddlewareHeaders ( eventOrResult , middlewareResponseHeaders ) ;
242+ return eventOrResult ;
233243 }
234244 }
235245
246+ const assetResult =
247+ await assetResolver ?. getMaybeAssetResult ?.( eventOrResult ) ;
248+ if ( assetResult ) {
249+ applyMiddlewareHeaders ( assetResult , middlewareResponseHeaders ) ;
250+ return assetResult ;
251+ }
252+
236253 // We apply the headers from the middleware response last
237- applyMiddlewareHeaders ( internalEvent . headers , {
238- ...middlewareResponseHeaders ,
239- ...nextHeaders ,
240- } ) ;
254+ applyMiddlewareHeaders ( eventOrResult , middlewareResponseHeaders ) ;
241255
242256 const resolvedRoutes : ResolvedRoute [ ] = [
243257 ...foundStaticRoute ,
@@ -247,14 +261,14 @@ export default async function routingHandler(
247261 debug ( "resolvedRoutes" , resolvedRoutes ) ;
248262
249263 return {
250- internalEvent,
264+ internalEvent : eventOrResult ,
251265 isExternalRewrite,
252266 origin : false ,
253267 isISR,
254268 resolvedRoutes,
255269 initialURL : event . url ,
256270 locale : NextConfig . i18n
257- ? detectLocale ( internalEvent , NextConfig . i18n )
271+ ? detectLocale ( eventOrResult , NextConfig . i18n )
258272 : undefined ,
259273 } ;
260274 } catch ( e ) {
@@ -284,3 +298,13 @@ export default async function routingHandler(
284298 } ;
285299 }
286300}
301+
302+ /**
303+ * @param eventOrResult
304+ * @returns Whether the event is an instance of `InternalResult`
305+ */
306+ function isInternalResult (
307+ eventOrResult : InternalEvent | InternalResult ,
308+ ) : eventOrResult is InternalResult {
309+ return eventOrResult != null && "statusCode" in eventOrResult ;
310+ }
0 commit comments