Skip to content

feat(proxy-rewrite): support multiple same-name headers in headers.add/set#13597

Draft
AlinsRan wants to merge 2 commits into
apache:masterfrom
AlinsRan:feat/13163-multi-value-headers
Draft

feat(proxy-rewrite): support multiple same-name headers in headers.add/set#13597
AlinsRan wants to merge 2 commits into
apache:masterfrom
AlinsRan:feat/13163-multi-value-headers

Conversation

@AlinsRan

Copy link
Copy Markdown
Contributor

Description

Allow headers.set and headers.add values in proxy-rewrite to be an array, producing multiple headers with the same name:

"proxy-rewrite": {
  "headers": {
    "set": { "X-Api-Version": ["v1", "v2"] }
  }
}
  • set with an array replaces any incoming header with the listed values.
  • add with an array appends the listed values to the existing ones.
  • remove is unchanged (it already takes an array of names).

Why

proxy-rewrite models headers.add/set as a JSON object (map), which structurally cannot express same-name multi-value headers — a JSON object can't hold two values for one key. This is a real gap vs. other gateways that model header transforms as an ordered list of (name, value) pairs (Kong request-transformer append.headers, Envoy request_headers_to_add, HAProxy add-header). The array form closes it. Genuine use cases: gRPC metadata (repeated keys → repeated HTTP/2 headers) and backends/auth proxies that read repeated custom headers.

Fully backward compatible: existing string/number values keep working; the array is an additive schema option. Each element still supports NGINX variables and regex_uri captures.

This also gives the clean answer to the remove + add ordering confusion in #11587 — multi-value is a data-model feature, not an operation-order one.

Which issue(s) this PR fixes

Closes #13163

Changes

  • apisix/plugins/proxy-rewrite.lua: schema allows array<string|number> for add/set values; apply loop resolves each element (set → one set_header with a table; add → one add_header per element).
  • t/plugin/proxy-rewrite.t: tests for set (replace with multiple) and add (append multiple); t/lib/server.lua: echo helper joining same-name headers.
  • docs/{en,zh}/.../proxy-rewrite.md: attribute docs + example.

Checklist

  • I have explained the need for this PR and the problem it solves
  • I have explained the changes or the new features added to this PR
  • I have added tests corresponding to this change
  • I have updated the documentation to reflect this change
  • I have verified that this change is backward compatible (if not, please discuss on the APISIX mailing list first)

AlinsRan added 2 commits June 23, 2026 12:02
Allow headers.set and headers.add values to be an array (e.g.
"foo": ["v1", "v2"]), producing multiple headers with the same name:
- set replaces any incoming header with the listed values;
- add appends the listed values to the existing ones.

The map-based headers schema previously could not express same-name
multi-value headers (a JSON object can't hold two values for one key);
the array form closes that gap. remove is unchanged (it already takes an
array of names). Backward compatible: string/number values keep working.

Closes apache#13163
The echo helper joined same-name headers with ", ", so the assertions
("x-multi: val1, val2") could not tell a genuine multi-header result apart
from a single comma-joined value. Emit one line per header occurrence and
assert the repeated "x-multi: ..." lines, so the test actually proves that
set/add with an array produces multiple headers with the same name.
@AlinsRan AlinsRan changed the title feat(proxy-rewrite): support multiple values for set/add headers feat(proxy-rewrite): support multiple same-name headers in headers.add/set Jun 24, 2026
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.

bug: proxy-rewrite silently drops duplicate keys in headers.add due to JSON object limitation

1 participant