@@ -49,6 +49,11 @@ export async function staticPlugin<const Prefix extends string = '/prefix'>({
4949 if ( ! builtinModule ) return new Elysia ( )
5050
5151 const [ fs , path ] = builtinModule
52+ const isUnsafeSep = path . sep !== '/'
53+
54+ const normalizePath = isUnsafeSep
55+ ? ( p : string ) => p . replace ( / \\ / g, '/' )
56+ : ( p : string ) => p
5257
5358 const fileCache = new LRUCache < string , Response > ( )
5459
@@ -79,24 +84,25 @@ export async function staticPlugin<const Prefix extends string = '/prefix'>({
7984 if ( decodeURI )
8085 relativePath = fastDecodeURI ( relativePath ) ?? relativePath
8186
82- let pathName = path . join ( prefix , relativePath )
87+ let pathName = normalizePath ( path . join ( prefix , relativePath ) )
8388
8489 if ( isBun && absolutePath . endsWith ( '.html' ) ) {
8590 const htmlBundle = await import ( absolutePath )
86- const normalizedPath = pathName . replace ( / \\ / g, '/' )
8791
88- app . get ( normalizedPath , htmlBundle . default )
89- if ( indexHTML && normalizedPath . endsWith ( '/index.html' ) )
92+ app . get ( pathName , htmlBundle . default )
93+ if ( indexHTML && pathName . endsWith ( '/index.html' ) )
9094 app . get (
91- normalizedPath . replace ( '/index.html' , '' ) ,
95+ pathName . replace ( '/index.html' , '' ) ,
9296 htmlBundle . default
9397 )
9498
9599 continue
96100 }
97101
98102 if ( ! extension )
99- pathName = pathName . slice ( 0 , pathName . lastIndexOf ( '.' ) )
103+ pathName = normalizePath (
104+ pathName . slice ( 0 , pathName . lastIndexOf ( '.' ) )
105+ )
100106
101107 const file : Awaited < ReturnType < typeof getFile > > = isBun
102108 ? getFile ( absolutePath )
@@ -182,9 +188,8 @@ export async function staticPlugin<const Prefix extends string = '/prefix'>({
182188
183189 return response . clone ( )
184190 }
185- const normalizedPath = pathName . replace ( / \\ / g, '/' )
186191 app . get (
187- normalizedPath ,
192+ pathName ,
188193 useETag
189194 ? ( handleCache as any )
190195 : new Response (
@@ -197,9 +202,9 @@ export async function staticPlugin<const Prefix extends string = '/prefix'>({
197202 )
198203 )
199204
200- if ( indexHTML && normalizedPath . endsWith ( '/index.html' ) )
205+ if ( indexHTML && pathName . endsWith ( '/index.html' ) )
201206 app . get (
202- normalizedPath . replace ( '/index.html' , '' ) ,
207+ pathName . replace ( '/index.html' , '' ) ,
203208 useETag
204209 ? ( handleCache as any )
205210 : new Response (
@@ -227,14 +232,13 @@ export async function staticPlugin<const Prefix extends string = '/prefix'>({
227232 if ( ! absolutePath || shouldIgnore ( absolutePath ) ) continue
228233
229234 let relativePath = absolutePath . replace ( assetsDir , '' )
230- const pathName = path . join ( prefix , relativePath )
231- const normalizedPath = pathName . replace ( / \\ / g, '/' )
235+ const pathName = normalizePath ( path . join ( prefix , relativePath ) )
232236 const htmlBundle = await import ( absolutePath )
233237
234- app . get ( normalizedPath , htmlBundle . default )
235- if ( indexHTML && normalizedPath . endsWith ( '/index.html' ) )
238+ app . get ( pathName , htmlBundle . default )
239+ if ( indexHTML && pathName . endsWith ( '/index.html' ) )
236240 app . get (
237- normalizedPath . replace ( '/index.html' , '' ) ,
241+ pathName . replace ( '/index.html' , '' ) ,
238242 htmlBundle . default
239243 )
240244 }
@@ -243,11 +247,13 @@ export async function staticPlugin<const Prefix extends string = '/prefix'>({
243247 app . onError ( ( ) => { } ) . get (
244248 `${ prefix } /*` ,
245249 async ( { params, headers : requestHeaders } ) => {
246- const pathName = path . join (
247- assets ,
248- decodeURI
249- ? fastDecodeURI ( params [ '*' ] ) ?? params [ '*' ]
250- : params [ '*' ]
250+ const pathName = normalizePath (
251+ path . join (
252+ assets ,
253+ decodeURI
254+ ? ( fastDecodeURI ( params [ '*' ] ) ?? params [ '*' ] )
255+ : params [ '*' ]
256+ )
251257 )
252258
253259 if ( shouldIgnore ( pathName ) ) throw new NotFoundError ( )
0 commit comments