Skip to content

feat: expose inbound request headers to override templates#1520

Merged
looplj merged 1 commit into
looplj:unstablefrom
ttttmr:worktree-request-override-request-header
May 3, 2026
Merged

feat: expose inbound request headers to override templates#1520
looplj merged 1 commit into
looplj:unstablefrom
ttttmr:worktree-request-override-request-header

Conversation

@ttttmr

@ttttmr ttttmr commented Apr 28, 2026

Copy link
Copy Markdown
Contributor

Summary

  • expose .RequestHeader in Request Override template context using filtered inbound client headers
  • support canonical and lowercase header lookups with first-value semantics for body/header overrides
  • add focused tests and concise zh/en doc updates for the new template variable

Test plan

  • go test ./internal/server/orchestrator -run 'TestOverrideParametersWithTemplate|TestOverrideParametersWithRequestHeaderTemplate|TestOverrideParametersWithRequestHeaderTemplate_LowercaseSensitiveHeaders|TestOverrideParametersWithRequestHeaderTemplate_NoRawRequest|TestOverrideHeadersWithRequestHeaderTemplate|TestOverrideHeadersKeepJSONLikeString' -v
  • cd llm && go test ./httpclient -run 'TestMergeHTTPHeaders_BlocksAllHardcodedHeaders|TestMaskSensitiveHeaders_MasksAllHardcodedHeaders|TestHeaderMaps_CanonicalForm' -v

🤖 Generated with Claude Code

Add filtered inbound request headers to the Request Override template context so channels can reuse non-sensitive client headers in body and header overrides. Support canonical and lowercase lookups, keep first-value semantics, and document the behavior in both zh and en guides.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@greptile-apps

greptile-apps Bot commented Apr 28, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR exposes filtered inbound client request headers as .RequestHeader in Go template override contexts, letting operators forward trace IDs and other non-sensitive headers to upstream LLM requests. As a side effect, the refactor of sensitiveHeaders access into IsSensitiveHeader also fixes a pre-existing bug in MergeHTTPHeaders and MaskSensitiveHeaders where non-canonical header keys (e.g., "authorization" instead of "Authorization") were not detected as sensitive.

Confidence Score: 5/5

Safe to merge — sensitive-header filtering is correct, the dual canonical/lowercase storage is sound, and the new helper also fixes a subtle pre-existing case-sensitivity gap in MergeHTTPHeaders and MaskSensitiveHeaders.

All changes are well-tested with five targeted unit tests. Sensitive headers are filtered before exposure via IsSensitiveHeader. The buildRequestHeaderMap dual-key design works correctly because http.CanonicalHeaderKey always produces a mixed-case result distinct from strings.ToLower. No P0/P1 findings.

No files require special attention.

Important Files Changed

Filename Overview
internal/server/orchestrator/override.go Adds RequestHeader field to RenderContext and a new buildRequestHeaderMap helper that filters sensitive headers and stores both canonical and lowercase forms for template lookup flexibility.
llm/httpclient/utils.go Extracts IsSensitiveHeader as an exported helper with canonical-key normalization; uses it in MaskSensitiveHeaders and MergeHTTPHeaders, fixing a subtle pre-existing bug where non-canonical sensitive header keys (e.g., "authorization") were not properly filtered.
internal/server/orchestrator/override_test.go Adds five targeted tests covering canonical/lowercase lookups, multi-value first-value semantics, sensitive-header filtering, nil RawRequest graceful degradation, and header override templates.
docs/en/guides/request-override.md Documents the new .RequestHeader template variable with an example in both the parameter and header override sections.
docs/zh/guides/request-override.md Chinese translation of the same .RequestHeader documentation additions.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[Inbound HTTP Request\nwith raw headers] --> B[buildRequestHeaderMap]
    B --> C{IsSensitiveHeader?}
    C -- yes --> D[Skip header\nauth, api-key, cookie…]
    C -- no --> E[Store canonical key\ne.g. X-Trace-Id → value]
    E --> F[Store lowercase key\ne.g. x-trace-id → value]
    F --> G[RequestHeader map\nin RenderContext]
    G --> H[Go template execution\n{{index .RequestHeader "x-trace-id"}}]
    H --> I1[Body override\noverride_parameters / body_ops]
    H --> I2[Header override\nheader_ops]
Loading

Reviews (1): Last reviewed commit: "feat: expose inbound request headers to ..." | Re-trigger Greptile

@gemini-code-assist gemini-code-assist Bot 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.

Code Review

This pull request adds support for accessing filtered inbound client headers in request override templates via the new .RequestHeader variable. The implementation includes sensitive header filtering and supports both canonical and lowercase key lookups. Documentation and tests have been updated to reflect these changes. A potential nil pointer dereference was identified in the buildRenderContext function which could lead to a panic if the request object is missing.

Comment on lines 60 to 68
func buildRenderContext(llmReq *llm.Request, requestModel string) RenderContext {
return RenderContext{
RequestModel: requestModel,
Model: llmReq.Model,
Metadata: llmReq.Metadata,
RequestHeader: buildRequestHeaderMap(llmReq),
ReasoningEffort: llmReq.ReasoningEffort,
}
}

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.

medium

The buildRenderContext function is susceptible to a nil pointer dereference if llmReq is nil, as it accesses fields like llmReq.Model directly. Although buildRequestHeaderMap (called on line 65) includes a nil check for llmReq, the panic would occur on line 63 before that function is even executed. Given that the nil check exists in the helper, it implies that llmReq might be nil in some execution paths, so this function should be made safe.

func buildRenderContext(llmReq *llm.Request, requestModel string) RenderContext {
	if llmReq == nil {
		return RenderContext{
			RequestModel:  requestModel,
			RequestHeader: make(map[string]string),
		}
	}

	return RenderContext{
		RequestModel:    requestModel,
		Model:           llmReq.Model,
		Metadata:        llmReq.Metadata,
		RequestHeader:   buildRequestHeaderMap(llmReq),
		ReasoningEffort: llmReq.ReasoningEffort,
	}
}

@looplj

looplj commented Apr 28, 2026

Copy link
Copy Markdown
Owner

Inbound request headers 覆盖好像没什么意义吧

@ttttmr

ttttmr commented Apr 28, 2026

Copy link
Copy Markdown
Contributor Author

Inbound request headers 覆盖好像没什么意义吧

目前是用来对齐codex/claude code的session id,从header中取数据对齐到一个header上

@looplj

looplj commented Apr 28, 2026

Copy link
Copy Markdown
Owner

请求覆盖在 trace 生成之后,所以可能用不上

@ttttmr

ttttmr commented Apr 28, 2026

Copy link
Copy Markdown
Contributor Author

可能我们的场景有点特别,axonhub的上游是另一个网关,session id是给上游做cache用的

@looplj looplj merged commit 3a9ffed into looplj:unstable May 3, 2026
4 checks passed
@ttttmr ttttmr deleted the worktree-request-override-request-header branch May 27, 2026 03:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants