Looking into an integration that was updated from camel v2 to v4, and
having problems with outbound "http" component requests being rejected
downstream due to an invalid *Content-Encoding* field.

The request is including the following header:

*Content-Encoding: us-ascii*


Based on research, this is invalid.  Content-Encoding does not accept
charset names.  The Camel v2 version of the project does not set
Content-Encoding.  No functional changes were made to the route - only
necessary changes to update to v4.

After digging through the Camel code with the debugger and comparing the
original version of the integration and the updated one, I tracked down the
code in HttpProducer that used to set chartset but now sets encoding in the
StringEntity class. Below is a minimal program that reproduces the issue.

*// Sample route that incorrectly generates Content-Encoding: UTF-8*

public static void main(String[] args) {
        org.apache.camel.CamelContext camelContext = new
org.apache.camel.impl.DefaultCamelContext();

        try {
                camelContext.addRoutes(new RouteBuilder() {
                        @Override
                        public void configure() throws Exception {
                                        from("direct:AAA")
                                                
.setProperty(Exchange.CHARSET_NAME, constant("UTF-8"))
                                                
.to("http://localhost:9999/redacted/endpoint/path";)
                                        ;
                                }
                        }
                );

                camelContext.start();
                camelContext.createProducerTemplate().sendBody("direct:AAA", 
"");
                Thread.sleep(2000);
        } catch (Exception e) {
                e.printStackTrace();
        }
}

To test:

1. run *nc -l 0.0.0.0 9999*

2. compile and run that code (I personally used Intellij to run it out of
another class that already had all the necessary dependencies to run it)

3. profit (notice the Content-Encoding header)


*More Details...*

*Camel v2*
Here is a little more detail on the history behind this change:

In httpcore-4.4.15 the following constructor was being used by camel:

public StringEntity(final String string, final String charset)


Note the "charset" argument.  Here is the Camel HttpProducer line that
calls it:

StringEntity entity = new StringEntity((String) data, charset);


*Camel v4*
In httpcore5-5.2.1, the following constructor is not being used by camel:

    public StringEntity(
            final String string, final ContentType contentType, final
String contentEncoding, final boolean chunked) {


Note the lack of a "charset" argument.  Here is the Camel HttpProducer line
that calls it:

answer = new StringEntity(content, contentType, charset, false);


It appears the following commit changed the call to the StringEntity
constructor in HttpProducer:

c33a140ce51aa9bc9a8205429b78e00a39041967


Finding which versions contain that commit:

$ git tag --contains c33a140ce51aa9bc9a8205429b78e00a39041967

camel-4.0.0

camel-4.0.0-M3

camel-4.0.0-RC1

camel-4.0.0-RC2

camel-4.0.1

camel-4.0.2

camel-4.0.3

camel-4.1.0

camel-4.2.0

camel-4.3.0


I would submit a PR to fix it if I knew how to correctly obtain the desired
result - that is, that both the charset and content-encoding are set on the
StringEntity.

Art

Reply via email to