summaryrefslogtreecommitdiff
path: root/modules/caddyhttp/fileserver
diff options
context:
space:
mode:
authorMatt Holt <mholt@users.noreply.github.com>2019-09-09 21:46:21 -0600
committerGitHub <noreply@github.com>2019-09-09 21:46:21 -0600
commit44b7ce98505ab8a34f6c632e661dd2cfae475a17 (patch)
tree4cd125e485047419fd19098007280b013906a0bc /modules/caddyhttp/fileserver
parent9169cd43d49236c69d5c9b7c556cb0ac0c9ce497 (diff)
parentb4f4fcd437c2f9816f9511217bde703679808679 (diff)
Merge pull request #2737 from caddyserver/fastcgi (reverse proxy!)
v2: Refactor reverse proxy and add FastCGI support
Diffstat (limited to 'modules/caddyhttp/fileserver')
-rw-r--r--modules/caddyhttp/fileserver/caddyfile.go6
-rw-r--r--modules/caddyhttp/fileserver/matcher.go50
2 files changed, 40 insertions, 16 deletions
diff --git a/modules/caddyhttp/fileserver/caddyfile.go b/modules/caddyhttp/fileserver/caddyfile.go
index 6480598..b7cb311 100644
--- a/modules/caddyhttp/fileserver/caddyfile.go
+++ b/modules/caddyhttp/fileserver/caddyfile.go
@@ -71,11 +71,6 @@ func parseCaddyfile(h httpcaddyfile.Helper) (caddyhttp.MiddlewareHandler, error)
}
}
- // if no root was configured explicitly, use site root
- if fsrv.Root == "" {
- fsrv.Root = "{http.var.root}"
- }
-
// hide the Caddyfile (and any imported Caddyfiles)
if configFiles := h.Caddyfiles(); len(configFiles) > 0 {
for _, file := range configFiles {
@@ -104,7 +99,6 @@ func parseTryFiles(h httpcaddyfile.Helper) ([]httpcaddyfile.ConfigValue, error)
matcherSet := map[string]json.RawMessage{
"file": h.JSON(MatchFile{
- Root: "{http.var.root}",
TryFiles: try,
}, nil),
}
diff --git a/modules/caddyhttp/fileserver/matcher.go b/modules/caddyhttp/fileserver/matcher.go
index b091250..fde086e 100644
--- a/modules/caddyhttp/fileserver/matcher.go
+++ b/modules/caddyhttp/fileserver/matcher.go
@@ -18,6 +18,8 @@ import (
"fmt"
"net/http"
"os"
+ "path"
+ "strings"
"time"
"github.com/caddyserver/caddy/v2"
@@ -87,8 +89,13 @@ func (m *MatchFile) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
}
}
}
+ return nil
+}
+
+// Provision sets up m's defaults.
+func (m *MatchFile) Provision(_ caddy.Context) error {
if m.Root == "" {
- m.Root = "{http.var.root}"
+ m.Root = "{http.vars.root}"
}
return nil
}
@@ -141,9 +148,9 @@ func (m MatchFile) selectFile(r *http.Request) (rel, abs string, matched bool) {
switch m.TryPolicy {
case "", tryPolicyFirstExist:
for _, f := range m.TryFiles {
- suffix := repl.ReplaceAll(f, "")
+ suffix := path.Clean(repl.ReplaceAll(f, ""))
fullpath := sanitizedPathJoin(root, suffix)
- if fileExists(fullpath) {
+ if strictFileExists(fullpath) {
return suffix, fullpath, true
}
}
@@ -153,7 +160,7 @@ func (m MatchFile) selectFile(r *http.Request) (rel, abs string, matched bool) {
var largestFilename string
var largestSuffix string
for _, f := range m.TryFiles {
- suffix := repl.ReplaceAll(f, "")
+ suffix := path.Clean(repl.ReplaceAll(f, ""))
fullpath := sanitizedPathJoin(root, suffix)
info, err := os.Stat(fullpath)
if err == nil && info.Size() > largestSize {
@@ -169,7 +176,7 @@ func (m MatchFile) selectFile(r *http.Request) (rel, abs string, matched bool) {
var smallestFilename string
var smallestSuffix string
for _, f := range m.TryFiles {
- suffix := repl.ReplaceAll(f, "")
+ suffix := path.Clean(repl.ReplaceAll(f, ""))
fullpath := sanitizedPathJoin(root, suffix)
info, err := os.Stat(fullpath)
if err == nil && (smallestSize == 0 || info.Size() < smallestSize) {
@@ -185,7 +192,7 @@ func (m MatchFile) selectFile(r *http.Request) (rel, abs string, matched bool) {
var recentFilename string
var recentSuffix string
for _, f := range m.TryFiles {
- suffix := repl.ReplaceAll(f, "")
+ suffix := path.Clean(repl.ReplaceAll(f, ""))
fullpath := sanitizedPathJoin(root, suffix)
info, err := os.Stat(fullpath)
if err == nil &&
@@ -201,10 +208,33 @@ func (m MatchFile) selectFile(r *http.Request) (rel, abs string, matched bool) {
return
}
-// fileExists returns true if file exists.
-func fileExists(file string) bool {
- _, err := os.Stat(file)
- return !os.IsNotExist(err)
+// 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 (