Fast and extensible multi-platform HTTP/1-2-3 web server with automatic HTTPS
Mirrored from https://github.com/Slazee/caddy.git
Synced Nov 14, 05:15 UTC
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
Matt Holt committed
Sep 17, 2019 at 15:16 UTC
484cee1ac12ee590128d85da22b6b9df2efe02d4
2 files changed
+42
-9
modules/caddyhttp/matchers.go
+15
-7
@@ -66,9 +66,9 @@ type (
66
67
// MatchNegate matches requests by negating its matchers' results.
68
MatchNegate struct {
69
- matchersRaw map[string]json.RawMessage
69
+ MatchersRaw map[string]json.RawMessage `json:"-"`
70
71
- matchers MatcherSet
71
+ Matchers MatcherSet `json:"-"`
72
}
73
74
// MatchStarlarkExpr matches requests by evaluating a Starlark expression.
@@ -400,7 +400,12 @@ func (MatchNegate) CaddyModule() caddy.ModuleInfo {
400
// the struct, but we need a struct because we need another
401
// field just for the provisioned modules.
402
func (m *MatchNegate) UnmarshalJSON(data []byte) error {
403
- return json.Unmarshal(data, &m.matchersRaw)
403
+ return json.Unmarshal(data, &m.MatchersRaw)
404
+}
405
+
406
+// MarshalJSON marshals m's matchers.
407
+func (m MatchNegate) MarshalJSON() ([]byte, error) {
408
+ return json.Marshal(m.MatchersRaw)
409
}
410
411
// UnmarshalCaddyfile implements caddyfile.Unmarshaler.
@@ -411,21 +416,21 @@ func (m *MatchNegate) UnmarshalCaddyfile(d *caddyfile.Dispenser) error {
416
417
// Provision loads the matcher modules to be negated.
418
func (m *MatchNegate) Provision(ctx caddy.Context) error {
414
- for modName, rawMsg := range m.matchersRaw {
419
+ for modName, rawMsg := range m.MatchersRaw {
420
val, err := ctx.LoadModule("http.matchers."+modName, rawMsg)
421
if err != nil {
422
return fmt.Errorf("loading matcher module '%s': %v", modName, err)
423
}
419
- m.matchers = append(m.matchers, val.(RequestMatcher))
424
+ m.Matchers = append(m.Matchers, val.(RequestMatcher))
425
}
421
- m.matchersRaw = nil // allow GC to deallocate
426
+ m.MatchersRaw = nil // allow GC to deallocate
427
return nil
428
}
429
430
// Match returns true if r matches m. Since this matcher negates the
431
// embedded matchers, false is returned if any of its matchers match.
432
func (m MatchNegate) Match(r *http.Request) bool {
428
- return !m.matchers.Match(r)
433
+ return !m.Matchers.Match(r)
434
}
435
436
// CaddyModule returns the Caddy module information.
@@ -686,4 +691,7 @@ var (
691
_ caddyfile.Unmarshaler = (*MatchHeaderRE)(nil)
692
_ caddyfile.Unmarshaler = (*MatchProtocol)(nil)
693
_ caddyfile.Unmarshaler = (*MatchRemoteIP)(nil)
694
+
695
+ _ json.Marshaler = (*MatchNegate)(nil)
696
+ _ json.Unmarshaler = (*MatchNegate)(nil)
697
)
modules/caddyhttp/reverseproxy/fastcgi/caddyfile.go
+27
-2
@@ -16,6 +16,7 @@ package fastcgi
16
17
import (
18
"encoding/json"
19
+ "net/http"
20
21
"github.com/caddyserver/caddy/v2/caddyconfig"
22
"github.com/caddyserver/caddy/v2/caddyconfig/caddyfile"
@@ -114,10 +115,30 @@ func parsePHPFastCGI(h httpcaddyfile.Helper) ([]httpcaddyfile.ConfigValue, error
115
return nil, h.ArgErr()
116
}
117
118
+ // route to redirect to canonical path if index PHP file
119
+ redirMatcherSet := map[string]json.RawMessage{
120
+ "file": h.JSON(fileserver.MatchFile{
121
+ TryFiles: []string{"{http.request.uri.path}/index.php"},
122
+ }, nil),
123
+ "not": h.JSON(caddyhttp.MatchNegate{
124
+ MatchersRaw: map[string]json.RawMessage{
125
+ "path": h.JSON(caddyhttp.MatchPath{"*/"}, nil),
126
+ },
127
+ }, nil),
128
+ }
129
+ redirHandler := caddyhttp.StaticResponse{
130
+ StatusCode: caddyhttp.WeakString("308"),
131
+ Headers: http.Header{"Location": []string{"{http.request.uri.path}/"}},
132
+ }
133
+ redirRoute := caddyhttp.Route{
134
+ MatcherSetsRaw: []map[string]json.RawMessage{redirMatcherSet},
135
+ HandlersRaw: []json.RawMessage{caddyconfig.JSONModuleObject(redirHandler, "handler", "static_response", nil)},
136
+ }
137
+
138
// route to rewrite to PHP index file
139
rewriteMatcherSet := map[string]json.RawMessage{
140
"file": h.JSON(fileserver.MatchFile{
120
- TryFiles: []string{"{http.request.uri.path}", "index.php"},
141
+ TryFiles: []string{"{http.request.uri.path}", "{http.request.uri.path}/index.php", "index.php"},
142
}, nil),
143
}
144
rewriteHandler := rewrite.Rewrite{
@@ -175,7 +196,7 @@ func parsePHPFastCGI(h httpcaddyfile.Helper) ([]httpcaddyfile.ConfigValue, error
196
// wrap ours in a subroute and return that
197
if hasUserMatcher {
198
subroute := caddyhttp.Subroute{
178
- Routes: caddyhttp.RouteList{rewriteRoute, rpRoute},
199
+ Routes: caddyhttp.RouteList{redirRoute, rewriteRoute, rpRoute},
200
}
201
return []httpcaddyfile.ConfigValue{
202
{
@@ -191,6 +212,10 @@ func parsePHPFastCGI(h httpcaddyfile.Helper) ([]httpcaddyfile.ConfigValue, error
212
// if the user did not specify a matcher, then
213
// we can just use our own matchers
214
return []httpcaddyfile.ConfigValue{
215
+ {
216
+ Class: "route",
217
+ Value: redirRoute,
218
+ },
219
{
220
Class: "route",
221
Value: rewriteRoute,