@marcel91200 / caddy Mirror · read-only / commits / cc23ad64
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 12, 07:00 UTC

fileserver: Add `file_limit` option for browse (to be experimental) (#6648)

* Add file_limit option for file_server browse * Move file_limit inside browse. * add file_server_file_limit caddyfile adapt test.

Atakan Yenel committed Nov 5, 2024 at 17:35 UTC cc23ad6402e6dace30b04f0d9113530a4d9541a9
4 files changed +62 -2
caddytest/integration/caddyfile_adapt/file_server_file_limit.caddyfiletest new
+36
@@ -0,0 +1,36 @@
1 +:80
2 +
3 +file_server {
4 + browse {
5 + file_limit 4000
6 + }
7 +}
8 +----------
9 +{
10 + "apps": {
11 + "http": {
12 + "servers": {
13 + "srv0": {
14 + "listen": [
15 + ":80"
16 + ],
17 + "routes": [
18 + {
19 + "handle": [
20 + {
21 + "browse": {
22 + "file_limit": 4000
23 + },
24 + "handler": "file_server",
25 + "hide": [
26 + "./Caddyfile"
27 + ]
28 + }
29 + ]
30 + }
31 + ]
32 + }
33 + }
34 + }
35 + }
36 +}
\ No newline at end of file
modules/caddyhttp/fileserver/browse.go
+12 -1
@@ -66,8 +66,15 @@ type Browse struct {
66 // - `sort size` will sort by size in ascending order
67 // The first option must be `sort_by` and the second option must be `order` (if exists).
68 SortOptions []string `json:"sort,omitempty"`
69 +
70 + // FileLimit limits the number of up to n DirEntry values in directory order.
71 + FileLimit int `json:"file_limit,omitempty"`
72 }
73
74 +const (
75 + defaultDirEntryLimit = 10000
76 +)
77 +
78 func (fsrv *FileServer) serveBrowse(fileSystem fs.FS, root, dirPath string, w http.ResponseWriter, r *http.Request, next caddyhttp.Handler) error {
79 if c := fsrv.logger.Check(zapcore.DebugLevel, "browse enabled; listing directory contents"); c != nil {
80 c.Write(zap.String("path", dirPath), zap.String("root", root))
@@ -206,7 +213,11 @@ func (fsrv *FileServer) serveBrowse(fileSystem fs.FS, root, dirPath string, w ht
213 }
214
215 func (fsrv *FileServer) loadDirectoryContents(ctx context.Context, fileSystem fs.FS, dir fs.ReadDirFile, root, urlPath string, repl *caddy.Replacer) (*browseTemplateContext, error) {
209 - files, err := dir.ReadDir(10000) // TODO: this limit should probably be configurable
216 + dirLimit := defaultDirEntryLimit
217 + if fsrv.Browse.FileLimit != 0 {
218 + dirLimit = fsrv.Browse.FileLimit
219 + }
220 + files, err := dir.ReadDir(dirLimit)
221 if err != nil && err != io.EOF {
222 return nil, err
223 }
modules/caddyhttp/fileserver/caddyfile.go
+11
@@ -16,6 +16,7 @@ package fileserver
16
17 import (
18 "path/filepath"
19 + "strconv"
20 "strings"
21
22 "github.com/caddyserver/caddy/v2"
@@ -129,6 +130,16 @@ func (fsrv *FileServer) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
130 return d.Errf("unknown sort option '%s'", dVal)
131 }
132 }
133 + case "file_limit":
134 + fileLimit := d.RemainingArgs()
135 + if len(fileLimit) != 1 {
136 + return d.Err("file_limit should have an integer value")
137 + }
138 + val, _ := strconv.Atoi(fileLimit[0])
139 + if fsrv.Browse.FileLimit != 0 {
140 + return d.Err("file_limit is already enabled")
141 + }
142 + fsrv.Browse.FileLimit = val
143 default:
144 return d.Errf("unknown subdirective '%s'", d.Val())
145 }
modules/caddyhttp/fileserver/command.go
+3 -1
@@ -66,6 +66,7 @@ respond with a file listing.`,
66 cmd.Flags().BoolP("templates", "t", false, "Enable template rendering")
67 cmd.Flags().BoolP("access-log", "a", false, "Enable the access log")
68 cmd.Flags().BoolP("debug", "v", false, "Enable verbose debug logs")
69 + cmd.Flags().IntP("file-limit", "f", defaultDirEntryLimit, "Max directories to read")
70 cmd.Flags().BoolP("no-compress", "", false, "Disable Zstandard and Gzip compression")
71 cmd.Flags().StringSliceP("precompressed", "p", []string{}, "Specify precompression file extensions. Compression preference implied from flag order.")
72 cmd.RunE = caddycmd.WrapCommandFuncForCobra(cmdFileServer)
@@ -91,6 +92,7 @@ func cmdFileServer(fs caddycmd.Flags) (int, error) {
92 browse := fs.Bool("browse")
93 templates := fs.Bool("templates")
94 accessLog := fs.Bool("access-log")
95 + fileLimit := fs.Int("file-limit")
96 debug := fs.Bool("debug")
97 revealSymlinks := fs.Bool("reveal-symlinks")
98 compress := !fs.Bool("no-compress")
@@ -151,7 +153,7 @@ func cmdFileServer(fs caddycmd.Flags) (int, error) {
153 }
154
155 if browse {
154 - handler.Browse = &Browse{RevealSymlinks: revealSymlinks}
156 + handler.Browse = &Browse{RevealSymlinks: revealSymlinks, FileLimit: fileLimit}
157 }
158
159 handlers = append(handlers, caddyconfig.JSONModuleObject(handler, "handler", "file_server", nil))