mirror of
https://github.com/caddyserver/caddy.git
synced 2024-12-05 07:24:08 +08:00
fileserver: Add first_exist_fallback
strategy for try_files
(#6699)
Some checks are pending
Tests / test (./cmd/caddy/caddy, ~1.22.3, macos-14, 0, 1.22, mac) (push) Waiting to run
Tests / test (./cmd/caddy/caddy, ~1.22.3, ubuntu-latest, 0, 1.22, linux) (push) Waiting to run
Tests / test (./cmd/caddy/caddy, ~1.23.0, macos-14, 0, 1.23, mac) (push) Waiting to run
Tests / test (./cmd/caddy/caddy, ~1.23.0, ubuntu-latest, 0, 1.23, linux) (push) Waiting to run
Tests / test (./cmd/caddy/caddy.exe, ~1.22.3, windows-latest, True, 1.22, windows) (push) Waiting to run
Tests / test (./cmd/caddy/caddy.exe, ~1.23.0, windows-latest, True, 1.23, windows) (push) Waiting to run
Tests / test (s390x on IBM Z) (push) Waiting to run
Tests / goreleaser-check (push) Waiting to run
Cross-Build / build (~1.22.3, 1.22, aix) (push) Waiting to run
Cross-Build / build (~1.22.3, 1.22, darwin) (push) Waiting to run
Cross-Build / build (~1.22.3, 1.22, dragonfly) (push) Waiting to run
Cross-Build / build (~1.22.3, 1.22, freebsd) (push) Waiting to run
Cross-Build / build (~1.22.3, 1.22, illumos) (push) Waiting to run
Cross-Build / build (~1.22.3, 1.22, linux) (push) Waiting to run
Cross-Build / build (~1.22.3, 1.22, netbsd) (push) Waiting to run
Cross-Build / build (~1.22.3, 1.22, openbsd) (push) Waiting to run
Cross-Build / build (~1.22.3, 1.22, solaris) (push) Waiting to run
Cross-Build / build (~1.22.3, 1.22, windows) (push) Waiting to run
Cross-Build / build (~1.23.0, 1.23, aix) (push) Waiting to run
Cross-Build / build (~1.23.0, 1.23, darwin) (push) Waiting to run
Cross-Build / build (~1.23.0, 1.23, dragonfly) (push) Waiting to run
Cross-Build / build (~1.23.0, 1.23, freebsd) (push) Waiting to run
Cross-Build / build (~1.23.0, 1.23, illumos) (push) Waiting to run
Cross-Build / build (~1.23.0, 1.23, linux) (push) Waiting to run
Cross-Build / build (~1.23.0, 1.23, netbsd) (push) Waiting to run
Cross-Build / build (~1.23.0, 1.23, openbsd) (push) Waiting to run
Cross-Build / build (~1.23.0, 1.23, solaris) (push) Waiting to run
Cross-Build / build (~1.23.0, 1.23, windows) (push) Waiting to run
Lint / lint (macos-14, mac) (push) Waiting to run
Lint / lint (ubuntu-latest, linux) (push) Waiting to run
Lint / lint (windows-latest, windows) (push) Waiting to run
Lint / govulncheck (push) Waiting to run
Some checks are pending
Tests / test (./cmd/caddy/caddy, ~1.22.3, macos-14, 0, 1.22, mac) (push) Waiting to run
Tests / test (./cmd/caddy/caddy, ~1.22.3, ubuntu-latest, 0, 1.22, linux) (push) Waiting to run
Tests / test (./cmd/caddy/caddy, ~1.23.0, macos-14, 0, 1.23, mac) (push) Waiting to run
Tests / test (./cmd/caddy/caddy, ~1.23.0, ubuntu-latest, 0, 1.23, linux) (push) Waiting to run
Tests / test (./cmd/caddy/caddy.exe, ~1.22.3, windows-latest, True, 1.22, windows) (push) Waiting to run
Tests / test (./cmd/caddy/caddy.exe, ~1.23.0, windows-latest, True, 1.23, windows) (push) Waiting to run
Tests / test (s390x on IBM Z) (push) Waiting to run
Tests / goreleaser-check (push) Waiting to run
Cross-Build / build (~1.22.3, 1.22, aix) (push) Waiting to run
Cross-Build / build (~1.22.3, 1.22, darwin) (push) Waiting to run
Cross-Build / build (~1.22.3, 1.22, dragonfly) (push) Waiting to run
Cross-Build / build (~1.22.3, 1.22, freebsd) (push) Waiting to run
Cross-Build / build (~1.22.3, 1.22, illumos) (push) Waiting to run
Cross-Build / build (~1.22.3, 1.22, linux) (push) Waiting to run
Cross-Build / build (~1.22.3, 1.22, netbsd) (push) Waiting to run
Cross-Build / build (~1.22.3, 1.22, openbsd) (push) Waiting to run
Cross-Build / build (~1.22.3, 1.22, solaris) (push) Waiting to run
Cross-Build / build (~1.22.3, 1.22, windows) (push) Waiting to run
Cross-Build / build (~1.23.0, 1.23, aix) (push) Waiting to run
Cross-Build / build (~1.23.0, 1.23, darwin) (push) Waiting to run
Cross-Build / build (~1.23.0, 1.23, dragonfly) (push) Waiting to run
Cross-Build / build (~1.23.0, 1.23, freebsd) (push) Waiting to run
Cross-Build / build (~1.23.0, 1.23, illumos) (push) Waiting to run
Cross-Build / build (~1.23.0, 1.23, linux) (push) Waiting to run
Cross-Build / build (~1.23.0, 1.23, netbsd) (push) Waiting to run
Cross-Build / build (~1.23.0, 1.23, openbsd) (push) Waiting to run
Cross-Build / build (~1.23.0, 1.23, solaris) (push) Waiting to run
Cross-Build / build (~1.23.0, 1.23, windows) (push) Waiting to run
Lint / lint (macos-14, mac) (push) Waiting to run
Lint / lint (ubuntu-latest, linux) (push) Waiting to run
Lint / lint (windows-latest, windows) (push) Waiting to run
Lint / govulncheck (push) Waiting to run
* feat: add first_exist_or_fallback strategy for try_files * fix tests * linter
This commit is contained in:
parent
b116dcea3d
commit
efd9251ad3
|
@ -58,6 +58,7 @@
|
||||||
"{http.request.uri.path}/index.php",
|
"{http.request.uri.path}/index.php",
|
||||||
"index.php"
|
"index.php"
|
||||||
],
|
],
|
||||||
|
"try_policy": "first_exist_fallback",
|
||||||
"split_path": [
|
"split_path": [
|
||||||
".php"
|
".php"
|
||||||
]
|
]
|
||||||
|
|
|
@ -73,7 +73,8 @@ php_fastcgi @test localhost:9000
|
||||||
"{http.request.uri.path}",
|
"{http.request.uri.path}",
|
||||||
"{http.request.uri.path}/index.php",
|
"{http.request.uri.path}/index.php",
|
||||||
"index.php"
|
"index.php"
|
||||||
]
|
],
|
||||||
|
"try_policy": "first_exist_fallback"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|
|
@ -59,6 +59,7 @@ php_fastcgi localhost:9000 {
|
||||||
"{http.request.uri.path}/index.php5",
|
"{http.request.uri.path}/index.php5",
|
||||||
"index.php5"
|
"index.php5"
|
||||||
],
|
],
|
||||||
|
"try_policy": "first_exist_fallback",
|
||||||
"split_path": [
|
"split_path": [
|
||||||
".php",
|
".php",
|
||||||
".php5"
|
".php5"
|
||||||
|
|
|
@ -32,6 +32,7 @@ php_fastcgi localhost:9000 {
|
||||||
"{http.request.uri.path}",
|
"{http.request.uri.path}",
|
||||||
"index.php"
|
"index.php"
|
||||||
],
|
],
|
||||||
|
"try_policy": "first_exist_fallback",
|
||||||
"split_path": [
|
"split_path": [
|
||||||
".php",
|
".php",
|
||||||
".php5"
|
".php5"
|
||||||
|
|
|
@ -274,7 +274,7 @@ func parseTryFiles(h httpcaddyfile.Helper) ([]httpcaddyfile.ConfigValue, error)
|
||||||
tryPolicy = h.Val()
|
tryPolicy = h.Val()
|
||||||
|
|
||||||
switch tryPolicy {
|
switch tryPolicy {
|
||||||
case tryPolicyFirstExist, tryPolicyLargestSize, tryPolicySmallestSize, tryPolicyMostRecentlyMod:
|
case tryPolicyFirstExist, tryPolicyFirstExistFallback, tryPolicyLargestSize, tryPolicySmallestSize, tryPolicyMostRecentlyMod:
|
||||||
default:
|
default:
|
||||||
return nil, h.Errf("unrecognized try policy: %s", tryPolicy)
|
return nil, h.Errf("unrecognized try policy: %s", tryPolicy)
|
||||||
}
|
}
|
||||||
|
|
|
@ -90,6 +90,7 @@ type MatchFile struct {
|
||||||
// How to choose a file in TryFiles. Can be:
|
// How to choose a file in TryFiles. Can be:
|
||||||
//
|
//
|
||||||
// - first_exist
|
// - first_exist
|
||||||
|
// - first_exist_fallback
|
||||||
// - smallest_size
|
// - smallest_size
|
||||||
// - largest_size
|
// - largest_size
|
||||||
// - most_recently_modified
|
// - most_recently_modified
|
||||||
|
@ -415,13 +416,13 @@ func (m MatchFile) selectFile(r *http.Request) (bool, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// setPlaceholders creates the placeholders for the matched file
|
// 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.relative", filepath.ToSlash(candidate.relative))
|
||||||
repl.Set("http.matchers.file.absolute", filepath.ToSlash(candidate.fullpath))
|
repl.Set("http.matchers.file.absolute", filepath.ToSlash(candidate.fullpath))
|
||||||
repl.Set("http.matchers.file.remainder", filepath.ToSlash(candidate.splitRemainder))
|
repl.Set("http.matchers.file.remainder", filepath.ToSlash(candidate.splitRemainder))
|
||||||
|
|
||||||
fileType := "file"
|
fileType := "file"
|
||||||
if info.IsDir() {
|
if isDir {
|
||||||
fileType = "directory"
|
fileType = "directory"
|
||||||
}
|
}
|
||||||
repl.Set("http.matchers.file.type", fileType)
|
repl.Set("http.matchers.file.type", fileType)
|
||||||
|
@ -429,8 +430,13 @@ func (m MatchFile) selectFile(r *http.Request) (bool, error) {
|
||||||
|
|
||||||
// match file according to the configured policy
|
// match file according to the configured policy
|
||||||
switch m.TryPolicy {
|
switch m.TryPolicy {
|
||||||
case "", tryPolicyFirstExist:
|
case "", tryPolicyFirstExist, tryPolicyFirstExistFallback:
|
||||||
for _, pattern := range m.TryFiles {
|
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,
|
// If the pattern is a status code, emit an error,
|
||||||
// which short-circuits the middleware pipeline and
|
// which short-circuits the middleware pipeline and
|
||||||
// writes an HTTP error response.
|
// writes an HTTP error response.
|
||||||
|
@ -440,8 +446,15 @@ func (m MatchFile) selectFile(r *http.Request) (bool, error) {
|
||||||
|
|
||||||
candidates := makeCandidates(pattern)
|
candidates := makeCandidates(pattern)
|
||||||
for _, c := range candidates {
|
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 {
|
if info, exists := m.strictFileExists(fileSystem, c.fullpath); exists {
|
||||||
setPlaceholders(c, info)
|
setPlaceholders(c, info.IsDir())
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -465,7 +478,7 @@ func (m MatchFile) selectFile(r *http.Request) (bool, error) {
|
||||||
if largestInfo == nil {
|
if largestInfo == nil {
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
setPlaceholders(largest, largestInfo)
|
setPlaceholders(largest, largestInfo.IsDir())
|
||||||
return true, nil
|
return true, nil
|
||||||
|
|
||||||
case tryPolicySmallestSize:
|
case tryPolicySmallestSize:
|
||||||
|
@ -486,7 +499,7 @@ func (m MatchFile) selectFile(r *http.Request) (bool, error) {
|
||||||
if smallestInfo == nil {
|
if smallestInfo == nil {
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
setPlaceholders(smallest, smallestInfo)
|
setPlaceholders(smallest, smallestInfo.IsDir())
|
||||||
return true, nil
|
return true, nil
|
||||||
|
|
||||||
case tryPolicyMostRecentlyMod:
|
case tryPolicyMostRecentlyMod:
|
||||||
|
@ -506,7 +519,7 @@ func (m MatchFile) selectFile(r *http.Request) (bool, error) {
|
||||||
if recentInfo == nil {
|
if recentInfo == nil {
|
||||||
return false, nil
|
return false, nil
|
||||||
}
|
}
|
||||||
setPlaceholders(recent, recentInfo)
|
setPlaceholders(recent, recentInfo.IsDir())
|
||||||
return true, nil
|
return true, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -709,6 +722,7 @@ var globSafeRepl = strings.NewReplacer(
|
||||||
|
|
||||||
const (
|
const (
|
||||||
tryPolicyFirstExist = "first_exist"
|
tryPolicyFirstExist = "first_exist"
|
||||||
|
tryPolicyFirstExistFallback = "first_exist_fallback"
|
||||||
tryPolicyLargestSize = "largest_size"
|
tryPolicyLargestSize = "largest_size"
|
||||||
tryPolicySmallestSize = "smallest_size"
|
tryPolicySmallestSize = "smallest_size"
|
||||||
tryPolicyMostRecentlyMod = "most_recently_modified"
|
tryPolicyMostRecentlyMod = "most_recently_modified"
|
||||||
|
|
|
@ -18,6 +18,7 @@ import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"github.com/caddyserver/caddy/v2"
|
"github.com/caddyserver/caddy/v2"
|
||||||
"github.com/caddyserver/caddy/v2/caddyconfig"
|
"github.com/caddyserver/caddy/v2/caddyconfig"
|
||||||
|
@ -312,12 +313,18 @@ func parsePHPFastCGI(h httpcaddyfile.Helper) ([]httpcaddyfile.ConfigValue, error
|
||||||
if indexFile != "off" {
|
if indexFile != "off" {
|
||||||
dirRedir := false
|
dirRedir := false
|
||||||
dirIndex := "{http.request.uri.path}/" + indexFile
|
dirIndex := "{http.request.uri.path}/" + indexFile
|
||||||
|
tryPolicy := "first_exist_fallback"
|
||||||
|
|
||||||
// if tryFiles wasn't overridden, use a reasonable default
|
// if tryFiles wasn't overridden, use a reasonable default
|
||||||
if len(tryFiles) == 0 {
|
if len(tryFiles) == 0 {
|
||||||
tryFiles = []string{"{http.request.uri.path}", dirIndex, indexFile}
|
tryFiles = []string{"{http.request.uri.path}", dirIndex, indexFile}
|
||||||
dirRedir = true
|
dirRedir = true
|
||||||
} else {
|
} 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 {
|
for _, tf := range tryFiles {
|
||||||
if tf == dirIndex {
|
if tf == dirIndex {
|
||||||
dirRedir = true
|
dirRedir = true
|
||||||
|
@ -357,6 +364,7 @@ func parsePHPFastCGI(h httpcaddyfile.Helper) ([]httpcaddyfile.ConfigValue, error
|
||||||
rewriteMatcherSet := caddy.ModuleMap{
|
rewriteMatcherSet := caddy.ModuleMap{
|
||||||
"file": h.JSON(fileserver.MatchFile{
|
"file": h.JSON(fileserver.MatchFile{
|
||||||
TryFiles: tryFiles,
|
TryFiles: tryFiles,
|
||||||
|
TryPolicy: tryPolicy,
|
||||||
SplitPath: extensions,
|
SplitPath: extensions,
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user