summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
authorMatt Holt <mholt@users.noreply.github.com>2019-09-17 15:16:17 -0600
committerGitHub <noreply@github.com>2019-09-17 15:16:17 -0600
commit484cee1ac12ee590128d85da22b6b9df2efe02d4 (patch)
treeddb5f20da081f8f3994d0dbe6fc7988d11a9620f /modules
parentd030bfdae065c8776e8ac14c0a28f725ec05145c (diff)
fastcgi: Implement / redirect for index.php with php_fastcgi directive (#2754)
* fastcgi: Implement / redirect for index.php with php_fastcgi directive See #2752 and https://caddy.community/t/v2-redirect-path-to-path-index-php-with-assets/6196?u=matt * caddyhttp: MatchNegate implements json.Marshaler * fastcgi: Add /index.php element to try_files matcher * fastcgi: Make /index.php redirect permanent
Diffstat (limited to 'modules')
-rw-r--r--modules/caddyhttp/matchers.go22
-rw-r--r--modules/caddyhttp/reverseproxy/fastcgi/caddyfile.go29
2 files changed, 42 insertions, 9 deletions
diff --git a/modules/caddyhttp/matchers.go b/modules/caddyhttp/matchers.go
index 94d051e..9cf52dc 100644
--- a/modules/caddyhttp/matchers.go
+++ b/modules/caddyhttp/matchers.go
@@ -66,9 +66,9 @@ type (
// MatchNegate matches requests by negating its matchers' results.
MatchNegate struct {
- matchersRaw map[string]json.RawMessage
+ MatchersRaw map[string]json.RawMessage `json:"-"`
- matchers MatcherSet
+ Matchers MatcherSet `json:"-"`
}
// MatchStarlarkExpr matches requests by evaluating a Starlark expression.
@@ -400,7 +400,12 @@ func (MatchNegate) CaddyModule() caddy.ModuleInfo {
// the struct, but we need a struct because we need another
// field just for the provisioned modules.
func (m *MatchNegate) UnmarshalJSON(data []byte) error {
- return json.Unmarshal(data, &m.matchersRaw)
+ return json.Unmarshal(data, &m.MatchersRaw)
+}
+
+// MarshalJSON marshals m's matchers.
+func (m MatchNegate) MarshalJSON() ([]byte, error) {
+ return json.Marshal(m.MatchersRaw)
}
// UnmarshalCaddyfile implements caddyfile.Unmarshaler.
@@ -411,21 +416,21 @@ func (m *MatchNegate) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
// Provision loads the matcher modules to be negated.
func (m *MatchNegate) Provision(ctx caddy.Context) error {
- for modName, rawMsg := range m.matchersRaw {
+ for modName, rawMsg := range m.MatchersRaw {
val, err := ctx.LoadModule("http.matchers."+modName, rawMsg)
if err != nil {
return fmt.Errorf("loading matcher module '%s': %v", modName, err)
}
- m.matchers = append(m.matchers, val.(RequestMatcher))
+ m.Matchers = append(m.Matchers, val.(RequestMatcher))
}
- m.matchersRaw = nil // allow GC to deallocate
+ m.MatchersRaw = nil // allow GC to deallocate
return nil
}
// Match returns true if r matches m. Since this matcher negates the
// embedded matchers, false is returned if any of its matchers match.
func (m MatchNegate) Match(r *http.Request) bool {
- return !m.matchers.Match(r)
+ return !m.Matchers.Match(r)
}
// CaddyModule returns the Caddy module information.
@@ -686,4 +691,7 @@ var (
_ caddyfile.Unmarshaler = (*MatchHeaderRE)(nil)
_ caddyfile.Unmarshaler = (*MatchProtocol)(nil)
_ caddyfile.Unmarshaler = (*MatchRemoteIP)(nil)
+
+ _ json.Marshaler = (*MatchNegate)(nil)
+ _ json.Unmarshaler = (*MatchNegate)(nil)
)
diff --git a/modules/caddyhttp/reverseproxy/fastcgi/caddyfile.go b/modules/caddyhttp/reverseproxy/fastcgi/caddyfile.go
index fd82c5a..b7326af 100644
--- a/modules/caddyhttp/reverseproxy/fastcgi/caddyfile.go
+++ b/modules/caddyhttp/reverseproxy/fastcgi/caddyfile.go
@@ -16,6 +16,7 @@ package fastcgi
import (
"encoding/json"
+ "net/http"
"github.com/caddyserver/caddy/v2/caddyconfig"
"github.com/caddyserver/caddy/v2/caddyconfig/caddyfile"
@@ -114,10 +115,30 @@ func parsePHPFastCGI(h httpcaddyfile.Helper) ([]httpcaddyfile.ConfigValue, error
return nil, h.ArgErr()
}
+ // route to redirect to canonical path if index PHP file
+ redirMatcherSet := map[string]json.RawMessage{
+ "file": h.JSON(fileserver.MatchFile{
+ TryFiles: []string{"{http.request.uri.path}/index.php"},
+ }, nil),
+ "not": h.JSON(caddyhttp.MatchNegate{
+ MatchersRaw: map[string]json.RawMessage{
+ "path": h.JSON(caddyhttp.MatchPath{"*/"}, nil),
+ },
+ }, nil),
+ }
+ redirHandler := caddyhttp.StaticResponse{
+ StatusCode: caddyhttp.WeakString("308"),
+ Headers: http.Header{"Location": []string{"{http.request.uri.path}/"}},
+ }
+ redirRoute := caddyhttp.Route{
+ MatcherSetsRaw: []map[string]json.RawMessage{redirMatcherSet},
+ HandlersRaw: []json.RawMessage{caddyconfig.JSONModuleObject(redirHandler, "handler", "static_response", nil)},
+ }
+
// route to rewrite to PHP index file
rewriteMatcherSet := map[string]json.RawMessage{
"file": h.JSON(fileserver.MatchFile{
- TryFiles: []string{"{http.request.uri.path}", "index.php"},
+ TryFiles: []string{"{http.request.uri.path}", "{http.request.uri.path}/index.php", "index.php"},
}, nil),
}
rewriteHandler := rewrite.Rewrite{
@@ -175,7 +196,7 @@ func parsePHPFastCGI(h httpcaddyfile.Helper) ([]httpcaddyfile.ConfigValue, error
// wrap ours in a subroute and return that
if hasUserMatcher {
subroute := caddyhttp.Subroute{
- Routes: caddyhttp.RouteList{rewriteRoute, rpRoute},
+ Routes: caddyhttp.RouteList{redirRoute, rewriteRoute, rpRoute},
}
return []httpcaddyfile.ConfigValue{
{
@@ -193,6 +214,10 @@ func parsePHPFastCGI(h httpcaddyfile.Helper) ([]httpcaddyfile.ConfigValue, error
return []httpcaddyfile.ConfigValue{
{
Class: "route",
+ Value: redirRoute,
+ },
+ {
+ Class: "route",
Value: rewriteRoute,
},
{