Skip to content

header_rewrite: add sort-destination operator#13424

Open
juanthropic wants to merge 9 commits into
apache:masterfrom
juanthropic:hrw-cachekey-sort-dest-query
Open

header_rewrite: add sort-destination operator#13424
juanthropic wants to merge 9 commits into
apache:masterfrom
juanthropic:hrw-cachekey-sort-dest-query

Conversation

@juanthropic

Copy link
Copy Markdown
Contributor

Add a sort-destination QUERY operator to header_rewrite that stably
sorts the request URL's query parameters by name. Normalizing parameter
order lets varied client query strings map to one origin request, which
helps origin-side caching and dedup.

The sort logic lives in a new pure, TS-API-free sort_query() helper
with its own unit test, kept separate from the operator so the
cache-key and parent-key operators can reuse it in a later PR.

  • sort_query() uses a stable sort, so duplicate-named parameters keep
    their relative order.
  • Empty tokens from leading, trailing, or consecutive & are dropped.
  • Docs note that QUERY is the only supported part; any other part is a
    no-op, matching the sibling rm-destination wording.

Covered by a Catch2 unit test for the helper and an end-to-end Proxy
Verifier test that checks an unsorted client query reaches the origin
sorted.

Adds a pure, TS-API-free sort_query() that stably sorts a URL
query string's parameters by name, plus a Catch2 unit test. This
helper is reused by the new sort-destination operator and, in a
later PR, by the cache/parent-key operators.
Adds OperatorSortDestination, which stably sorts the request
URL's query parameters by name using the new sort_query() helper.
Useful for origin normalization, not just cache keys.
Verifies that an unsorted client query is forwarded to the
origin sorted by header_rewrite's sort-destination operator.
Adds tests for a trailing '&' and for a value containing '=',
both flagged during code review as untested-but-correct paths.
Sorting only reorders tokens, so the output length equals the input
length; reserving it up front avoids the geometric-growth reallocations
std::string would otherwise do while appending in the loop.
split matches how other languages name this operation (Python str.split, Go strings.Split); tokenize implied a distinction from splitting that was not intended.
An empty query tuple (leading '&' or '&&') sorts to the front and is silently absorbed by the join loop's emptiness check, regardless of position. Only the trailing case was previously covered.
rm-destination handles only QUERY, PATH, and PORT. Document that any other part is a no-op leaving the destination unchanged, so rule authors know it does not error.
sort-destination supports only QUERY. Document that any other part is a no-op leaving the destination unchanged, matching the sibling rm-destination wording.
@juanthropic
juanthropic marked this pull request as ready for review July 23, 2026 20:00
@JosiahWI JosiahWI added the header_rewrite header_rewrite plugin label Jul 23, 2026
@JosiahWI JosiahWI added this to the 11.0.0 milestone Jul 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

header_rewrite header_rewrite plugin

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants