summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAbdussamet Koçak <abdus@abdus.dev>2022-10-08 21:56:35 +0300
committerGitHub <noreply@github.com>2022-10-08 12:56:35 -0600
commit33f60da9f2d6edc5de550275f043c4262d23f6ca (patch)
treef4ae6156456d934f0857feb998746d0c40120223
parentb4e28af953aa02fb44f88c155956488b1f473348 (diff)
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
-rw-r--r--modules/caddyhttp/fileserver/browse.go7
-rw-r--r--modules/caddyhttp/fileserver/browsetplcontext.go7
2 files changed, 10 insertions, 4 deletions
diff --git a/modules/caddyhttp/fileserver/browse.go b/modules/caddyhttp/fileserver/browse.go
index 6a72e15..a8f5e8a 100644
--- a/modules/caddyhttp/fileserver/browse.go
+++ b/modules/caddyhttp/fileserver/browse.go
@@ -16,6 +16,7 @@ package fileserver
import (
"bytes"
+ "context"
_ "embed"
"encoding/json"
"fmt"
@@ -82,7 +83,7 @@ func (fsrv *FileServer) serveBrowse(root, dirPath string, w http.ResponseWriter,
repl := r.Context().Value(caddy.ReplacerCtxKey).(*caddy.Replacer)
// calling path.Clean here prevents weird breadcrumbs when URL paths are sketchy like /%2e%2e%2f
- listing, err := fsrv.loadDirectoryContents(dir.(fs.ReadDirFile), root, path.Clean(r.URL.Path), repl)
+ listing, err := fsrv.loadDirectoryContents(r.Context(), dir.(fs.ReadDirFile), root, path.Clean(r.URL.Path), repl)
switch {
case os.IsPermission(err):
return caddyhttp.Error(http.StatusForbidden, err)
@@ -136,7 +137,7 @@ func (fsrv *FileServer) serveBrowse(root, dirPath string, w http.ResponseWriter,
return nil
}
-func (fsrv *FileServer) loadDirectoryContents(dir fs.ReadDirFile, root, urlPath string, repl *caddy.Replacer) (browseTemplateContext, error) {
+func (fsrv *FileServer) loadDirectoryContents(ctx context.Context, dir fs.ReadDirFile, root, urlPath string, repl *caddy.Replacer) (browseTemplateContext, error) {
files, err := dir.ReadDir(10000) // TODO: this limit should probably be configurable
if err != nil && err != io.EOF {
return browseTemplateContext{}, err
@@ -145,7 +146,7 @@ func (fsrv *FileServer) loadDirectoryContents(dir fs.ReadDirFile, root, urlPath
// user can presumably browse "up" to parent folder if path is longer than "/"
canGoUp := len(urlPath) > 1
- return fsrv.directoryListing(files, canGoUp, root, urlPath, repl), nil
+ return fsrv.directoryListing(ctx, files, canGoUp, root, urlPath, repl), nil
}
// browseApplyQueryParams applies query parameters to the listing.
diff --git a/modules/caddyhttp/fileserver/browsetplcontext.go b/modules/caddyhttp/fileserver/browsetplcontext.go
index cd24fc2..172fa50 100644
--- a/modules/caddyhttp/fileserver/browsetplcontext.go
+++ b/modules/caddyhttp/fileserver/browsetplcontext.go
@@ -15,6 +15,7 @@
package fileserver
import (
+ "context"
"io/fs"
"net/url"
"os"
@@ -30,13 +31,17 @@ import (
"go.uber.org/zap"
)
-func (fsrv *FileServer) directoryListing(entries []fs.DirEntry, canGoUp bool, root, urlPath string, repl *caddy.Replacer) browseTemplateContext {
+func (fsrv *FileServer) directoryListing(ctx context.Context, entries []fs.DirEntry, canGoUp bool, root, urlPath string, repl *caddy.Replacer) browseTemplateContext {
filesToHide := fsrv.transformHidePaths(repl)
var dirCount, fileCount int
fileInfos := []fileInfo{}
for _, entry := range entries {
+ if err := ctx.Err(); err != nil {
+ break
+ }
+
name := entry.Name()
if fileHidden(name, filesToHide) {