summaryrefslogtreecommitdiff
path: root/modules/caddyhttp/rewrite
diff options
context:
space:
mode:
authorMatthew Holt <mholt@users.noreply.github.com>2019-10-19 19:22:29 -0600
committerMatthew Holt <mholt@users.noreply.github.com>2019-10-19 19:22:29 -0600
commit208f2ff93c1bd2c009e4b96f664c1808ede79f3a (patch)
tree072a5fc3f1624cd8dbd4a8d85d7ec2ff4b83dd60 /modules/caddyhttp/rewrite
parent19e834cf36ed757738ff7504eb8b3fff45f67a79 (diff)
rewrite: Options to strip prefix/suffix and issue redirects
Fixes #2011
Diffstat (limited to 'modules/caddyhttp/rewrite')
-rw-r--r--modules/caddyhttp/rewrite/rewrite.go61
1 files changed, 54 insertions, 7 deletions
diff --git a/modules/caddyhttp/rewrite/rewrite.go b/modules/caddyhttp/rewrite/rewrite.go
index f434a38..7d4c6f7 100644
--- a/modules/caddyhttp/rewrite/rewrite.go
+++ b/modules/caddyhttp/rewrite/rewrite.go
@@ -15,8 +15,10 @@
package rewrite
import (
+ "fmt"
"net/http"
"net/url"
+ "strconv"
"strings"
"github.com/caddyserver/caddy/v2"
@@ -29,9 +31,14 @@ func init() {
// Rewrite is a middleware which can rewrite HTTP requests.
type Rewrite struct {
- Method string `json:"method,omitempty"`
- URI string `json:"uri,omitempty"`
- Rehandle bool `json:"rehandle,omitempty"`
+ Method string `json:"method,omitempty"`
+ URI string `json:"uri,omitempty"`
+
+ StripPathPrefix string `json:"strip_path_prefix,omitempty"`
+ StripPathSuffix string `json:"strip_path_suffix,omitempty"`
+
+ HTTPRedirect caddyhttp.WeakString `json:"http_redirect,omitempty"`
+ Rehandle bool `json:"rehandle,omitempty"`
}
// CaddyModule returns the Caddy module information.
@@ -42,18 +49,28 @@ func (Rewrite) CaddyModule() caddy.ModuleInfo {
}
}
+// Validate ensures rewr's configuration is valid.
+func (rewr Rewrite) Validate() error {
+ if rewr.HTTPRedirect != "" && rewr.Rehandle {
+ return fmt.Errorf("cannot be configured to both write a redirect response and rehandle internally")
+ }
+ return nil
+}
+
func (rewr Rewrite) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddyhttp.Handler) error {
repl := r.Context().Value(caddy.ReplacerCtxKey).(caddy.Replacer)
- var rehandleNeeded bool
+ var changed bool
+ // rewrite the method
if rewr.Method != "" {
method := r.Method
r.Method = strings.ToUpper(repl.ReplaceAll(rewr.Method, ""))
if r.Method != method {
- rehandleNeeded = true
+ changed = true
}
}
+ // rewrite the URI
if rewr.URI != "" {
oldURI := r.RequestURI
newURI := repl.ReplaceAll(rewr.URI, "")
@@ -73,14 +90,44 @@ func (rewr Rewrite) ServeHTTP(w http.ResponseWriter, r *http.Request, next caddy
}
if newURI != oldURI {
- rehandleNeeded = true
+ changed = true
}
}
- if rehandleNeeded && rewr.Rehandle {
+ // strip path prefix or suffix
+ if rewr.StripPathPrefix != "" {
+ prefix := repl.ReplaceAll(rewr.StripPathPrefix, "")
+ r.URL.Path = strings.TrimPrefix(r.URL.Path, prefix)
+ newURI := r.URL.String()
+ if newURI != r.RequestURI {
+ changed = true
+ }
+ r.RequestURI = newURI
+ }
+ if rewr.StripPathSuffix != "" {
+ suffix := repl.ReplaceAll(rewr.StripPathSuffix, "")
+ r.URL.Path = strings.TrimSuffix(r.URL.Path, suffix)
+ newURI := r.URL.String()
+ if newURI != r.RequestURI {
+ changed = true
+ }
+ r.RequestURI = newURI
+ }
+
+ if changed && rewr.Rehandle {
return caddyhttp.ErrRehandle
}
+ if changed && rewr.HTTPRedirect != "" {
+ statusCode, err := strconv.Atoi(repl.ReplaceAll(rewr.HTTPRedirect.String(), ""))
+ if err != nil {
+ return caddyhttp.Error(http.StatusInternalServerError, err)
+ }
+ w.Header().Set("Location", r.RequestURI)
+ w.WriteHeader(statusCode)
+ return nil
+ }
+
return next.ServeHTTP(w, r)
}