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, 09:30 UTC
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
lollipopkit🏳️⚧️ committed
Aug 5, 2024 at 22:27 UTC
b1986781740b2b7f546c6ce56496c5cc7145674d
5 files changed
+103
-4
caddytest/integration/caddyfile_adapt/file_server_sort.caddyfiletest
new
+36
@@ -0,0 +1,36 @@
1
+:80
2
+
3
+file_server browse {
4
+ sort size desc
5
+}
6
+----------
7
+{
8
+ "apps": {
9
+ "http": {
10
+ "servers": {
11
+ "srv0": {
12
+ "listen": [
13
+ ":80"
14
+ ],
15
+ "routes": [
16
+ {
17
+ "handle": [
18
+ {
19
+ "browse": {},
20
+ "handler": "file_server",
21
+ "hide": [
22
+ "./Caddyfile"
23
+ ],
24
+ "sort": [
25
+ "size",
26
+ "desc"
27
+ ]
28
+ }
29
+ ]
30
+ }
31
+ ]
32
+ }
33
+ }
34
+ }
35
+ }
36
+}
\ No newline at end of file
modules/caddyhttp/fileserver/browse.go
+27
-4
@@ -206,11 +206,34 @@ func (fsrv *FileServer) loadDirectoryContents(ctx context.Context, fileSystem fs
206
// browseApplyQueryParams applies query parameters to the listing.
207
// It mutates the listing and may set cookies.
208
func (fsrv *FileServer) browseApplyQueryParams(w http.ResponseWriter, r *http.Request, listing *browseTemplateContext) {
209
+ var orderParam, sortParam string
210
+
211
+ // The configs in Caddyfile have lower priority than Query params,
212
+ // so put it at first.
213
+ for idx, item := range fsrv.SortOptions {
214
+ // Only `sort` & `order`, 2 params are allowed
215
+ if idx >= 2 {
216
+ break
217
+ }
218
+ switch item {
219
+ case sortByName, sortByNameDirFirst, sortBySize, sortByTime:
220
+ sortParam = item
221
+ case sortOrderAsc, sortOrderDesc:
222
+ orderParam = item
223
+ }
224
+ }
225
+
226
layoutParam := r.URL.Query().Get("layout")
210
- sortParam := r.URL.Query().Get("sort")
211
- orderParam := r.URL.Query().Get("order")
227
limitParam := r.URL.Query().Get("limit")
228
offsetParam := r.URL.Query().Get("offset")
229
+ sortParamTmp := r.URL.Query().Get("sort")
230
+ if sortParamTmp != "" {
231
+ sortParam = sortParamTmp
232
+ }
233
+ orderParamTmp := r.URL.Query().Get("order")
234
+ if orderParamTmp != "" {
235
+ orderParam = orderParamTmp
236
+ }
237
238
switch layoutParam {
239
case "list", "grid", "":
@@ -233,11 +256,11 @@ func (fsrv *FileServer) browseApplyQueryParams(w http.ResponseWriter, r *http.Re
256
// then figure out the order
257
switch orderParam {
258
case "":
236
- orderParam = "asc"
259
+ orderParam = sortOrderAsc
260
if orderCookie, orderErr := r.Cookie("order"); orderErr == nil {
261
orderParam = orderCookie.Value
262
}
240
- case "asc", "desc":
263
+ case sortOrderAsc, sortOrderDesc:
264
http.SetCookie(w, &http.Cookie{Name: "order", Value: orderParam, Secure: r.TLS != nil})
265
}
266
modules/caddyhttp/fileserver/browsetplcontext.go
+3
@@ -373,4 +373,7 @@ const (
373
sortByNameDirFirst = "namedirfirst"
374
sortBySize = "size"
375
sortByTime = "time"
376
+
377
+ sortOrderAsc = "asc"
378
+ sortOrderDesc = "desc"
379
)
modules/caddyhttp/fileserver/caddyfile.go
+11
@@ -171,6 +171,17 @@ func (fsrv *FileServer) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
171
}
172
fsrv.EtagFileExtensions = etagFileExtensions
173
174
+ case "sort":
175
+ for d.NextArg() {
176
+ dVal := d.Val()
177
+ switch dVal {
178
+ case sortByName, sortBySize, sortByTime, sortOrderAsc, sortOrderDesc:
179
+ fsrv.SortOptions = append(fsrv.SortOptions, dVal)
180
+ default:
181
+ return d.Errf("unknown sort option '%s'", dVal)
182
+ }
183
+ }
184
+
185
default:
186
return d.Errf("unknown subdirective '%s'", d.Val())
187
}
modules/caddyhttp/fileserver/staticfiles.go
+26
@@ -153,6 +153,16 @@ type FileServer struct {
153
// a 404 error. By default, this is false (disabled).
154
PassThru bool `json:"pass_thru,omitempty"`
155
156
+ // Override the default sort.
157
+ // It includes the following options:
158
+ // - sort_by: name(default), namedirfirst, size, time
159
+ // - order: asc(default), desc
160
+ // eg.:
161
+ // - `sort time desc` will sort by time in descending order
162
+ // - `sort size` will sort by size in ascending order
163
+ // The first option must be `sort_by` and the second option must be `order` (if exists).
164
+ SortOptions []string `json:"sort,omitempty"`
165
+
166
// Selection of encoders to use to check for precompressed files.
167
PrecompressedRaw caddy.ModuleMap `json:"precompressed,omitempty" caddy:"namespace=http.precompressed"`
168
@@ -236,6 +246,22 @@ func (fsrv *FileServer) Provision(ctx caddy.Context) error {
246
fsrv.precompressors[ae] = p
247
}
248
249
+ // check sort options
250
+ for idx, sortOption := range fsrv.SortOptions {
251
+ switch idx {
252
+ case 0:
253
+ if sortOption != sortByName && sortOption != sortByNameDirFirst && sortOption != sortBySize && sortOption != sortByTime {
254
+ return fmt.Errorf("the first option must be one of the following: %s, %s, %s, %s, but got %s", sortByName, sortByNameDirFirst, sortBySize, sortByTime, sortOption)
255
+ }
256
+ case 1:
257
+ if sortOption != sortOrderAsc && sortOption != sortOrderDesc {
258
+ return fmt.Errorf("the second option must be one of the following: %s, %s, but got %s", sortOrderAsc, sortOrderDesc, sortOption)
259
+ }
260
+ default:
261
+ return fmt.Errorf("only max 2 sort options are allowed, but got %d", idx+1)
262
+ }
263
+ }
264
+
265
return nil
266
}
267