From 94d41a9d86d6ca2d2d001183a62d762ee045094f Mon Sep 17 00:00:00 2001 From: esell Date: Fri, 3 Mar 2023 14:45:17 -0700 Subject: fileserver: Remove trailing slash on fs filenames (#5417) --- modules/caddyhttp/fileserver/staticfiles.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'modules/caddyhttp/fileserver/staticfiles.go') diff --git a/modules/caddyhttp/fileserver/staticfiles.go b/modules/caddyhttp/fileserver/staticfiles.go index c0fde66..0459b3a 100644 --- a/modules/caddyhttp/fileserver/staticfiles.go +++ b/modules/caddyhttp/fileserver/staticfiles.go @@ -250,7 +250,8 @@ func (fsrv *FileServer) ServeHTTP(w http.ResponseWriter, r *http.Request, next c root := repl.ReplaceAll(fsrv.Root, ".") - filename := caddyhttp.SanitizedPathJoin(root, r.URL.Path) + // remove any trailing `/` as it breaks fs.ValidPath() in the stdlib + filename := strings.TrimSuffix(caddyhttp.SanitizedPathJoin(root, r.URL.Path), "/") fsrv.logger.Debug("sanitized path join", zap.String("site_root", root), -- cgit v1.2.3 From 1c9ea0113d007d57bb8f793ebe7a64a3dcad7bc7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?K=C3=A9vin=20Dunglas?= Date: Thu, 27 Apr 2023 01:44:01 +0200 Subject: caddyhttp: Impl `ResponseWriter.Unwrap()`, prep for Go 1.20's `ResponseController` (#5509) * feat: add support for ResponseWriter.Unwrap() * cherry-pick Francis' code --- modules/caddyhttp/fileserver/staticfiles.go | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'modules/caddyhttp/fileserver/staticfiles.go') diff --git a/modules/caddyhttp/fileserver/staticfiles.go b/modules/caddyhttp/fileserver/staticfiles.go index 0459b3a..2b5cc3d 100644 --- a/modules/caddyhttp/fileserver/staticfiles.go +++ b/modules/caddyhttp/fileserver/staticfiles.go @@ -636,6 +636,12 @@ func (wr statusOverrideResponseWriter) WriteHeader(int) { wr.ResponseWriter.WriteHeader(wr.code) } +// Unwrap returns the underlying ResponseWriter, necessary for +// http.ResponseController to work correctly. +func (wr statusOverrideResponseWriter) Unwrap() http.ResponseWriter { + return wr.ResponseWriter +} + // osFS is a simple fs.FS implementation that uses the local // file system. (We do not use os.DirFS because we do our own // rooting or path prefixing without being constrained to a single -- cgit v1.2.3 From 2615c9c52417d6ac01a56841b4684400b33f7db1 Mon Sep 17 00:00:00 2001 From: Charles Duffy Date: Sat, 20 May 2023 18:21:43 -0500 Subject: fileserver: Only set Etag if not already set (fix #5546) (#5547) --- modules/caddyhttp/fileserver/staticfiles.go | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) (limited to 'modules/caddyhttp/fileserver/staticfiles.go') diff --git a/modules/caddyhttp/fileserver/staticfiles.go b/modules/caddyhttp/fileserver/staticfiles.go index 2b5cc3d..feef66d 100644 --- a/modules/caddyhttp/fileserver/staticfiles.go +++ b/modules/caddyhttp/fileserver/staticfiles.go @@ -356,7 +356,9 @@ func (fsrv *FileServer) ServeHTTP(w http.ResponseWriter, r *http.Request, next c } var file fs.File - var etag string + + // etag is usually unset, but if the user knows what they're doing, let them override it + etag := w.Header().Get("Etag") // check for precompressed files for _, ae := range encode.AcceptedEncodings(r, fsrv.PrecompressedOrder) { @@ -388,7 +390,9 @@ func (fsrv *FileServer) ServeHTTP(w http.ResponseWriter, r *http.Request, next c // don't assign info = compressedInfo because sidecars are kind // of transparent; however we do need to set the Etag: // https://caddy.community/t/gzipped-sidecar-file-wrong-same-etag/16793 - etag = calculateEtag(compressedInfo) + if etag == "" { + etag = calculateEtag(compressedInfo) + } break } @@ -408,7 +412,9 @@ func (fsrv *FileServer) ServeHTTP(w http.ResponseWriter, r *http.Request, next c } defer file.Close() - etag = calculateEtag(info) + if etag == "" { + etag = calculateEtag(info) + } } // at this point, we're serving a file; Go std lib supports only @@ -421,7 +427,9 @@ func (fsrv *FileServer) ServeHTTP(w http.ResponseWriter, r *http.Request, next c // set the Etag - note that a conditional If-None-Match request is handled // by http.ServeContent below, which checks against this Etag value - w.Header().Set("Etag", etag) + if etag != "" { + w.Header().Set("Etag", etag) + } if w.Header().Get("Content-Type") == "" { mtyp := mime.TypeByExtension(filepath.Ext(filename)) -- cgit v1.2.3 From 5bd9c49042112183f0902a7ce6252aebf58e1ac9 Mon Sep 17 00:00:00 2001 From: Matt Holt Date: Mon, 22 May 2023 14:17:15 -0600 Subject: fileserver: Don't set Etag if mtime is 0 or 1 (close #5548) (#5550) --- modules/caddyhttp/fileserver/staticfiles.go | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'modules/caddyhttp/fileserver/staticfiles.go') diff --git a/modules/caddyhttp/fileserver/staticfiles.go b/modules/caddyhttp/fileserver/staticfiles.go index feef66d..f335d31 100644 --- a/modules/caddyhttp/fileserver/staticfiles.go +++ b/modules/caddyhttp/fileserver/staticfiles.go @@ -616,7 +616,11 @@ func (fsrv *FileServer) notFound(w http.ResponseWriter, r *http.Request, next ca // Prefix the etag with "W/" to convert it into a weak etag. // See: https://tools.ietf.org/html/rfc7232#section-2.3 func calculateEtag(d os.FileInfo) string { - t := strconv.FormatInt(d.ModTime().Unix(), 36) + mtime := d.ModTime().Unix() + if mtime == 0 || mtime == 1 { + return "" // not useful anyway; see issue #5548 + } + t := strconv.FormatInt(mtime, 36) s := strconv.FormatInt(d.Size(), 36) return `"` + t + s + `"` } -- cgit v1.2.3 From f45a6de20dd19e82e58c85b37e03957b2203b544 Mon Sep 17 00:00:00 2001 From: Marten Seemann Date: Fri, 21 Jul 2023 21:00:48 -0700 Subject: go.mod: Update quic-go to v0.37.0, bump to Go 1.20 minimum (#5644) * update quic-go to v0.37.0 * Bump to Go 1.20 * Bump golangci-lint version, yml syntax consistency * Use skip-pkg-cache workaround * Workaround needed for both? * Seeding weakrand is no longer necessary --------- Co-authored-by: Matt Holt Co-authored-by: Francis Lavoie --- modules/caddyhttp/fileserver/staticfiles.go | 3 --- 1 file changed, 3 deletions(-) (limited to 'modules/caddyhttp/fileserver/staticfiles.go') diff --git a/modules/caddyhttp/fileserver/staticfiles.go b/modules/caddyhttp/fileserver/staticfiles.go index f335d31..3261093 100644 --- a/modules/caddyhttp/fileserver/staticfiles.go +++ b/modules/caddyhttp/fileserver/staticfiles.go @@ -29,7 +29,6 @@ import ( "runtime" "strconv" "strings" - "time" "github.com/caddyserver/caddy/v2" "github.com/caddyserver/caddy/v2/modules/caddyhttp" @@ -38,8 +37,6 @@ import ( ) func init() { - weakrand.Seed(time.Now().UnixNano()) - caddy.RegisterModule(FileServer{}) } -- cgit v1.2.3 From a8492c064df48bb1b2830fb82cf740cfeba4b2b2 Mon Sep 17 00:00:00 2001 From: Francis Lavoie Date: Wed, 9 Aug 2023 13:12:09 -0400 Subject: fileserver: Don't repeat error for invalid method inside error context (#5705) --- modules/caddyhttp/fileserver/staticfiles.go | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'modules/caddyhttp/fileserver/staticfiles.go') diff --git a/modules/caddyhttp/fileserver/staticfiles.go b/modules/caddyhttp/fileserver/staticfiles.go index 3261093..133578c 100644 --- a/modules/caddyhttp/fileserver/staticfiles.go +++ b/modules/caddyhttp/fileserver/staticfiles.go @@ -418,8 +418,13 @@ func (fsrv *FileServer) ServeHTTP(w http.ResponseWriter, r *http.Request, next c // GET and HEAD, which is sensible for a static file server - reject // any other methods (see issue #5166) if r.Method != http.MethodGet && r.Method != http.MethodHead { - w.Header().Add("Allow", "GET, HEAD") - return caddyhttp.Error(http.StatusMethodNotAllowed, nil) + // if we're in an error context, then it doesn't make sense + // to repeat the error; just continue because we're probably + // trying to write an error page response (see issue #5703) + if _, ok := r.Context().Value(caddyhttp.ErrorCtxKey).(error); !ok { + w.Header().Add("Allow", "GET, HEAD") + return caddyhttp.Error(http.StatusMethodNotAllowed, nil) + } } // set the Etag - note that a conditional If-None-Match request is handled -- cgit v1.2.3 From d6f86cccf5fa5b4eb30141da390cf2439746c5da Mon Sep 17 00:00:00 2001 From: Jacob Gadikian Date: Mon, 14 Aug 2023 23:41:15 +0800 Subject: ci: use gci linter (#5708) * use gofmput to format code * use gci to format imports * reconfigure gci * linter autofixes * rearrange imports a little * export GOOS=windows golangci-lint run ./... --fix --- modules/caddyhttp/fileserver/staticfiles.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'modules/caddyhttp/fileserver/staticfiles.go') diff --git a/modules/caddyhttp/fileserver/staticfiles.go b/modules/caddyhttp/fileserver/staticfiles.go index 133578c..4fe28d3 100644 --- a/modules/caddyhttp/fileserver/staticfiles.go +++ b/modules/caddyhttp/fileserver/staticfiles.go @@ -30,10 +30,11 @@ import ( "strconv" "strings" + "go.uber.org/zap" + "github.com/caddyserver/caddy/v2" "github.com/caddyserver/caddy/v2/modules/caddyhttp" "github.com/caddyserver/caddy/v2/modules/caddyhttp/encode" - "go.uber.org/zap" ) func init() { -- cgit v1.2.3 From 0a6d3333b2c92553e66c93c14d3258a790aac639 Mon Sep 17 00:00:00 2001 From: Mohammed Al Sahaf Date: Fri, 18 Aug 2023 21:04:08 +0200 Subject: fileserver: docs: clarify the ability to produce JSON array with `browse` (#5751) --- modules/caddyhttp/fileserver/staticfiles.go | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'modules/caddyhttp/fileserver/staticfiles.go') diff --git a/modules/caddyhttp/fileserver/staticfiles.go b/modules/caddyhttp/fileserver/staticfiles.go index 4fe28d3..0ed558e 100644 --- a/modules/caddyhttp/fileserver/staticfiles.go +++ b/modules/caddyhttp/fileserver/staticfiles.go @@ -60,7 +60,23 @@ func init() { // requested directory does not have an index file, Caddy writes a // 404 response. Alternatively, file browsing can be enabled with // the "browse" parameter which shows a list of files when directories -// are requested if no index file is present. +// are requested if no index file is present. If "browse" is enabled, +// Caddy may serve a JSON array of the dirctory listing when the `Accept` +// header mentions `application/json` with the following structure: +// +// [{ +// "name": "", +// "size": 0, +// "url": "", +// "mod_time": "", +// "mode": 0, +// "is_dir": false, +// "is_symlink": false +// }] +// +// with the `url` being relative to the request path and `mod_time` in the RFC 3339 format +// with sub-second precision. For any other value for the `Accept` header, the +// respective browse template is executed with `Content-Type: text/html`. // // By default, this handler will canonicalize URIs so that requests to // directories end with a slash, but requests to regular files do not. -- cgit v1.2.3