summaryrefslogtreecommitdiff
path: root/modules/caddyhttp
diff options
context:
space:
mode:
authorMatthew Holt <mholt@users.noreply.github.com>2019-09-06 13:32:02 -0600
committerMatthew Holt <mholt@users.noreply.github.com>2019-09-06 13:32:02 -0600
commit97ace2a39e058f435d4e6adbee874eaabb42e45d (patch)
tree84dbb7284b614c4b18e22da27f664d4c9e140091 /modules/caddyhttp
parent4bd949652564eff8ccfc50f105f0d35f0af26402 (diff)
File matcher enforces trailing-slash convention to match dirs/files
Diffstat (limited to 'modules/caddyhttp')
-rw-r--r--modules/caddyhttp/fileserver/matcher.go42
1 files changed, 27 insertions, 15 deletions
diff --git a/modules/caddyhttp/fileserver/matcher.go b/modules/caddyhttp/fileserver/matcher.go
index 88ce1d0..fde086e 100644
--- a/modules/caddyhttp/fileserver/matcher.go
+++ b/modules/caddyhttp/fileserver/matcher.go
@@ -19,6 +19,7 @@ import (
"net/http"
"os"
"path"
+ "strings"
"time"
"github.com/caddyserver/caddy/v2"
@@ -149,7 +150,7 @@ func (m MatchFile) selectFile(r *http.Request) (rel, abs string, matched bool) {
for _, f := range m.TryFiles {
suffix := path.Clean(repl.ReplaceAll(f, ""))
fullpath := sanitizedPathJoin(root, suffix)
- if fileExists(fullpath) {
+ if strictFileExists(fullpath) {
return suffix, fullpath, true
}
}
@@ -207,22 +208,33 @@ func (m MatchFile) selectFile(r *http.Request) (rel, abs string, matched bool) {
return
}
-// fileExists returns true if file exists,
-// false if it doesn't, or false if there
-// was any other error.
-func fileExists(file string) bool {
- _, err := os.Stat(file)
- if err == nil {
- return true
- } else if os.IsNotExist(err) {
- return false
- } else {
- // we don't know if it exists,
- // so assume it doesn't, since
- // there must have been some
- // other error anyway
+// strictFileExists returns true if file exists
+// and matches the convention of the given file
+// path. If the path ends in a forward slash,
+// the file must also be a directory; if it does
+// NOT end in a forward slash, the file must NOT
+// be a directory.
+func strictFileExists(file string) bool {
+ stat, err := os.Stat(file)
+ if err != nil {
+ // in reality, this can be any error
+ // such as permission or even obscure
+ // ones like "is not a directory" (when
+ // trying to stat a file within a file);
+ // in those cases we can't be sure if
+ // the file exists, so we just treat any
+ // error as if it does not exist; see
+ // https://stackoverflow.com/a/12518877/1048862
return false
}
+ if strings.HasSuffix(file, "/") {
+ // by convention, file paths ending
+ // in a slash must be a directory
+ return stat.IsDir()
+ }
+ // by convention, file paths NOT ending
+ // in a slash must NOT be a directory
+ return !stat.IsDir()
}
const (