mirror of
https://github.com/caddyserver/caddy.git
synced 2026-08-02 10:28:07 -04:00
rewrite: preserve non-canonical path encoding after uri replace (#7907)
changePath cleared RawPath whenever it equalled url.Path, which discarded a valid non-canonical percent-encoding produced by a replacement. This compare `RawPath` against the default escaping of Path instead.
This commit is contained in:
@@ -513,12 +513,21 @@ func changePath(req *http.Request, newVal func(pathOrRawPath string) string) {
|
||||
} else {
|
||||
req.URL.Path = newVal(req.URL.Path)
|
||||
}
|
||||
// RawPath is only set if it's different from the normalized Path (std lib)
|
||||
if req.URL.RawPath == req.URL.Path {
|
||||
// RawPath is only needed if it is a valid, non-canonical encoding of Path;
|
||||
// (see #6578). Mirror net/url.URL.setPath by comparing against the default
|
||||
// escaping of Path instead.
|
||||
if req.URL.RawPath == defaultEscapedPath(req.URL.Path) {
|
||||
req.URL.RawPath = ""
|
||||
}
|
||||
}
|
||||
|
||||
// defaultEscapedPath returns the canonical percent-encoding of p, matching
|
||||
// what net/url.URL.EscapedPath() produces when RawPath is empty. It mirrors
|
||||
// the comparison net/url.URL.setPath uses to decide whether RawPath is needed.
|
||||
func defaultEscapedPath(p string) string {
|
||||
return (&url.URL{Path: p}).EscapedPath()
|
||||
}
|
||||
|
||||
// queryOps describes the operations to perform on query keys: add, set, rename and delete.
|
||||
type queryOps struct {
|
||||
// Renames a query key from Key to Val, without affecting the value.
|
||||
|
||||
@@ -351,6 +351,19 @@ func TestRewrite(t *testing.T) {
|
||||
input: newRequest(t, "GET", "/foo/findme%2Fbar"),
|
||||
expect: newRequest(t, "GET", "/foo/replaced%2Fbar"),
|
||||
},
|
||||
{
|
||||
rule: Rewrite{URISubstring: []substrReplacer{{Find: "%28", Replace: "("}}},
|
||||
input: newRequest(t, "GET", "/hello/%28%29"),
|
||||
expect: newRequest(t, "GET", "/hello/(%29"),
|
||||
},
|
||||
{
|
||||
rule: Rewrite{URISubstring: []substrReplacer{
|
||||
{Find: "%28", Replace: "("},
|
||||
{Find: "%29", Replace: ")"},
|
||||
}},
|
||||
input: newRequest(t, "GET", "/hello/%28%29"),
|
||||
expect: newRequest(t, "GET", "/hello/()"),
|
||||
},
|
||||
|
||||
{
|
||||
rule: Rewrite{PathRegexp: []*regexReplacer{{Find: "/{2,}", Replace: "/"}}},
|
||||
|
||||
Reference in New Issue
Block a user