shashank created CAMEL-25457:
--------------------------------
Summary: camel-http-common - a non-chunked text String response
replaces the charset that the Content-Type declares with the exchange charset
Key: CAMEL-25457
URL: https://issues.apache.org/jira/browse/CAMEL-25457
Project: Camel
Issue Type: Bug
Components: camel-http-common
Reporter: shashank
{{DefaultHttpBinding.doWriteDirectResponse}} (camel-http-common, used by
camel-servlet and camel-jetty) writes a {{String}} response body that is not
chunked ({{chunked=false}} or the {{CamelHttpChunked}} header) and has a text
{{Content-Type}} ({{isText}}: the type contains {{text}} or {{html}}) through
the fallback at the end of the method (main 7514fbc164da, lines 572-579):
{code:java}
String charset = ExchangeHelper.getCharsetName(exchange, true);
final int dataByteLength = data.getBytes(charset).length;
response.setCharacterEncoding(charset);
response.setContentLength(dataByteLength);
{code}
{{response.setCharacterEncoding}} replaces the charset of the {{Content-Type}}
that {{writeResponse}} set from the message. So a route that sets
{{Content-Type: text/plain; charset=ISO-8859-1}} sends
{{text/plain;charset=UTF-8}} (the charset of the exchange: the request charset,
else UTF-8). The body and the header agree (this path was made consistent for
the Content-Length in CAMEL-5265), so a client decodes the text correctly, but
the charset the route declared is ignored. The chunked and non-text paths write
a {{String}} body in the declared charset with CAMEL-25316 (PR #27392), so
after that change this is the only path that does not honour it. Raised by
Claus Ibsen in the review of #27392.
h3. Reproduction
A servlet route
{{from("servlet:/notChunked?chunked=false").setHeader(Exchange.CONTENT_TYPE,
constant("text/plain; charset=ISO-8859-1")).setBody(constant("Grüße aus
Köln"))}}; the test asserts the response {{Content-Type}}. On main: {{expected:
<text/plain; charset=ISO-8859-1> but was: <text/plain;charset=UTF-8>}}.
h3. Proposed fix
In the fallback, use the charset that the {{Content-Type}} declares when it is
supported (the same parsing as CAMEL-25316), else the exchange charset as
today, for both the byte length and {{setCharacterEncoding}}. A response
without a declared charset is unchanged. Behaviour change for the upgrade
guide: such a response is sent in the declared charset instead of the exchange
charset (characters the declared charset cannot represent become {{?}}), as the
other paths do after CAMEL-25316. #27392 is merged; a fix with a servlet test
is ready.
Found in the review of CAMEL-25316 and confirmed with a servlet test on main.
Affected: main (same code in 4.18.x and 4.22.x, not checked separately).
Duplicate check (2026-10-06): JIRA text "DefaultHttpBinding" and "charset" (5:
CAMEL-25316 and CAMEL-25248, which fix other paths and components; CAMEL-25355
is the empty charset parameter; CAMEL-4871 and CAMEL-2981 are request
parameters), "setCharacterEncoding" (CAMEL-25248 only), components
camel-servlet / camel-http-common / camel-jetty with "Content-Type charset
response" (CAMEL-5265 is the Content-Length of this path, fixed in 2012).
GitHub pull requests "DefaultHttpBinding": none for this path (#27392 and
#27397 are ours, other paths).
_Filed with Claude Code on behalf of allthingssecurity._
--
This message was sent by Atlassian Jira
(v8.20.10#820010)