mirror of
https://github.com/caddyserver/caddy.git
synced 2024-12-28 06:33:47 +03:00
Prevent information loss, i.e. the encoded form that was sent by the client, when using URL strip/replace.
This commit is contained in:
parent
4f64105fbb
commit
88a38bd00d
2 changed files with 37 additions and 11 deletions
|
@ -191,11 +191,21 @@ func (rewr Rewrite) rewrite(r *http.Request, repl *caddy.Replacer, logger *zap.L
|
||||||
// strip path prefix or suffix
|
// strip path prefix or suffix
|
||||||
if rewr.StripPathPrefix != "" {
|
if rewr.StripPathPrefix != "" {
|
||||||
prefix := repl.ReplaceAll(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 != "" {
|
if rewr.StripPathSuffix != "" {
|
||||||
suffix := repl.ReplaceAll(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
|
// substring replacements in URI
|
||||||
|
@ -289,10 +299,10 @@ type replacer struct {
|
||||||
Limit int `json:"limit,omitempty"`
|
Limit int `json:"limit,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// do performs the replacement on r and returns true if any changes were made.
|
// do performs the replacement on r.
|
||||||
func (rep replacer) do(r *http.Request, repl *caddy.Replacer) bool {
|
func (rep replacer) do(r *http.Request, repl *caddy.Replacer) {
|
||||||
if rep.Find == "" || rep.Replace == "" {
|
if rep.Find == "" || rep.Replace == "" {
|
||||||
return false
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
lim := rep.Limit
|
lim := rep.Limit
|
||||||
|
@ -303,13 +313,14 @@ func (rep replacer) do(r *http.Request, repl *caddy.Replacer) bool {
|
||||||
find := repl.ReplaceAll(rep.Find, "")
|
find := repl.ReplaceAll(rep.Find, "")
|
||||||
replace := repl.ReplaceAll(rep.Replace, "")
|
replace := repl.ReplaceAll(rep.Replace, "")
|
||||||
|
|
||||||
oldPath := r.URL.Path
|
r.URL.RawPath = strings.Replace(r.URL.RawPath, find, replace, lim)
|
||||||
oldQuery := r.URL.RawQuery
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
r.URL.Path = strings.Replace(oldPath, find, replace, lim)
|
r.URL.RawQuery = strings.Replace(r.URL.RawQuery, find, replace, lim)
|
||||||
r.URL.RawQuery = strings.Replace(oldQuery, find, replace, lim)
|
|
||||||
|
|
||||||
return r.URL.Path != oldPath && r.URL.RawQuery != oldQuery
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Interface guard
|
// Interface guard
|
||||||
|
|
|
@ -199,6 +199,11 @@ func TestRewrite(t *testing.T) {
|
||||||
input: newRequest(t, "GET", "/prefix/foo/bar"),
|
input: newRequest(t, "GET", "/prefix/foo/bar"),
|
||||||
expect: newRequest(t, "GET", "/foo/bar"),
|
expect: newRequest(t, "GET", "/foo/bar"),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
rule: Rewrite{StripPathPrefix: "/prefix"},
|
||||||
|
input: newRequest(t, "GET", "/prefix/foo%2Fbar"),
|
||||||
|
expect: newRequest(t, "GET", "/foo%2Fbar"),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
rule: Rewrite{StripPathPrefix: "/prefix"},
|
rule: Rewrite{StripPathPrefix: "/prefix"},
|
||||||
input: newRequest(t, "GET", "/foo/prefix/bar"),
|
input: newRequest(t, "GET", "/foo/prefix/bar"),
|
||||||
|
@ -215,6 +220,11 @@ func TestRewrite(t *testing.T) {
|
||||||
input: newRequest(t, "GET", "/foo/bar/suffix"),
|
input: newRequest(t, "GET", "/foo/bar/suffix"),
|
||||||
expect: newRequest(t, "GET", "/foo/bar/"),
|
expect: newRequest(t, "GET", "/foo/bar/"),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
rule: Rewrite{StripPathSuffix: "suffix"},
|
||||||
|
input: newRequest(t, "GET", "/foo%2Fbar/suffix"),
|
||||||
|
expect: newRequest(t, "GET", "/foo%2Fbar/"),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
rule: Rewrite{StripPathSuffix: "/suffix"},
|
rule: Rewrite{StripPathSuffix: "/suffix"},
|
||||||
input: newRequest(t, "GET", "/foo/suffix/bar"),
|
input: newRequest(t, "GET", "/foo/suffix/bar"),
|
||||||
|
@ -231,6 +241,11 @@ func TestRewrite(t *testing.T) {
|
||||||
input: newRequest(t, "GET", "/foo/findme/bar"),
|
input: newRequest(t, "GET", "/foo/findme/bar"),
|
||||||
expect: newRequest(t, "GET", "/foo/replaced/bar"),
|
expect: newRequest(t, "GET", "/foo/replaced/bar"),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
rule: Rewrite{URISubstring: []replacer{{Find: "findme", Replace: "replaced"}}},
|
||||||
|
input: newRequest(t, "GET", "/foo/findme%2Fbar"),
|
||||||
|
expect: newRequest(t, "GET", "/foo/replaced%2Fbar"),
|
||||||
|
},
|
||||||
} {
|
} {
|
||||||
// copy the original input just enough so that we can
|
// copy the original input just enough so that we can
|
||||||
// compare it after the rewrite to see if it changed
|
// compare it after the rewrite to see if it changed
|
||||||
|
|
Loading…
Reference in a new issue