aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorlollipopkit🏳️‍⚧️ <[email protected]>2024-08-05 22:27:45 +0800
committerGitHub <[email protected]>2024-08-05 08:27:45 -0600
commitb1986781740b2b7f546c6ce56496c5cc7145674d (patch)
tree5ba69a0a8634e324bd38ca6d7f2ddee957765b05
parent840094ac65c2c27dbf0be63478d36969a57ce7e0 (diff)
downloadcaddy-b1986781740b2b7f546c6ce56496c5cc7145674d.tar.gz
caddy-b1986781740b2b7f546c6ce56496c5cc7145674d.zip
browse: Customizable default sort options (#6468)
* fileserver: add `sort` options * fix: test * fileserver: check options in `Provison` * fileserver: more obvious err alerts in sort options
-rw-r--r--caddytest/integration/caddyfile_adapt/file_server_sort.caddyfiletest36
-rw-r--r--modules/caddyhttp/fileserver/browse.go31
-rw-r--r--modules/caddyhttp/fileserver/browsetplcontext.go3
-rw-r--r--modules/caddyhttp/fileserver/caddyfile.go11
-rw-r--r--modules/caddyhttp/fileserver/staticfiles.go26
5 files changed, 103 insertions, 4 deletions
diff --git a/caddytest/integration/caddyfile_adapt/file_server_sort.caddyfiletest b/caddytest/integration/caddyfile_adapt/file_server_sort.caddyfiletest
new file mode 100644
index 000000000..62bfd0cba
--- /dev/null
+++ b/caddytest/integration/caddyfile_adapt/file_server_sort.caddyfiletest
@@ -0,0 +1,36 @@
+:80
+
+file_server browse {
+ sort size desc
+}
+----------
+{
+ "apps": {
+ "http": {
+ "servers": {
+ "srv0": {
+ "listen": [
+ ":80"
+ ],
+ "routes": [
+ {
+ "handle": [
+ {
+ "browse": {},
+ "handler": "file_server",
+ "hide": [
+ "./Caddyfile"
+ ],
+ "sort": [
+ "size",
+ "desc"
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ }
+ }
+ }
+} \ No newline at end of file
diff --git a/modules/caddyhttp/fileserver/browse.go b/modules/caddyhttp/fileserver/browse.go
index 8b2b48e77..bd02c584f 100644
--- a/modules/caddyhttp/fileserver/browse.go
+++ b/modules/caddyhttp/fileserver/browse.go
@@ -206,11 +206,34 @@ func (fsrv *FileServer) loadDirectoryContents(ctx context.Context, fileSystem fs
// browseApplyQueryParams applies query parameters to the listing.
// It mutates the listing and may set cookies.
func (fsrv *FileServer) browseApplyQueryParams(w http.ResponseWriter, r *http.Request, listing *browseTemplateContext) {
+ var orderParam, sortParam string
+
+ // The configs in Caddyfile have lower priority than Query params,
+ // so put it at first.
+ for idx, item := range fsrv.SortOptions {
+ // Only `sort` & `order`, 2 params are allowed
+ if idx >= 2 {
+ break
+ }
+ switch item {
+ case sortByName, sortByNameDirFirst, sortBySize, sortByTime:
+ sortParam = item
+ case sortOrderAsc, sortOrderDesc:
+ orderParam = item
+ }
+ }
+
layoutParam := r.URL.Query().Get("layout")
- sortParam := r.URL.Query().Get("sort")
- orderParam := r.URL.Query().Get("order")
limitParam := r.URL.Query().Get("limit")
offsetParam := r.URL.Query().Get("offset")
+ sortParamTmp := r.URL.Query().Get("sort")
+ if sortParamTmp != "" {
+ sortParam = sortParamTmp
+ }
+ orderParamTmp := r.URL.Query().Get("order")
+ if orderParamTmp != "" {
+ orderParam = orderParamTmp
+ }
switch layoutParam {
case "list", "grid", "":
@@ -233,11 +256,11 @@ func (fsrv *FileServer) browseApplyQueryParams(w http.ResponseWriter, r *http.Re
// then figure out the order
switch orderParam {
case "":
- orderParam = "asc"
+ orderParam = sortOrderAsc
if orderCookie, orderErr := r.Cookie("order"); orderErr == nil {
orderParam = orderCookie.Value
}
- case "asc", "desc":
+ case sortOrderAsc, sortOrderDesc:
http.SetCookie(w, &http.Cookie{Name: "order", Value: orderParam, Secure: r.TLS != nil})
}
diff --git a/modules/caddyhttp/fileserver/browsetplcontext.go b/modules/caddyhttp/fileserver/browsetplcontext.go
index 81e260c71..0251bc581 100644
--- a/modules/caddyhttp/fileserver/browsetplcontext.go
+++ b/modules/caddyhttp/fileserver/browsetplcontext.go
@@ -373,4 +373,7 @@ const (
sortByNameDirFirst = "namedirfirst"
sortBySize = "size"
sortByTime = "time"
+
+ sortOrderAsc = "asc"
+ sortOrderDesc = "desc"
)
diff --git a/modules/caddyhttp/fileserver/caddyfile.go b/modules/caddyhttp/fileserver/caddyfile.go
index f65695018..603a828c9 100644
--- a/modules/caddyhttp/fileserver/caddyfile.go
+++ b/modules/caddyhttp/fileserver/caddyfile.go
@@ -171,6 +171,17 @@ func (fsrv *FileServer) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
}
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:
return d.Errf("unknown subdirective '%s'", d.Val())
}
diff --git a/modules/caddyhttp/fileserver/staticfiles.go b/modules/caddyhttp/fileserver/staticfiles.go
index 3d7032804..48812cfec 100644
--- a/modules/caddyhttp/fileserver/staticfiles.go
+++ b/modules/caddyhttp/fileserver/staticfiles.go
@@ -153,6 +153,16 @@ type FileServer struct {
// a 404 error. By default, this is false (disabled).
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.
PrecompressedRaw caddy.ModuleMap `json:"precompressed,omitempty" caddy:"namespace=http.precompressed"`
@@ -236,6 +246,22 @@ func (fsrv *FileServer) Provision(ctx caddy.Context) error {
fsrv.precompressors[ae] = p
}
+ // check sort options
+ for idx, sortOption := range fsrv.SortOptions {
+ switch idx {
+ case 0:
+ if sortOption != sortByName && sortOption != sortByNameDirFirst && sortOption != sortBySize && sortOption != sortByTime {
+ return fmt.Errorf("the first option must be one of the following: %s, %s, %s, %s, but got %s", sortByName, sortByNameDirFirst, sortBySize, sortByTime, sortOption)
+ }
+ case 1:
+ if sortOption != sortOrderAsc && sortOption != sortOrderDesc {
+ return fmt.Errorf("the second option must be one of the following: %s, %s, but got %s", sortOrderAsc, sortOrderDesc, sortOption)
+ }
+ default:
+ return fmt.Errorf("only max 2 sort options are allowed, but got %d", idx+1)
+ }
+ }
+
return nil
}