summaryrefslogtreecommitdiff
path: root/modules/caddyhttp/rewrite/rewrite.go
diff options
context:
space:
mode:
authorgo-d <37667595+go-d@users.noreply.github.com>2021-01-11 17:18:53 +0100
committerGitHub <noreply@github.com>2021-01-11 09:18:53 -0700
commit88a38bd00d386457aec71696a386449d3bcf8990 (patch)
tree12df326ddc9282279b5b7be118dee158c38902b3 /modules/caddyhttp/rewrite/rewrite.go
parent4f64105fbb9b315e8faf7a15144fe27e780d5384 (diff)
rewrite: Use RawPath instead of Path (fix #3596) (#3918)
Prevent information loss, i.e. the encoded form that was sent by the client, when using URL strip/replace.
Diffstat (limited to 'modules/caddyhttp/rewrite/rewrite.go')
-rw-r--r--modules/caddyhttp/rewrite/rewrite.go33
1 files changed, 22 insertions, 11 deletions
diff --git a/modules/caddyhttp/rewrite/rewrite.go b/modules/caddyhttp/rewrite/rewrite.go
index d47c388..ad1c470 100644
--- a/modules/caddyhttp/rewrite/rewrite.go
+++ b/modules/caddyhttp/rewrite/rewrite.go
@@ -191,11 +191,21 @@ func (rewr Rewrite) rewrite(r *http.Request, repl *caddy.Replacer, logger *zap.L
// strip path prefix or suffix
if rewr.StripPathPrefix != "" {
prefix := repl.ReplaceAll(rewr.StripPathPrefix, "")
- r.URL.Path = strings.TrimPrefix(r.URL.Path, prefix)
+ r.URL.RawPath = strings.TrimPrefix(r.URL.RawPath, prefix)
+ if p, err := url.PathUnescape(r.URL.RawPath); err == nil && p != "" {
+ r.URL.Path = p
+ } else {
+ r.URL.Path = strings.TrimPrefix(r.URL.Path, prefix)
+ }
}
if rewr.StripPathSuffix != "" {
suffix := repl.ReplaceAll(rewr.StripPathSuffix, "")
- r.URL.Path = strings.TrimSuffix(r.URL.Path, suffix)
+ r.URL.RawPath = strings.TrimSuffix(r.URL.RawPath, suffix)
+ if p, err := url.PathUnescape(r.URL.RawPath); err == nil && p != "" {
+ r.URL.Path = p
+ } else {
+ r.URL.Path = strings.TrimSuffix(r.URL.Path, suffix)
+ }
}
// substring replacements in URI
@@ -289,10 +299,10 @@ type replacer struct {
Limit int `json:"limit,omitempty"`
}
-// do performs the replacement on r and returns true if any changes were made.
-func (rep replacer) do(r *http.Request, repl *caddy.Replacer) bool {
+// do performs the replacement on r.
+func (rep replacer) do(r *http.Request, repl *caddy.Replacer) {
if rep.Find == "" || rep.Replace == "" {
- return false
+ return
}
lim := rep.Limit
@@ -303,13 +313,14 @@ func (rep replacer) do(r *http.Request, repl *caddy.Replacer) bool {
find := repl.ReplaceAll(rep.Find, "")
replace := repl.ReplaceAll(rep.Replace, "")
- oldPath := r.URL.Path
- oldQuery := r.URL.RawQuery
-
- r.URL.Path = strings.Replace(oldPath, find, replace, lim)
- r.URL.RawQuery = strings.Replace(oldQuery, find, replace, lim)
+ r.URL.RawPath = strings.Replace(r.URL.RawPath, find, replace, lim)
+ if p, err := url.PathUnescape(r.URL.RawPath); err == nil && p != "" {
+ r.URL.Path = p
+ } else {
+ r.URL.Path = strings.Replace(r.URL.Path, find, replace, lim)
+ }
- return r.URL.Path != oldPath && r.URL.RawQuery != oldQuery
+ r.URL.RawQuery = strings.Replace(r.URL.RawQuery, find, replace, lim)
}
// Interface guard