@@ -118,12 +118,13 @@ const directoryListHTMLTemplate = `
118118 </header>
119119 <ul>
120120 {{ range .Files }}
121+ {{ $href := .Name }}{{ if ne $.Name "/" }}{{ $href = print $.Name "/" .Name }}{{ end }}
121122 <li>
122123 {{ if .Dir }}
123124 {{ $name := print .Name "/" }}
124- <a class="dir" href="{{ $name }}">{{ $name }}</a>
125+ <a class="dir" href="{{ $href }}">{{ $name }}</a>
125126 {{ else }}
126- <a class="file" href="{{ .Name }}">{{ .Name }}</a>
127+ <a class="file" href="{{ $href }}">{{ .Name }}</a>
127128 <span>{{ .Size }}</span>
128129 {{ end }}
129130 </li>
@@ -196,14 +197,15 @@ func (config StaticConfig) ToMiddleware() (echo.MiddlewareFunc, error) {
196197 // 3. The "/" prefix forces absolute path interpretation, removing ".." components
197198 // 4. Backslashes are treated as literal characters (not path separators), preventing traversal
198199 // See static_windows.go for Go 1.20+ filepath.Clean compatibility notes
199- name := path .Join (config .Root , path .Clean ("/" + p )) // "/"+ for security
200+ requestedPath := path .Clean ("/" + p ) // "/"+ for security
201+ filePath := path .Join (config .Root , requestedPath )
200202
201203 if config .IgnoreBase {
202204 routePath := path .Base (strings .TrimRight (c .Path (), "/*" ))
203205 baseURLPath := path .Base (p )
204206 if baseURLPath == routePath {
205- i := strings .LastIndex (name , routePath )
206- name = name [:i ] + strings .Replace (name [i :], routePath , "" , 1 )
207+ i := strings .LastIndex (filePath , routePath )
208+ filePath = filePath [:i ] + strings .Replace (filePath [i :], routePath , "" , 1 )
207209 }
208210 }
209211
@@ -212,7 +214,7 @@ func (config StaticConfig) ToMiddleware() (echo.MiddlewareFunc, error) {
212214 currentFS = c .Echo ().Filesystem
213215 }
214216
215- file , err := currentFS .Open (name )
217+ file , err := currentFS .Open (filePath )
216218 if err != nil {
217219 if ! isIgnorableOpenFileError (err ) {
218220 return err
@@ -243,10 +245,10 @@ func (config StaticConfig) ToMiddleware() (echo.MiddlewareFunc, error) {
243245 }
244246
245247 if info .IsDir () {
246- index , err := currentFS .Open (path .Join (name , config .Index ))
248+ index , err := currentFS .Open (path .Join (filePath , config .Index ))
247249 if err != nil {
248250 if config .Browse {
249- return listDir (dirListTemplate , name , currentFS , c .Response ())
251+ return listDir (dirListTemplate , requestedPath , filePath , currentFS , c .Response ())
250252 }
251253
252254 return next (c )
@@ -276,34 +278,36 @@ func serveFile(c *echo.Context, file fs.File, info os.FileInfo) error {
276278 return nil
277279}
278280
279- func listDir (t * template.Template , name string , filesystem fs.FS , res http.ResponseWriter ) error {
281+ func listDir (t * template.Template , requestedPath string , pathInFs string , filesystem fs.FS , res http.ResponseWriter ) error {
282+ files , err := fs .ReadDir (filesystem , pathInFs )
283+ if err != nil {
284+ return fmt .Errorf ("static middleware failed to read directory for listing: %w" , err )
285+ }
286+
280287 // Create directory index
281288 res .Header ().Set (echo .HeaderContentType , echo .MIMETextHTMLCharsetUTF8 )
282289 data := struct {
283290 Name string
284291 Files []any
285292 }{
286- Name : name ,
293+ Name : requestedPath ,
287294 }
288- err := fs .WalkDir (filesystem , "." , func (path string , d fs.DirEntry , err error ) error {
289- if err != nil {
290- return err
291- }
292295
293- info , infoErr := d .Info ()
294- if infoErr != nil {
295- return fmt .Errorf ("static middleware list dir error when getting file info: %w" , infoErr )
296+ for _ , f := range files {
297+ var size int64
298+ if ! f .IsDir () {
299+ info , err := f .Info ()
300+ if err != nil {
301+ return fmt .Errorf ("static middleware failed to get file info for listing: %w" , err )
302+ }
303+ size = info .Size ()
296304 }
305+
297306 data .Files = append (data .Files , struct {
298307 Name string
299308 Dir bool
300309 Size string
301- }{d .Name (), d .IsDir (), format (info .Size ())})
302-
303- return nil
304- })
305- if err != nil {
306- return err
310+ }{f .Name (), f .IsDir (), format (size )})
307311 }
308312
309313 return t .Execute (res , data )
0 commit comments