diff options
| author | Matthew Holt <mholt@users.noreply.github.com> | 2019-10-19 19:22:29 -0600 | 
|---|---|---|
| committer | Matthew Holt <mholt@users.noreply.github.com> | 2019-10-19 19:22:29 -0600 | 
| commit | 208f2ff93c1bd2c009e4b96f664c1808ede79f3a (patch) | |
| tree | 072a5fc3f1624cd8dbd4a8d85d7ec2ff4b83dd60 /modules/caddyhttp/rewrite | |
| parent | 19e834cf36ed757738ff7504eb8b3fff45f67a79 (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.go | 61 | 
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)  } | 
