@@ -178,9 +178,22 @@ export class NetlifyDev {
178178 this . #staticHandlerAdditionalDirectories = options . staticFiles ?. directories ?? [ ]
179179 }
180180
181+ /**
182+ * Runs a request through the Netlify request chain and returns a `Response`
183+ * if there's a match. We must not disturb the incoming request unless we
184+ * know we will be returning a response, so this method takes a read-only
185+ * request that is safe to access (used for matching) and a getter for the
186+ * actual request (used for handling matches).
187+ *
188+ * @param readRequest Read-only version of the request (without a body)
189+ * @param getWriteRequest Getter for the actual request (with a body)
190+ * @param destPath Destination directory for compiled files
191+ * @param options Options object
192+ * @returns
193+ */
181194 private async handleInEphemeralDirectory (
182- matchRequest : Request ,
183- getHandleRequest : ( ) => Request ,
195+ readRequest : Request ,
196+ getWriteRequest : ( ) => Request ,
184197 destPath : string ,
185198 options : HandleOptions = { } ,
186199 ) : Promise < { response : Response ; type : ResponseType } | undefined > {
@@ -190,51 +203,51 @@ export class NetlifyDev {
190203
191204 // 1. Check if the request matches an edge function. Handles edge functions
192205 // with both modes of cache (manual and off) by running them serially.
193- const edgeFunctionMatch = await this . #edgeFunctionsHandler?. match ( matchRequest )
206+ const edgeFunctionMatch = await this . #edgeFunctionsHandler?. match ( readRequest )
194207 if ( edgeFunctionMatch ) {
195208 return {
196- response : await edgeFunctionMatch . handle ( getHandleRequest ( ) ) ,
209+ response : await edgeFunctionMatch . handle ( getWriteRequest ( ) ) ,
197210 type : 'edge-function' ,
198211 }
199212 }
200213
201214 // 2. Check if the request matches a function.
202- const functionMatch = await this . #functionsHandler?. match ( matchRequest , destPath )
215+ const functionMatch = await this . #functionsHandler?. match ( readRequest , destPath )
203216 if ( functionMatch ) {
204217 // If the function prefers static files, check if there is a static match
205218 // and, if so, return that
206219 if ( functionMatch . preferStatic ) {
207- const staticMatch = await this . #staticHandler?. match ( matchRequest )
220+ const staticMatch = await this . #staticHandler?. match ( readRequest )
208221
209222 if ( staticMatch ) {
210223 const response = await staticMatch . handle ( )
211224
212- await this . #headersHandler?. apply ( matchRequest , response , options . headersCollector )
225+ await this . #headersHandler?. apply ( readRequest , response , options . headersCollector )
213226
214227 return { response, type : 'static' }
215228 }
216229 }
217230
218231 // Let the function handle the request.
219- return { response : await functionMatch . handle ( getHandleRequest ( ) ) , type : 'function' }
232+ return { response : await functionMatch . handle ( getWriteRequest ( ) ) , type : 'function' }
220233 }
221234
222235 // 3. Check if the request matches a redirect rule.
223- const redirectMatch = await this . #redirectsHandler?. match ( matchRequest )
236+ const redirectMatch = await this . #redirectsHandler?. match ( readRequest )
224237 if ( redirectMatch ) {
225238 // If the redirect rule matches a function, we'll serve it. The exception
226239 // is if the function prefers static files, which in this case means that
227240 // we'll follow the redirect rule.
228241 const functionMatch = await this . #functionsHandler?. match ( new Request ( redirectMatch . target ) , destPath )
229242 if ( functionMatch && ! functionMatch . preferStatic ) {
230243 return {
231- response : await functionMatch . handle ( getHandleRequest ( ) ) ,
244+ response : await functionMatch . handle ( getWriteRequest ( ) ) ,
232245 type : 'function' ,
233246 }
234247 }
235248
236249 const response = await this . #redirectsHandler?. handle (
237- getHandleRequest ( ) ,
250+ getWriteRequest ( ) ,
238251 redirectMatch ,
239252 async ( maybeStaticFile : Request ) => {
240253 const staticMatch = await this . #staticHandler?. match ( maybeStaticFile )
@@ -256,7 +269,7 @@ export class NetlifyDev {
256269 }
257270 }
258271
259- const { pathname } = new URL ( matchRequest . url )
272+ const { pathname } = new URL ( readRequest . url )
260273 if ( pathname . startsWith ( '/.netlify/images' ) ) {
261274 this . #logger. error (
262275 `The Netlify Image CDN is currently only supported in the Netlify CLI. Run ${ netlifyCommand ( 'npx netlify dev' ) } to get started.` ,
@@ -266,11 +279,11 @@ export class NetlifyDev {
266279 }
267280
268281 // 4. Check if the request matches a static file.
269- const staticMatch = await this . #staticHandler?. match ( matchRequest )
282+ const staticMatch = await this . #staticHandler?. match ( readRequest )
270283 if ( staticMatch ) {
271284 const response = await staticMatch . handle ( )
272285
273- await this . #headersHandler?. apply ( matchRequest , response , options . headersCollector )
286+ await this . #headersHandler?. apply ( readRequest , response , options . headersCollector )
274287
275288 return { response, type : 'static' }
276289 }
@@ -295,12 +308,21 @@ export class NetlifyDev {
295308 return config
296309 }
297310
311+ /**
312+ * Runs a `Request` through the Netlify request chain. If there is a match,
313+ * it returns the resulting `Response` object; if not, it returns `undefined`.
314+ */
298315 async handle ( request : Request , options : HandleOptions = { } ) {
299316 const result = await this . handleAndIntrospect ( request , options )
300317
301318 return result ?. response
302319 }
303320
321+ /**
322+ * Runs a `Request` through the Netlify request chain. If there is a match,
323+ * it returns an object with the resulting `Response` object and information
324+ * about the match; if not, it returns `undefined`.
325+ */
304326 async handleAndIntrospect ( request : Request , options : HandleOptions = { } ) {
305327 await fs . mkdir ( this . #functionsServePath, { recursive : true } )
306328
@@ -318,6 +340,11 @@ export class NetlifyDev {
318340 }
319341 }
320342
343+ /**
344+ * Runs a Node.js `IncomingMessage` through the Netlify request chain. If
345+ * there is a match, it returns an object with the resulting `Response`
346+ * object and information about the match; if not, it returns `undefined`.
347+ */
321348 async handleAndIntrospectNodeRequest ( request : IncomingMessage , options : HandleOptions = { } ) {
322349 await fs . mkdir ( this . #functionsServePath, { recursive : true } )
323350
0 commit comments