@marcel91200 / caddy Mirror · read-only / commits / 33f60da9
Fork 0

Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS

Mirrored from https://github.com/Slazee/caddy.git

Synced Nov 13, 09:15 UTC

fileserver: stop listing dir when request context is cancelled (#5131)

Prevents caddy from performing disk IO needlessly when the request is cancelled before the listing is finished. Closes #5129

Abdussamet Koçak committed Oct 8, 2022 at 21:56 UTC 33f60da9f2d6edc5de550275f043c4262d23f6ca
2 files changed +10 -4
modules/caddyhttp/fileserver/browse.go
+4 -3
@@ -16,6 +16,7 @@ package fileserver
16
17 import (
18 "bytes"
19 + "context"
20 _ "embed"
21 "encoding/json"
22 "fmt"
@@ -82,7 +83,7 @@ func (fsrv *FileServer) serveBrowse(root, dirPath string, w http.ResponseWriter,
83 repl := r.Context().Value(caddy.ReplacerCtxKey).(*caddy.Replacer)
84
85 // calling path.Clean here prevents weird breadcrumbs when URL paths are sketchy like /%2e%2e%2f
85 - listing, err := fsrv.loadDirectoryContents(dir.(fs.ReadDirFile), root, path.Clean(r.URL.Path), repl)
86 + listing, err := fsrv.loadDirectoryContents(r.Context(), dir.(fs.ReadDirFile), root, path.Clean(r.URL.Path), repl)
87 switch {
88 case os.IsPermission(err):
89 return caddyhttp.Error(http.StatusForbidden, err)
@@ -136,7 +137,7 @@ func (fsrv *FileServer) serveBrowse(root, dirPath string, w http.ResponseWriter,
137 return nil
138 }
139
139 -func (fsrv *FileServer) loadDirectoryContents(dir fs.ReadDirFile, root, urlPath string, repl *caddy.Replacer) (browseTemplateContext, error) {
140 +func (fsrv *FileServer) loadDirectoryContents(ctx context.Context, dir fs.ReadDirFile, root, urlPath string, repl *caddy.Replacer) (browseTemplateContext, error) {
141 files, err := dir.ReadDir(10000) // TODO: this limit should probably be configurable
142 if err != nil && err != io.EOF {
143 return browseTemplateContext{}, err
@@ -145,7 +146,7 @@ func (fsrv *FileServer) loadDirectoryContents(dir fs.ReadDirFile, root, urlPath
146 // user can presumably browse "up" to parent folder if path is longer than "/"
147 canGoUp := len(urlPath) > 1
148
148 - return fsrv.directoryListing(files, canGoUp, root, urlPath, repl), nil
149 + return fsrv.directoryListing(ctx, files, canGoUp, root, urlPath, repl), nil
150 }
151
152 // browseApplyQueryParams applies query parameters to the listing.
modules/caddyhttp/fileserver/browsetplcontext.go
+6 -1
@@ -15,6 +15,7 @@
15 package fileserver
16
17 import (
18 + "context"
19 "io/fs"
20 "net/url"
21 "os"
@@ -30,13 +31,17 @@ import (
31 "go.uber.org/zap"
32 )
33
33 -func (fsrv *FileServer) directoryListing(entries []fs.DirEntry, canGoUp bool, root, urlPath string, repl *caddy.Replacer) browseTemplateContext {
34 +func (fsrv *FileServer) directoryListing(ctx context.Context, entries []fs.DirEntry, canGoUp bool, root, urlPath string, repl *caddy.Replacer) browseTemplateContext {
35 filesToHide := fsrv.transformHidePaths(repl)
36
37 var dirCount, fileCount int
38 fileInfos := []fileInfo{}
39
40 for _, entry := range entries {
41 + if err := ctx.Err(); err != nil {
42 + break
43 + }
44 +
45 name := entry.Name()
46
47 if fileHidden(name, filesToHide) {