fileserver: browse: Configurable default sort (#6502)

* fileserver: add `sort` options

* fix: test

* fileserver: check options in `Provison`

* fileserver: more obvious err alerts in sort options

* fileserver: move `sort` to `browse`

---------

Co-authored-by: Matt Holt <mholt@users.noreply.github.com>
This commit is contained in:
lollipopkit🏳️‍⚧️ 2024-08-30 23:01:37 +08:00 committed by GitHub
parent ffd28be90a
commit 5c47c2f147
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 46 additions and 41 deletions

View file

@ -1,7 +1,9 @@
:80 :80
file_server browse { file_server {
browse {
sort size desc sort size desc
}
} }
---------- ----------
{ {
@ -16,15 +18,16 @@ file_server browse {
{ {
"handle": [ "handle": [
{ {
"browse": {}, "browse": {
"handler": "file_server",
"hide": [
"./Caddyfile"
],
"sort": [ "sort": [
"size", "size",
"desc" "desc"
] ]
},
"handler": "file_server",
"hide": [
"./Caddyfile"
]
} }
] ]
} }

View file

@ -52,8 +52,19 @@ var BrowseTemplate string
type Browse struct { type Browse struct {
// Filename of the template to use instead of the embedded browse template. // Filename of the template to use instead of the embedded browse template.
TemplateFile string `json:"template_file,omitempty"` TemplateFile string `json:"template_file,omitempty"`
// Determines whether or not targets of symlinks should be revealed. // Determines whether or not targets of symlinks should be revealed.
RevealSymlinks bool `json:"reveal_symlinks,omitempty"` RevealSymlinks bool `json:"reveal_symlinks,omitempty"`
// Override the default sort.
// It includes the following options:
// - sort_by: name(default), namedirfirst, size, time
// - order: asc(default), desc
// eg.:
// - `sort time desc` will sort by time in descending order
// - `sort size` will sort by size in ascending order
// The first option must be `sort_by` and the second option must be `order` (if exists).
SortOptions []string `json:"sort,omitempty"`
} }
func (fsrv *FileServer) serveBrowse(fileSystem fs.FS, root, dirPath string, w http.ResponseWriter, r *http.Request, next caddyhttp.Handler) error { func (fsrv *FileServer) serveBrowse(fileSystem fs.FS, root, dirPath string, w http.ResponseWriter, r *http.Request, next caddyhttp.Handler) error {
@ -210,7 +221,7 @@ func (fsrv *FileServer) browseApplyQueryParams(w http.ResponseWriter, r *http.Re
// The configs in Caddyfile have lower priority than Query params, // The configs in Caddyfile have lower priority than Query params,
// so put it at first. // so put it at first.
for idx, item := range fsrv.SortOptions { for idx, item := range fsrv.Browse.SortOptions {
// Only `sort` & `order`, 2 params are allowed // Only `sort` & `order`, 2 params are allowed
if idx >= 2 { if idx >= 2 {
break break

View file

@ -119,6 +119,16 @@ func (fsrv *FileServer) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
return d.Err("Symlinks path reveal is already enabled") return d.Err("Symlinks path reveal is already enabled")
} }
fsrv.Browse.RevealSymlinks = true fsrv.Browse.RevealSymlinks = true
case "sort":
for d.NextArg() {
dVal := d.Val()
switch dVal {
case sortByName, sortByNameDirFirst, sortBySize, sortByTime, sortOrderAsc, sortOrderDesc:
fsrv.Browse.SortOptions = append(fsrv.Browse.SortOptions, dVal)
default:
return d.Errf("unknown sort option '%s'", dVal)
}
}
default: default:
return d.Errf("unknown subdirective '%s'", d.Val()) return d.Errf("unknown subdirective '%s'", d.Val())
} }
@ -171,17 +181,6 @@ func (fsrv *FileServer) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
} }
fsrv.EtagFileExtensions = etagFileExtensions fsrv.EtagFileExtensions = etagFileExtensions
case "sort":
for d.NextArg() {
dVal := d.Val()
switch dVal {
case sortByName, sortBySize, sortByTime, sortOrderAsc, sortOrderDesc:
fsrv.SortOptions = append(fsrv.SortOptions, dVal)
default:
return d.Errf("unknown sort option '%s'", dVal)
}
}
default: default:
return d.Errf("unknown subdirective '%s'", d.Val()) return d.Errf("unknown subdirective '%s'", d.Val())
} }

View file

@ -153,16 +153,6 @@ type FileServer struct {
// a 404 error. By default, this is false (disabled). // a 404 error. By default, this is false (disabled).
PassThru bool `json:"pass_thru,omitempty"` PassThru bool `json:"pass_thru,omitempty"`
// Override the default sort.
// It includes the following options:
// - sort_by: name(default), namedirfirst, size, time
// - order: asc(default), desc
// eg.:
// - `sort time desc` will sort by time in descending order
// - `sort size` will sort by size in ascending order
// The first option must be `sort_by` and the second option must be `order` (if exists).
SortOptions []string `json:"sort,omitempty"`
// Selection of encoders to use to check for precompressed files. // Selection of encoders to use to check for precompressed files.
PrecompressedRaw caddy.ModuleMap `json:"precompressed,omitempty" caddy:"namespace=http.precompressed"` PrecompressedRaw caddy.ModuleMap `json:"precompressed,omitempty" caddy:"namespace=http.precompressed"`
@ -246,8 +236,9 @@ func (fsrv *FileServer) Provision(ctx caddy.Context) error {
fsrv.precompressors[ae] = p fsrv.precompressors[ae] = p
} }
if fsrv.Browse != nil {
// check sort options // check sort options
for idx, sortOption := range fsrv.SortOptions { for idx, sortOption := range fsrv.Browse.SortOptions {
switch idx { switch idx {
case 0: case 0:
if sortOption != sortByName && sortOption != sortByNameDirFirst && sortOption != sortBySize && sortOption != sortByTime { if sortOption != sortByName && sortOption != sortByNameDirFirst && sortOption != sortBySize && sortOption != sortByTime {
@ -261,6 +252,7 @@ func (fsrv *FileServer) Provision(ctx caddy.Context) error {
return fmt.Errorf("only max 2 sort options are allowed, but got %d", idx+1) return fmt.Errorf("only max 2 sort options are allowed, but got %d", idx+1)
} }
} }
}
return nil return nil
} }