@@ -34,8 +34,12 @@ import ready from "./utils/ready.js";
3434/** @typedef {import("./index.js").IncomingMessage } IncomingMessage */
3535/** @typedef {import("./index.js").ServerResponse } ServerResponse */
3636/** @typedef {import("./index.js").NormalizedHeaders } NormalizedHeaders */
37+ /** @typedef {import("./utils/getFilenameFromUrl.js").FilenameError } FilenameError */
38+ /** @typedef {import("./utils/getFilenameFromUrl.js").Extra } Extra */
3739/** @typedef {import("fs").ReadStream } ReadStream */
3840
41+ /** @typedef {{ filename: string, extra: Extra } } FilenameWithExtra */
42+
3943const BYTES_RANGE_REGEXP = / ^ * b y t e s / i;
4044const UTF8_CHARSET_MIME_TYPES = new Set ( [
4145 "application/javascript" ,
@@ -279,9 +283,11 @@ function wrapper(context) {
279283
280284 /**
281285 * @param {NodeJS.ErrnoException } error error
286+ * @param {string= } message override message
287+ * @param {number= } code override code
282288 * @returns {Promise<void> }
283289 */
284- async function errorHandler ( error ) {
290+ async function errorHandler ( error , message , code ) {
285291 switch ( error . code ) {
286292 case "ENAMETOOLONG" :
287293 case "ENOENT" :
@@ -291,7 +297,7 @@ function wrapper(context) {
291297 } ) ;
292298 break ;
293299 default :
294- await sendError ( error . message , 500 , {
300+ await sendError ( message || error . message , code || 500 , {
295301 modifyResponseData : context . options . modifyResponseData ,
296302 } ) ;
297303 break ;
@@ -532,30 +538,38 @@ function wrapper(context) {
532538 */
533539 async function processRequest ( ) {
534540 // Pipe and SendFile
535- /** @type {import("./utils/getFilenameFromUrl.js").Extra } */
536- const extra = { } ;
537- const filename = getFilenameFromUrl (
538- context ,
539- /** @type {string } */ ( getRequestURL ( req ) ) ,
540- extra ,
541- ) ;
542-
543- if ( extra . errorCode ) {
544- if ( extra . errorCode === 403 ) {
545- context . logger . error ( `Malicious path "${ filename } ".` ) ;
541+ /** @type {FilenameWithExtra | undefined } */
542+ let resolved ;
543+ const requestUrl = /** @type {string } */ ( getRequestURL ( req ) ) ;
544+
545+ try {
546+ resolved = getFilenameFromUrl ( context , requestUrl ) ;
547+ } catch ( error ) {
548+ const errorCode =
549+ typeof error === "object" &&
550+ error !== null &&
551+ typeof ( /** @type {FilenameError } */ ( error ) . statusCode ) !==
552+ "undefined"
553+ ? /** @type {FilenameError } */ ( error ) . statusCode
554+ : undefined ;
555+
556+ if ( errorCode === 403 ) {
557+ context . logger . error ( `Malicious path "${ requestUrl } ".` ) ;
546558 }
547559
548- await sendError (
549- extra . errorCode === 400 ? "Bad Request" : "Forbidden" ,
550- extra . errorCode ,
551- {
552- modifyResponseData : context . options . modifyResponseData ,
553- } ,
560+ await errorHandler (
561+ /** @type {NodeJS.ErrnoException } */ ( error ) ,
562+ errorCode === 400
563+ ? "Bad Request"
564+ : errorCode === 403
565+ ? "Forbidden"
566+ : undefined ,
567+ errorCode ,
554568 ) ;
555569 return ;
556570 }
557571
558- if ( ! filename ) {
572+ if ( ! resolved ) {
559573 await goNext ( ) ;
560574 return ;
561575 }
@@ -565,7 +579,8 @@ function wrapper(context) {
565579 return ;
566580 }
567581
568- const { size } = /** @type {import("fs").Stats } */ ( extra . stats ) ;
582+ const { extra, filename } = resolved ;
583+ const { size } = extra . stats ;
569584
570585 let len = size ;
571586 let offset = 0 ;
@@ -686,7 +701,7 @@ function wrapper(context) {
686701 try {
687702 const result = createReadStreamOrReadFileSync (
688703 filename ,
689- context . outputFileSystem ,
704+ extra . outputFileSystem ,
690705 start ,
691706 end ,
692707 ) ;
@@ -831,7 +846,7 @@ function wrapper(context) {
831846 try {
832847 ( { bufferOrStream, byteLength } = createReadStreamOrReadFileSync (
833848 filename ,
834- context . outputFileSystem ,
849+ extra . outputFileSystem ,
835850 start ,
836851 end ,
837852 ) ) ;
0 commit comments