@marcel91200 / caddy Mirror · read-only / commits / 97ace2a3
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

File matcher enforces trailing-slash convention to match dirs/files

Matthew Holt committed Sep 6, 2019 at 13:32 UTC 97ace2a39e058f435d4e6adbee874eaabb42e45d
1 file changed +27 -15
modules/caddyhttp/fileserver/matcher.go
+27 -15
@@ -19,6 +19,7 @@ import (
19 "net/http"
20 "os"
21 "path"
22 + "strings"
23 "time"
24
25 "github.com/caddyserver/caddy/v2"
@@ -149,7 +150,7 @@ func (m MatchFile) selectFile(r *http.Request) (rel, abs string, matched bool) {
150 for _, f := range m.TryFiles {
151 suffix := path.Clean(repl.ReplaceAll(f, ""))
152 fullpath := sanitizedPathJoin(root, suffix)
152 - if fileExists(fullpath) {
153 + if strictFileExists(fullpath) {
154 return suffix, fullpath, true
155 }
156 }
@@ -207,22 +208,33 @@ func (m MatchFile) selectFile(r *http.Request) (rel, abs string, matched bool) {
208 return
209 }
210
210 -// fileExists returns true if file exists,
211 -// false if it doesn't, or false if there
212 -// was any other error.
213 -func fileExists(file string) bool {
214 - _, err := os.Stat(file)
215 - if err == nil {
216 - return true
217 - } else if os.IsNotExist(err) {
218 - return false
219 - } else {
220 - // we don't know if it exists,
221 - // so assume it doesn't, since
222 - // there must have been some
223 - // other error anyway
211 +// strictFileExists returns true if file exists
212 +// and matches the convention of the given file
213 +// path. If the path ends in a forward slash,
214 +// the file must also be a directory; if it does
215 +// NOT end in a forward slash, the file must NOT
216 +// be a directory.
217 +func strictFileExists(file string) bool {
218 + stat, err := os.Stat(file)
219 + if err != nil {
220 + // in reality, this can be any error
221 + // such as permission or even obscure
222 + // ones like "is not a directory" (when
223 + // trying to stat a file within a file);
224 + // in those cases we can't be sure if
225 + // the file exists, so we just treat any
226 + // error as if it does not exist; see
227 + // https://stackoverflow.com/a/12518877/1048862
228 return false
229 }
230 + if strings.HasSuffix(file, "/") {
231 + // by convention, file paths ending
232 + // in a slash must be a directory
233 + return stat.IsDir()
234 + }
235 + // by convention, file paths NOT ending
236 + // in a slash must NOT be a directory
237 + return !stat.IsDir()
238 }
239
240 const (