@marcel91200 / caddy Mirror · read-only / commits / 74f5d66c
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 14, 05:15 UTC

fileserver: Fix `file` matcher with empty `try_files` (#4147)

* fileserver: Fix `file` matcher with empty `try_files` Fixes https://github.com/caddyserver/caddy/issues/4146 If `TryFiles` is empty, we fill it with `r.URL.Path`. In this case, this is `/`. Then later, in `prepareFilePath()`, we run the replacer (which turns `{path}` into `/` at that point) but `file` remains the original value (and the placeholder is still the placeholder there). So then `strings.HasSuffix(file, "/")` will be `false` for the placeholder, but `true` for the empty `TryFiles` codepath, because `file` was `/` due to being set to the actual request value beforehand. This means that `suffix` becomes `//` in that case, so after `sanitizedPathJoin`, it becomes `./`, so `strictFileExists`'s `strings.HasSuffix(file, separator)` codepath will return true. I think we should change the `m.TryFiles == nil` codepath to `m.TryFiles = []string{"{http.request.uri.path}"}` for consistency. (And maybe consider hoisting this to `Provision` cause there's no point doing this on every request). I don't think this "optimization" of directly using `r.URL.Path` is so valuable, cause it causes this edgecase with directories. * Update modules/caddyhttp/fileserver/matcher.go Co-authored-by: Matt Holt <mholt@users.noreply.github.com> Co-authored-by: Matt Holt <mholt@users.noreply.github.com>

Francis Lavoie committed May 4, 2021 at 11:49 UTC 74f5d66c4826e177123859abae3981bd196bfdcf
1 file changed +5 -7
modules/caddyhttp/fileserver/matcher.go
+5 -7
@@ -139,6 +139,11 @@ func (m *MatchFile) Provision(_ caddy.Context) error {
139 if m.Root == "" {
140 m.Root = "{http.vars.root}"
141 }
142 + // if list of files to try was omitted entirely, assume URL path
143 + // (use placeholder instead of r.URL.Path; see issue #4146)
144 + if m.TryFiles == nil {
145 + m.TryFiles = []string{"{http.request.uri.path}"}
146 + }
147 return nil
148 }
149
@@ -174,13 +179,6 @@ func (m MatchFile) selectFile(r *http.Request) (matched bool) {
179
180 root := repl.ReplaceAll(m.Root, ".")
181
177 - // if list of files to try was omitted entirely,
178 - // assume URL path
179 - if m.TryFiles == nil {
180 - // m is not a pointer, so this is safe
181 - m.TryFiles = []string{r.URL.Path}
182 - }
183 -
182 // common preparation of the file into parts
183 prepareFilePath := func(file string) (suffix, fullpath, remainder string) {
184 suffix, remainder = m.firstSplit(path.Clean(repl.ReplaceAll(file, "")))