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
This commit is contained in:
Abdussamet Koçak 2022-10-08 21:56:35 +03:00 committed by GitHub
parent b4e28af953
commit 33f60da9f2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 10 additions and 4 deletions

View file

@ -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.

View file

@ -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) {