[
https://issues.apache.org/jira/browse/CAMEL-25316?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
]
Claus Ibsen updated CAMEL-25316:
--------------------------------
Fix Version/s: 4.23.0
> camel-http-common - a String response is written in the exchange charset
> while the Content-Type declares another charset (servlet and Jetty consumers,
> chunked by default)
> --------------------------------------------------------------------------------------------------------------------------------------------------------------------------
>
> Key: CAMEL-25316
> URL: https://issues.apache.org/jira/browse/CAMEL-25316
> Project: Camel
> Issue Type: Bug
> Components: camel-http-common, camel-jetty, camel-servlet
> Reporter: shashank
> Priority: Minor
> Fix For: 4.23.0
>
>
> {{DefaultHttpBinding.doWriteDirectResponse}} sets the response
> {{Content-Type}} as the route declares it, and then writes the body through
> an input stream:
> {code:java}
> if (checkChunked(message, exchange)) { // chunked=true is the
> default
> is = message.getBody(InputStream.class);
> } else if (!isText(contentType)) { // for example
> application/json
> is =
> exchange.getContext().getTypeConverter().tryConvertTo(InputStream.class,
> message.getBody());
> }
> {code}
> A {{String}} body is converted with the charset of the exchange, which for a
> servlet or Jetty consumer is the charset of the request, UTF-8 when the
> request names none (every GET). So a route that answers with {{text/plain;
> charset=ISO-8859-1}} (or {{application/json; charset=ISO-8859-1}} without
> chunking) sends UTF-8 bytes under an ISO-8859-1 header, and the client reads
> {{GrüÃe}} instead of {{Grüße}}. Only the non-chunked text path writes the
> body and the header in one charset (it replaces the declared charset with the
> exchange charset).
> h3. Reproduction
> New {{ServletStringResponseCharsetTest}} (camel-servlet, embedded Undertow):
> a chunked {{text/plain; charset=ISO-8859-1}} response and a non-chunked
> {{application/json; charset=ISO-8859-1}} response with {{Grüße aus Köln}},
> decoded with the charset of the response header: both fail on main
> ({{expected: <Grüße aus Köln> but was: <GrüÃe aus Köln>}}), in two runs;
> the non-chunked {{text/plain}} response is the control and passes.
> h3. Proposed fix
> When the body is a {{String}} and the Content-Type declares a supported
> charset (parameter name matched case-insensitively, RFC 9110 5.6.6), convert
> it with that charset in the two stream paths. Responses without a declared
> charset, bodies that are not a {{String}}, and the non-chunked text path are
> unchanged. Not changed either: a gzip-encoded response ({{Content-Encoding:
> gzip}}, {{doWriteGZIPResponse}}) still converts a {{String}} body with the
> exchange charset; it can follow the same way if wanted. Upgrade guide entry,
> as for CAMEL-25217 and CAMEL-25248. With the fix: camel-http-common,
> camel-servlet (105 tests) and camel-jetty (395 tests;
> {{JettyXsltHttpTemplateTest}} fails on this machine with and without the
> change, {{0.0.0.0}} binding) pass.
> Found with a Lean 4 model of the four write paths: the property "the bytes
> are in the charset that the response header names" fails on main for the
> chunked and the non-text paths for every text with a character outside
> US-ASCII (declared ISO-8859-1, UTF-8 exchange), and holds for the fix in all
> four paths; the fix equals main when the declared charset is the exchange
> charset and in the non-chunked text path. The model abstracts the parsing of
> the Content-Type (case, quotes) and the fallback for an unsupported charset
> name; those are covered by reading the code only.
> Affected: 4.14.x, 4.18.x and main (same code).
> Priority Minor, as for CAMEL-25217 and CAMEL-25248: the default (chunked)
> configuration is affected, but only a route that declares a charset other
> than the exchange charset (UTF-8 for a GET) sees it, and the client gets the
> right text in the wrong charset (wrong characters, no lost or truncated body).
> Duplicate check (2026-10-04): JIRA components camel-servlet / camel-jetty /
> camel-http-common with charset or encoding (36 issues, CAMEL-3443 and
> CAMEL-12424 are about the request), "DefaultHttpBinding" with charset or
> chunked: none on this. GitHub pull requests "DefaultHttpBinding charset",
> "servlet response charset": none.
> _Filed with Claude Code on behalf of allthingssecurity._
--
This message was sent by Atlassian Jira
(v8.20.10#820010)