|
|
@ -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 ( |
|
|
|