aboutsummaryrefslogtreecommitdiffhomepage
path: root/modules/caddyhttp
diff options
context:
space:
mode:
Diffstat (limited to 'modules/caddyhttp')
-rw-r--r--modules/caddyhttp/fileserver/caddyfile.go2
-rw-r--r--modules/caddyhttp/fileserver/matcher.go39
-rw-r--r--modules/caddyhttp/replacer.go11
-rw-r--r--modules/caddyhttp/reverseproxy/fastcgi/caddyfile.go10
4 files changed, 48 insertions, 14 deletions
diff --git a/modules/caddyhttp/fileserver/caddyfile.go b/modules/caddyhttp/fileserver/caddyfile.go
index dbe2b2e56..86c26ea35 100644
--- a/modules/caddyhttp/fileserver/caddyfile.go
+++ b/modules/caddyhttp/fileserver/caddyfile.go
@@ -274,7 +274,7 @@ func parseTryFiles(h httpcaddyfile.Helper) ([]httpcaddyfile.ConfigValue, error)
tryPolicy = h.Val()
switch tryPolicy {
- case tryPolicyFirstExist, tryPolicyLargestSize, tryPolicySmallestSize, tryPolicyMostRecentlyMod:
+ case tryPolicyFirstExist, tryPolicyFirstExistFallback, tryPolicyLargestSize, tryPolicySmallestSize, tryPolicyMostRecentlyMod:
default:
return nil, h.Errf("unrecognized try policy: %s", tryPolicy)
}
diff --git a/modules/caddyhttp/fileserver/matcher.go b/modules/caddyhttp/fileserver/matcher.go
index c42907491..2bc665d4f 100644
--- a/modules/caddyhttp/fileserver/matcher.go
+++ b/modules/caddyhttp/fileserver/matcher.go
@@ -90,6 +90,7 @@ type MatchFile struct {
// How to choose a file in TryFiles. Can be:
//
// - first_exist
+ // - first_exist_fallback
// - smallest_size
// - largest_size
// - most_recently_modified
@@ -296,6 +297,7 @@ func (m MatchFile) Validate() error {
switch m.TryPolicy {
case "",
tryPolicyFirstExist,
+ tryPolicyFirstExistFallback,
tryPolicyLargestSize,
tryPolicySmallestSize,
tryPolicyMostRecentlyMod:
@@ -415,13 +417,13 @@ func (m MatchFile) selectFile(r *http.Request) (bool, error) {
}
// setPlaceholders creates the placeholders for the matched file
- setPlaceholders := func(candidate matchCandidate, info fs.FileInfo) {
+ setPlaceholders := func(candidate matchCandidate, isDir bool) {
repl.Set("http.matchers.file.relative", filepath.ToSlash(candidate.relative))
repl.Set("http.matchers.file.absolute", filepath.ToSlash(candidate.fullpath))
repl.Set("http.matchers.file.remainder", filepath.ToSlash(candidate.splitRemainder))
fileType := "file"
- if info.IsDir() {
+ if isDir {
fileType = "directory"
}
repl.Set("http.matchers.file.type", fileType)
@@ -429,8 +431,13 @@ func (m MatchFile) selectFile(r *http.Request) (bool, error) {
// match file according to the configured policy
switch m.TryPolicy {
- case "", tryPolicyFirstExist:
- for _, pattern := range m.TryFiles {
+ case "", tryPolicyFirstExist, tryPolicyFirstExistFallback:
+ maxI := -1
+ if m.TryPolicy == tryPolicyFirstExistFallback {
+ maxI = len(m.TryFiles) - 1
+ }
+
+ for i, pattern := range m.TryFiles {
// If the pattern is a status code, emit an error,
// which short-circuits the middleware pipeline and
// writes an HTTP error response.
@@ -440,8 +447,15 @@ func (m MatchFile) selectFile(r *http.Request) (bool, error) {
candidates := makeCandidates(pattern)
for _, c := range candidates {
+ // Skip the IO if using fallback policy and it's the latest item
+ if i == maxI {
+ setPlaceholders(c, false)
+
+ return true, nil
+ }
+
if info, exists := m.strictFileExists(fileSystem, c.fullpath); exists {
- setPlaceholders(c, info)
+ setPlaceholders(c, info.IsDir())
return true, nil
}
}
@@ -465,7 +479,7 @@ func (m MatchFile) selectFile(r *http.Request) (bool, error) {
if largestInfo == nil {
return false, nil
}
- setPlaceholders(largest, largestInfo)
+ setPlaceholders(largest, largestInfo.IsDir())
return true, nil
case tryPolicySmallestSize:
@@ -486,7 +500,7 @@ func (m MatchFile) selectFile(r *http.Request) (bool, error) {
if smallestInfo == nil {
return false, nil
}
- setPlaceholders(smallest, smallestInfo)
+ setPlaceholders(smallest, smallestInfo.IsDir())
return true, nil
case tryPolicyMostRecentlyMod:
@@ -506,7 +520,7 @@ func (m MatchFile) selectFile(r *http.Request) (bool, error) {
if recentInfo == nil {
return false, nil
}
- setPlaceholders(recent, recentInfo)
+ setPlaceholders(recent, recentInfo.IsDir())
return true, nil
}
@@ -708,10 +722,11 @@ var globSafeRepl = strings.NewReplacer(
)
const (
- tryPolicyFirstExist = "first_exist"
- tryPolicyLargestSize = "largest_size"
- tryPolicySmallestSize = "smallest_size"
- tryPolicyMostRecentlyMod = "most_recently_modified"
+ tryPolicyFirstExist = "first_exist"
+ tryPolicyFirstExistFallback = "first_exist_fallback"
+ tryPolicyLargestSize = "largest_size"
+ tryPolicySmallestSize = "smallest_size"
+ tryPolicyMostRecentlyMod = "most_recently_modified"
)
// Interface guards
diff --git a/modules/caddyhttp/replacer.go b/modules/caddyhttp/replacer.go
index 2c0f32357..776aa6294 100644
--- a/modules/caddyhttp/replacer.go
+++ b/modules/caddyhttp/replacer.go
@@ -186,6 +186,11 @@ func addHTTPVarsToReplacer(repl *caddy.Replacer, req *http.Request, w http.Respo
return path.Ext(req.URL.Path), true
case "http.request.uri.query":
return req.URL.RawQuery, true
+ case "http.request.uri.prefixed_query":
+ if req.URL.RawQuery == "" {
+ return "", true
+ }
+ return "?" + req.URL.RawQuery, true
case "http.request.duration":
start := GetVar(req.Context(), "start_time").(time.Time)
return time.Since(start), true
@@ -239,6 +244,12 @@ func addHTTPVarsToReplacer(repl *caddy.Replacer, req *http.Request, w http.Respo
case "http.request.orig_uri.query":
or, _ := req.Context().Value(OriginalRequestCtxKey).(http.Request)
return or.URL.RawQuery, true
+ case "http.request.orig_uri.prefixed_query":
+ or, _ := req.Context().Value(OriginalRequestCtxKey).(http.Request)
+ if or.URL.RawQuery == "" {
+ return "", true
+ }
+ return "?" + or.URL.RawQuery, true
}
// remote IP range/prefix (e.g. keep top 24 bits of 1.2.3.4 => "1.2.3.0/24")
diff --git a/modules/caddyhttp/reverseproxy/fastcgi/caddyfile.go b/modules/caddyhttp/reverseproxy/fastcgi/caddyfile.go
index 5dd19d210..6fe7df3fd 100644
--- a/modules/caddyhttp/reverseproxy/fastcgi/caddyfile.go
+++ b/modules/caddyhttp/reverseproxy/fastcgi/caddyfile.go
@@ -18,6 +18,7 @@ import (
"encoding/json"
"net/http"
"strconv"
+ "strings"
"github.com/caddyserver/caddy/v2"
"github.com/caddyserver/caddy/v2/caddyconfig"
@@ -312,12 +313,18 @@ func parsePHPFastCGI(h httpcaddyfile.Helper) ([]httpcaddyfile.ConfigValue, error
if indexFile != "off" {
dirRedir := false
dirIndex := "{http.request.uri.path}/" + indexFile
+ tryPolicy := "first_exist_fallback"
// if tryFiles wasn't overridden, use a reasonable default
if len(tryFiles) == 0 {
tryFiles = []string{"{http.request.uri.path}", dirIndex, indexFile}
dirRedir = true
} else {
+ if !strings.HasSuffix(tryFiles[len(tryFiles)-1], ".php") {
+ // use first_exist strategy if the last file is not a PHP file
+ tryPolicy = ""
+ }
+
for _, tf := range tryFiles {
if tf == dirIndex {
dirRedir = true
@@ -343,7 +350,7 @@ func parsePHPFastCGI(h httpcaddyfile.Helper) ([]httpcaddyfile.ConfigValue, error
}
redirHandler := caddyhttp.StaticResponse{
StatusCode: caddyhttp.WeakString(strconv.Itoa(http.StatusPermanentRedirect)),
- Headers: http.Header{"Location": []string{"{http.request.orig_uri.path}/"}},
+ Headers: http.Header{"Location": []string{"{http.request.orig_uri.path}/{http.request.orig_uri.prefixed_query}"}},
}
redirRoute := caddyhttp.Route{
MatcherSetsRaw: []caddy.ModuleMap{redirMatcherSet},
@@ -357,6 +364,7 @@ func parsePHPFastCGI(h httpcaddyfile.Helper) ([]httpcaddyfile.ConfigValue, error
rewriteMatcherSet := caddy.ModuleMap{
"file": h.JSON(fileserver.MatchFile{
TryFiles: tryFiles,
+ TryPolicy: tryPolicy,
SplitPath: extensions,
}),
}