[ 
https://issues.apache.org/jira/browse/CAMEL-25526?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

shashank updated CAMEL-25526:
-----------------------------
    Description: 
{{DefaultVertxHttpBinding.populateRequestHeaders}} (lines 120-148 at main 
586855a18315) copies each message header to the request with {{headers.set(key, 
tc.convertTo(String.class, headerValue))}}. For a header whose value is a 
collection, the String conversion is {{toString()}}, so {{List.of("a", "b")}} 
is sent as the single header line {{X-Test: [a, b]}}; a {{String[]}} is sent as 
{{[Ljava.lang.String;@7112ce6}}. The HTTP consumers (platform-http, undertow, 
servlet, netty-http, vertx-http's own responses) map a request header that 
occurs more than once to a List, so a route that forwards such a request with 
vertx-http (a proxy, or HTTP/2 clients that send each cookie in its own 
{{cookie}} header) sends corrupted header values, without any error.

camel-http ({{HttpProducer}}), camel-netty-http and camel-undertow iterate the 
values with {{ObjectHelper.createIterator(value, null, true)}} and 
{{HttpUtil.applyHeader}} and send one header line per value, and a String as 
one value.

h3. Reproduction

New {{VertxHttpMultiValueHeaderTest}} (undertow test server as in the other 
tests, which echoes the values of {{X-Test}} it receives, joined with {{|}} 
when there are several): on main two of the three tests fail, twice:
{noformat}
sendsEachValueOfAListHeader: expected: <a|b> but was: <[a, b]>
sendsEachValueOfAnArrayHeader: expected: <a|b> but was: 
<[Ljava.lang.String;@7112ce6>
{noformat}
The third test checks that a String with a comma ({{"a, b"}}) is still sent as 
one value (it passes before and after, and guards the "no delimiter" choice of 
the fix).

h3. Proposed fix

Iterate the header value as camel-http does 
({{ObjectHelper.createIterator(headerValue, null, true)}} with 
{{HttpUtil.applyHeader}}, which applies the header filter per value and skips 
null values) and set all the values of the header. A String or any other single 
value is sent as before. 4.23 upgrade guide note added (a collection or array 
header now gives one header line per value). camel-vertx-http tests with the 
fix: 100, 0 failures (1 skipped, as on main).

Found with a Lean 4 model of the header copy (a value is a String or a list of 
Strings): "a header is sent as one line per value" (camel-http) fails for 
{{["a", "b"]}}, and main is proved to be wrong for every list value (also a 
one-element list, sent as {{[a]}}). The fix is proved to equal camel-http's 
behaviour for every value and to send the same line as main for every String. 
Confirmed with the real producer.

Not changed here: {{KnativeHttpProducer}} of camel-knative-http has the same 
{{toString()}} copy of the request headers (the reply headers of 
{{KnativeHttpConsumer}} already iterate the values).

Affected: main, camel-4.22.x, camel-4.18.x, camel-4.14.x (same code, GitHub 
contents API).

Duplicate check (2026-10-10): JIRA text "vertx-http" and "header" (44, none 
about multi-value headers; CAMEL-24424 was the REST header filter direction); 
GitHub pull requests "vertx-http header multiple values" (none). No open pull 
request changes {{DefaultVertxHttpBinding}}.

_Filed with Claude Code on behalf of allthingssecurity._


  was:
{{DefaultVertxHttpBinding.populateRequestHeaders}} (lines 120-148 at main 
586855a18315) copies each message header to the request with {{headers.set(key, 
tc.convertTo(String.class, headerValue))}}. For a header whose value is a 
collection, the String conversion is {{toString()}}, so {{List.of("a", "b")}} 
is sent as the single header line {{X-Test: [a, b]}}; a {{String[]}} is sent as 
{{[Ljava.lang.String;@7112ce6}}. The HTTP consumers (platform-http, undertow, 
servlet, netty-http, vertx-http's own responses) map a request header that 
occurs more than once to a List, so a route that forwards such a request with 
vertx-http (a proxy, or HTTP/2 clients that send each cookie in its own 
{{cookie}} header) sends corrupted header values, without any error.

camel-http ({{HttpProducer}}), camel-netty-http and camel-undertow iterate the 
values with {{ObjectHelper.createIterator(value, null, true)}} and 
{{HttpUtil.applyHeader}} and send one header line per value, and a String as 
one value.

h3. Reproduction

New {{VertxHttpMultiValueHeaderTest}} (undertow test server as in the other 
tests, which echoes the values of {{X-Test}} it receives, joined with {{|}} 
when there are several): on main two of the three tests fail, twice:
{noformat}
sendsEachValueOfAListHeader: expected: <a|b> but was: <[a, b]>
sendsEachValueOfAnArrayHeader: expected: <a|b> but was: 
<[Ljava.lang.String;@7112ce6>
{noformat}
The third test checks that a String with a comma ({{"a, b"}}) is still sent as 
one value (it passes before and after, and guards the "no delimiter" choice of 
the fix).

h3. Proposed fix

Iterate the header value as camel-http does 
({{ObjectHelper.createIterator(headerValue, null, true)}} with 
{{HttpUtil.applyHeader}}, which applies the header filter per value and skips 
null values) and set all the values of the header. A String or any other single 
value is sent as before. 4.23 upgrade guide note added (a collection or array 
header now gives one header line per value). camel-vertx-http tests with the 
fix: 100, 0 failures (1 skipped, as on main).

Found with a Lean 4 model of the header copy (a value is a String or a list of 
Strings): "a header is sent as one line per value" (camel-http) fails for 
{{["a", "b"]}}, and main is proved to be wrong for every list value (also a 
one-element list, sent as {{[a]}}). The fix is proved to equal camel-http's 
behaviour for every value and to send the same line as main for every String. 
Confirmed with the real producer.

Not changed here: camel-knative-http has the same {{toString()}} copy in 
{{KnativeHttpProducer}} and in the reply headers of {{KnativeHttpConsumer}}.

Affected: main, camel-4.22.x, camel-4.18.x, camel-4.14.x (same code, GitHub 
contents API).

Duplicate check (2026-10-10): JIRA text "vertx-http" and "header" (44, none 
about multi-value headers; CAMEL-24424 was the REST header filter direction); 
GitHub pull requests "vertx-http header multiple values" (none). No open pull 
request changes {{DefaultVertxHttpBinding}}.

_Filed with Claude Code on behalf of allthingssecurity._



> camel-vertx-http - a header with several values (a List or an array, such as 
> a repeated request header) is sent as one header with the value "[a, b]"
> -----------------------------------------------------------------------------------------------------------------------------------------------------
>
>                 Key: CAMEL-25526
>                 URL: https://issues.apache.org/jira/browse/CAMEL-25526
>             Project: Camel
>          Issue Type: Bug
>          Components: camel-vertx-http
>            Reporter: shashank
>            Assignee: shashank
>            Priority: Major
>
> {{DefaultVertxHttpBinding.populateRequestHeaders}} (lines 120-148 at main 
> 586855a18315) copies each message header to the request with 
> {{headers.set(key, tc.convertTo(String.class, headerValue))}}. For a header 
> whose value is a collection, the String conversion is {{toString()}}, so 
> {{List.of("a", "b")}} is sent as the single header line {{X-Test: [a, b]}}; a 
> {{String[]}} is sent as {{[Ljava.lang.String;@7112ce6}}. The HTTP consumers 
> (platform-http, undertow, servlet, netty-http, vertx-http's own responses) 
> map a request header that occurs more than once to a List, so a route that 
> forwards such a request with vertx-http (a proxy, or HTTP/2 clients that send 
> each cookie in its own {{cookie}} header) sends corrupted header values, 
> without any error.
> camel-http ({{HttpProducer}}), camel-netty-http and camel-undertow iterate 
> the values with {{ObjectHelper.createIterator(value, null, true)}} and 
> {{HttpUtil.applyHeader}} and send one header line per value, and a String as 
> one value.
> h3. Reproduction
> New {{VertxHttpMultiValueHeaderTest}} (undertow test server as in the other 
> tests, which echoes the values of {{X-Test}} it receives, joined with {{|}} 
> when there are several): on main two of the three tests fail, twice:
> {noformat}
> sendsEachValueOfAListHeader: expected: <a|b> but was: <[a, b]>
> sendsEachValueOfAnArrayHeader: expected: <a|b> but was: 
> <[Ljava.lang.String;@7112ce6>
> {noformat}
> The third test checks that a String with a comma ({{"a, b"}}) is still sent 
> as one value (it passes before and after, and guards the "no delimiter" 
> choice of the fix).
> h3. Proposed fix
> Iterate the header value as camel-http does 
> ({{ObjectHelper.createIterator(headerValue, null, true)}} with 
> {{HttpUtil.applyHeader}}, which applies the header filter per value and skips 
> null values) and set all the values of the header. A String or any other 
> single value is sent as before. 4.23 upgrade guide note added (a collection 
> or array header now gives one header line per value). camel-vertx-http tests 
> with the fix: 100, 0 failures (1 skipped, as on main).
> Found with a Lean 4 model of the header copy (a value is a String or a list 
> of Strings): "a header is sent as one line per value" (camel-http) fails for 
> {{["a", "b"]}}, and main is proved to be wrong for every list value (also a 
> one-element list, sent as {{[a]}}). The fix is proved to equal camel-http's 
> behaviour for every value and to send the same line as main for every String. 
> Confirmed with the real producer.
> Not changed here: {{KnativeHttpProducer}} of camel-knative-http has the same 
> {{toString()}} copy of the request headers (the reply headers of 
> {{KnativeHttpConsumer}} already iterate the values).
> Affected: main, camel-4.22.x, camel-4.18.x, camel-4.14.x (same code, GitHub 
> contents API).
> Duplicate check (2026-10-10): JIRA text "vertx-http" and "header" (44, none 
> about multi-value headers; CAMEL-24424 was the REST header filter direction); 
> GitHub pull requests "vertx-http header multiple values" (none). No open pull 
> request changes {{DefaultVertxHttpBinding}}.
> _Filed with Claude Code on behalf of allthingssecurity._



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to