Skip to content

header_rewrite: add POST_REMAP_HOOK support - #13426

Open
juanthropic wants to merge 4 commits into
apache:masterfrom
juanthropic:hrw-enable-post-remap
Open

header_rewrite: add POST_REMAP_HOOK support#13426
juanthropic wants to merge 4 commits into
apache:masterfrom
juanthropic:hrw-enable-post-remap

Conversation

@juanthropic

@juanthropic juanthropic commented Jul 24, 2026

Copy link
Copy Markdown
Contributor

header_rewrite can attach rulesets to most transaction hooks, but not to
TS_HTTP_POST_REMAP_HOOK. For a global (plugin.config) configuration, that
leaves no hook that sees the remapped request before the cache lookup:

  • READ_REQUEST_HDR_HOOK / READ_REQUEST_PRE_REMAP_HOOK run before remapping,
    so they only ever see the pristine request.
  • REMAP_PSEUDO_HOOK sees the remapped request before the lookup, but is valid
    only in a remap context.
  • SEND_REQUEST_HDR_HOOK sees the remapped request, but fires after the lookup
    and only when the request is forwarded to an origin. It cannot influence the
    lookup, and it never runs on a cache hit.

That window is where anything feeding the cache lookup has to run. The cachekey
plugin registers TS_HTTP_POST_REMAP_HOOK for exactly this reason
(plugins/cachekey/plugin.cc:114): its remap-time path (TSRemapDoRemap)
covers the per-remap case, and a global instance needs the remapped request
before TSCacheUrlSet is consumed by the lookup.

This is the hook a planned header_rewrite cache-key operator needs, for the
same reason: setting the cache key is only meaningful between remapping and the
cache lookup, and SEND_REQUEST_HDR_HOOK is already too late.

This PR adds a POST_REMAP_HOOK hook condition and wires it end to end:

  • Recognize the POST_REMAP_HOOK keyword in the parser.
  • Handle the POST_REMAP event so rulesets run at that hook.
  • Gather the post-remap request headers for the hook.
  • Allow operators and conditions on the hook.

Covered by a parser unit test and an end-to-end autest.

Add the POST_REMAP_HOOK keyword to the config parser so rulesets can
target the real post-remap hook. Parser-only; runtime wiring follows.
Map the POST_REMAP event in the continuation, gather the post-remap
request headers, and allow operators/conditions on the hook. Enables
the global-plugin deployment model where rules act after remapping.
Adds an end-to-end autest and documents the hook.
@juanthropic
juanthropic marked this pull request as ready for review July 24, 2026 22:45
@JosiahWI JosiahWI added the header_rewrite header_rewrite plugin label Jul 27, 2026
@JosiahWI JosiahWI added this to the 11.0.0 milestone Jul 27, 2026
The earlier wording sold the hook as the window before the origin
request, which SEND_REQUEST_HDR_HOOK already covers. The window that
matters is before the cache lookup, and the gap is specific to global
(plugin.config) rulesets: the read-request hooks run pre-remap,
SEND_REQUEST_HDR_HOOK runs after the lookup and only on a forward to
origin, and REMAP_PSEUDO_HOOK closes the window for remap.config only.
The old test set a header at POST_REMAP and asserted it on the request
forwarded to origin. Swapping the rule to SEND_REQUEST_HDR_HOOK passed
just as well, so the test demonstrated nothing that existing hooks
couldn't already do.

The rule now records the remapped host and echoes it into the client
response, and the replay adds a cache-hit transaction. That combination
pins both properties the hook uniquely provides:

- Fires on a cache hit, where no request goes to origin, so
  SEND_REQUEST_HDR_HOOK never runs.
- Sees the remapped request, so the pre-remap hooks record the wrong
  host.

Verified by rerunning the test with the rule moved to
SEND_REQUEST_HDR_HOOK, READ_REQUEST_HDR_HOOK, and
READ_REQUEST_PRE_REMAP_HOOK; each one fails.

Note %{CLIENT-URL} is the pristine URL by design, so the rule uses
%{URL:HOST} to read the in-flight request.
@cmcfarlen
cmcfarlen requested review from bneradt and zwoop July 27, 2026 22:16

@bneradt bneradt left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Codex had one comment. Otherwise the PR looks good to me.

@bneradt

bneradt commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Adding TS_HTTP_POST_REMAP_HOOK only to Statement::initialize_hooks() does not affect derived operators that override initialize_hooks(). In particular, OperatorSetPluginCntl and OperatorSetStateFlag/Int8/Int16 each say they should be allowed everywhere, but their explicit hook lists omit the new hook. The session-state operators reuse those state classes, so they are affected too.

As a result, a POST_REMAP_HOOK ruleset using set-plugin-cntl, set-state-, or set-session- is rejected during configuration parsing. Could these overrides add TS_HTTP_POST_REMAP_HOOK (or delegate to Statement::initialize_hooks()), with a configuration-level test covering one of these operators?

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.

3 participants