mirror of
https://github.com/caddyserver/caddy.git
synced 2026-06-27 12:21:47 +00:00
rewrite: scope keyed query replace to its named key (#7818)
Some checks failed
Tests / test (./cmd/caddy/caddy, ~1.26.0, macos-14, 0, 1.26, mac) (push) Has been cancelled
Tests / test (./cmd/caddy/caddy, ~1.26.0, ubuntu-latest, 0, 1.26, linux) (push) Has been cancelled
Tests / test (./cmd/caddy/caddy.exe, ~1.26.0, windows-latest, True, 1.26, windows) (push) Has been cancelled
Tests / test (s390x on IBM Z) (push) Has been cancelled
Tests / goreleaser-check (push) Has been cancelled
Cross-Build / build (~1.26.0, 1.26, aix) (push) Has been cancelled
Cross-Build / build (~1.26.0, 1.26, darwin) (push) Has been cancelled
Cross-Build / build (~1.26.0, 1.26, dragonfly) (push) Has been cancelled
Cross-Build / build (~1.26.0, 1.26, freebsd) (push) Has been cancelled
Cross-Build / build (~1.26.0, 1.26, illumos) (push) Has been cancelled
Cross-Build / build (~1.26.0, 1.26, linux) (push) Has been cancelled
Cross-Build / build (~1.26.0, 1.26, netbsd) (push) Has been cancelled
Cross-Build / build (~1.26.0, 1.26, openbsd) (push) Has been cancelled
Cross-Build / build (~1.26.0, 1.26, solaris) (push) Has been cancelled
Cross-Build / build (~1.26.0, 1.26, windows) (push) Has been cancelled
Lint / lint (push) Has been cancelled
Lint / lint-1 (push) Has been cancelled
Lint / lint-2 (push) Has been cancelled
Lint / govulncheck (push) Has been cancelled
Lint / dependency-review (push) Has been cancelled
OpenSSF Scorecard supply-chain security / Scorecard analysis (push) Has been cancelled
Some checks failed
Tests / test (./cmd/caddy/caddy, ~1.26.0, macos-14, 0, 1.26, mac) (push) Has been cancelled
Tests / test (./cmd/caddy/caddy, ~1.26.0, ubuntu-latest, 0, 1.26, linux) (push) Has been cancelled
Tests / test (./cmd/caddy/caddy.exe, ~1.26.0, windows-latest, True, 1.26, windows) (push) Has been cancelled
Tests / test (s390x on IBM Z) (push) Has been cancelled
Tests / goreleaser-check (push) Has been cancelled
Cross-Build / build (~1.26.0, 1.26, aix) (push) Has been cancelled
Cross-Build / build (~1.26.0, 1.26, darwin) (push) Has been cancelled
Cross-Build / build (~1.26.0, 1.26, dragonfly) (push) Has been cancelled
Cross-Build / build (~1.26.0, 1.26, freebsd) (push) Has been cancelled
Cross-Build / build (~1.26.0, 1.26, illumos) (push) Has been cancelled
Cross-Build / build (~1.26.0, 1.26, linux) (push) Has been cancelled
Cross-Build / build (~1.26.0, 1.26, netbsd) (push) Has been cancelled
Cross-Build / build (~1.26.0, 1.26, openbsd) (push) Has been cancelled
Cross-Build / build (~1.26.0, 1.26, solaris) (push) Has been cancelled
Cross-Build / build (~1.26.0, 1.26, windows) (push) Has been cancelled
Lint / lint (push) Has been cancelled
Lint / lint-1 (push) Has been cancelled
Lint / lint-2 (push) Has been cancelled
Lint / govulncheck (push) Has been cancelled
Lint / dependency-review (push) Has been cancelled
OpenSSF Scorecard supply-chain security / Scorecard analysis (push) Has been cancelled
* rewrite: scope keyed query replace to its named key * rewrite: cover keyed search_regexp query replace in test * rewrite: provision query replace test via Provision path
This commit is contained in:
parent
39c9a85f80
commit
ae9bc028e6
2 changed files with 69 additions and 7 deletions
|
|
@ -606,13 +606,15 @@ func (q *queryOps) do(r *http.Request, repl *caddy.Replacer) {
|
|||
continue
|
||||
}
|
||||
|
||||
for fieldName, vals := range query {
|
||||
for i := range vals {
|
||||
if replaceParam.re != nil {
|
||||
query[fieldName][i] = replaceParam.re.ReplaceAllString(query[fieldName][i], replace)
|
||||
} else {
|
||||
query[fieldName][i] = strings.ReplaceAll(query[fieldName][i], search, replace)
|
||||
}
|
||||
vals, ok := query[key]
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
for i := range vals {
|
||||
if replaceParam.re != nil {
|
||||
query[key][i] = replaceParam.re.ReplaceAllString(query[key][i], replace)
|
||||
} else {
|
||||
query[key][i] = strings.ReplaceAll(query[key][i], search, replace)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -483,6 +483,66 @@ func TestQueryOpsRenameNoOpCases(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestQueryOpsReplaceScopedToKey(t *testing.T) {
|
||||
repl := caddy.NewReplacer()
|
||||
|
||||
for i, tc := range []struct {
|
||||
input *http.Request
|
||||
expect map[string][]string
|
||||
ops *queryOps
|
||||
}{
|
||||
{
|
||||
// a keyed replace must only touch the named key, even when
|
||||
// other keys hold the same value
|
||||
ops: &queryOps{
|
||||
Replace: []*queryOpsReplacement{{Key: "a", Search: "foo", Replace: "bar"}},
|
||||
},
|
||||
input: newRequest(t, "GET", "/?a=foo&b=foo"),
|
||||
expect: map[string][]string{"a": {"bar"}, "b": {"foo"}},
|
||||
},
|
||||
{
|
||||
// "*" still replaces across every key
|
||||
ops: &queryOps{
|
||||
Replace: []*queryOpsReplacement{{Key: "*", Search: "foo", Replace: "bar"}},
|
||||
},
|
||||
input: newRequest(t, "GET", "/?a=foo&b=foo"),
|
||||
expect: map[string][]string{"a": {"bar"}, "b": {"bar"}},
|
||||
},
|
||||
{
|
||||
// a keyed replace against a missing key is a no-op
|
||||
ops: &queryOps{
|
||||
Replace: []*queryOpsReplacement{{Key: "missing", Search: "foo", Replace: "bar"}},
|
||||
},
|
||||
input: newRequest(t, "GET", "/?a=foo&b=foo"),
|
||||
expect: map[string][]string{"a": {"foo"}, "b": {"foo"}},
|
||||
},
|
||||
{
|
||||
// the regexp branch must also stay scoped to the named key
|
||||
ops: &queryOps{
|
||||
Replace: []*queryOpsReplacement{{Key: "a", SearchRegexp: "f.o", Replace: "bar"}},
|
||||
},
|
||||
input: newRequest(t, "GET", "/?a=foo&b=foo"),
|
||||
expect: map[string][]string{"a": {"bar"}, "b": {"foo"}},
|
||||
},
|
||||
} {
|
||||
repl.Set("http.request.uri", tc.input.RequestURI)
|
||||
repl.Set("http.request.uri.path", tc.input.URL.Path)
|
||||
repl.Set("http.request.uri.query", tc.input.URL.RawQuery)
|
||||
|
||||
for _, rep := range tc.ops.Replace {
|
||||
if err := rep.Provision(caddy.Context{}); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
tc.ops.do(tc.input, repl)
|
||||
|
||||
if actual := tc.input.URL.Query(); !reflect.DeepEqual(tc.expect, map[string][]string(actual)) {
|
||||
t.Errorf("Test %d: Expected query=%v but got %v", i, tc.expect, actual)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func newRequest(t *testing.T, method, uri string) *http.Request {
|
||||
req, err := http.NewRequest(method, uri, nil)
|
||||
if err != nil {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue