[ 
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)

Reply via email to