CAMEL-6872: camel-netty-http - support optional parameters on Content-Type when extracting charset.
Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/2b3704f9 Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/2b3704f9 Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/2b3704f9 Branch: refs/heads/camel-2.12.x Commit: 2b3704f97dcdd956692646b0e4d4def011eaad54 Parents: 7d94e22 Author: Claus Ibsen <davscl...@apache.org> Authored: Thu Oct 17 20:35:56 2013 +0200 Committer: Claus Ibsen <davscl...@apache.org> Committed: Thu Oct 17 20:36:08 2013 +0200 ---------------------------------------------------------------------- .../camel/component/http/helper/HttpHelper.java | 18 ++++- .../component/jetty/JettyContentExchange.java | 11 ++- .../jetty/JettyHttpContentTypeTest.java | 71 ++++++++++++++++++++ ...pProducerContentTypeEncodingInQuoteTest.java | 38 ++++++++--- .../netty/http/NettyHttpContentTypeTest.java | 4 +- 5 files changed, 129 insertions(+), 13 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/2b3704f9/components/camel-http/src/main/java/org/apache/camel/component/http/helper/HttpHelper.java ---------------------------------------------------------------------- diff --git a/components/camel-http/src/main/java/org/apache/camel/component/http/helper/HttpHelper.java b/components/camel-http/src/main/java/org/apache/camel/component/http/helper/HttpHelper.java index 11d48d5..96ebeef 100644 --- a/components/camel-http/src/main/java/org/apache/camel/component/http/helper/HttpHelper.java +++ b/components/camel-http/src/main/java/org/apache/camel/component/http/helper/HttpHelper.java @@ -66,7 +66,23 @@ public final class HttpHelper { } } } - + + public static String getCharsetFromContentType(String contentType) { + if (contentType != null) { + // find the charset and set it to the Exchange + int index = contentType.indexOf("charset="); + if (index > 0) { + String charset = contentType.substring(index + 8); + // there may be another parameter after a semi colon, so skip that + if (charset.contains(";")) { + charset = ObjectHelper.before(charset, ";"); + } + return IOHelper.normalizeCharset(charset); + } + } + return null; + } + /** * Writes the given object as response body to the servlet response * <p/> http://git-wip-us.apache.org/repos/asf/camel/blob/2b3704f9/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/JettyContentExchange.java ---------------------------------------------------------------------- diff --git a/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/JettyContentExchange.java b/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/JettyContentExchange.java index c9ef129..2440bea 100644 --- a/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/JettyContentExchange.java +++ b/components/camel-jetty/src/main/java/org/apache/camel/component/jetty/JettyContentExchange.java @@ -75,12 +75,21 @@ public class JettyContentExchange extends ContentExchange { if (Exchange.CONTENT_TYPE.equalsIgnoreCase(k)) { String charset = ObjectHelper.after(v, "charset="); if (charset != null) { + // there may be another parameter as well, we only want the charset parameter + String extra = ""; + if (charset.contains(";")) { + extra = ObjectHelper.after(charset, ";"); + charset = ObjectHelper.before(charset, ";"); + } charset = charset.trim(); String s = StringHelper.removeLeadingAndEndingQuotes(charset); if (!charset.equals(s)) { v = ObjectHelper.before(v, "charset=") + "charset=" + s; LOG.debug("Removed quotes from charset in " + Exchange.CONTENT_TYPE + " from {} to {}", charset, s); - + // add extra parameters + if (extra != null) { + v = v + ";" + extra; + } // use a new buffer to adjust the value value = new ByteArrayBuffer.CaseInsensitive(v); } http://git-wip-us.apache.org/repos/asf/camel/blob/2b3704f9/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/JettyHttpContentTypeTest.java ---------------------------------------------------------------------- diff --git a/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/JettyHttpContentTypeTest.java b/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/JettyHttpContentTypeTest.java new file mode 100644 index 0000000..b6e9c9b --- /dev/null +++ b/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/JettyHttpContentTypeTest.java @@ -0,0 +1,71 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.camel.component.jetty; + +import java.nio.charset.Charset; + +import org.apache.camel.Exchange; +import org.apache.camel.builder.RouteBuilder; +import org.junit.Test; + +public class JettyHttpContentTypeTest extends BaseJettyTest { + + @Test + public void testContentType() throws Exception { + getMockEndpoint("mock:input").expectedBodiesReceived("Hello World"); + getMockEndpoint("mock:input").expectedHeaderReceived(Exchange.CONTENT_TYPE, "text/plain; charset=\"iso-8859-1\""); + getMockEndpoint("mock:input").expectedHeaderReceived(Exchange.HTTP_CHARACTER_ENCODING, "iso-8859-1"); + getMockEndpoint("mock:input").expectedHeaderReceived(Exchange.HTTP_URL, "http://0.0.0.0:" + getPort() + "/foo"); + getMockEndpoint("mock:input").expectedPropertyReceived(Exchange.CHARSET_NAME, "iso-8859-1"); + + byte[] data = "Hello World".getBytes(Charset.forName("iso-8859-1")); + String out = template.requestBodyAndHeader("jetty:http://0.0.0.0:{{port}}/foo", data, + "content-type", "text/plain; charset=\"iso-8859-1\"", String.class); + assertEquals("Bye World", out); + + assertMockEndpointsSatisfied(); + } + + @Test + public void testContentTypeWithAction() throws Exception { + getMockEndpoint("mock:input").expectedBodiesReceived("Hello World"); + getMockEndpoint("mock:input").expectedHeaderReceived(Exchange.CONTENT_TYPE, "text/plain;charset=\"iso-8859-1\";action=\"http://somewhere.com/foo\""); + getMockEndpoint("mock:input").expectedHeaderReceived(Exchange.HTTP_CHARACTER_ENCODING, "iso-8859-1"); + getMockEndpoint("mock:input").expectedHeaderReceived(Exchange.HTTP_URL, "http://0.0.0.0:" + getPort() + "/foo"); + getMockEndpoint("mock:input").expectedPropertyReceived(Exchange.CHARSET_NAME, "iso-8859-1"); + + byte[] data = "Hello World".getBytes(Charset.forName("iso-8859-1")); + String out = template.requestBodyAndHeader("jetty:http://0.0.0.0:{{port}}/foo", data, + "content-type", "text/plain;charset=\"iso-8859-1\";action=\"http://somewhere.com/foo\"", String.class); + assertEquals("Bye World", out); + + assertMockEndpointsSatisfied(); + } + + @Override + protected RouteBuilder createRouteBuilder() throws Exception { + return new RouteBuilder() { + @Override + public void configure() throws Exception { + from("jetty:http://0.0.0.0:{{port}}/foo") + .to("mock:input") + .transform().constant("Bye World"); + } + }; + } + +} http://git-wip-us.apache.org/repos/asf/camel/blob/2b3704f9/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/jettyproducer/JettyHttpProducerContentTypeEncodingInQuoteTest.java ---------------------------------------------------------------------- diff --git a/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/jettyproducer/JettyHttpProducerContentTypeEncodingInQuoteTest.java b/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/jettyproducer/JettyHttpProducerContentTypeEncodingInQuoteTest.java index 343da2a..8e83bf29 100644 --- a/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/jettyproducer/JettyHttpProducerContentTypeEncodingInQuoteTest.java +++ b/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/jettyproducer/JettyHttpProducerContentTypeEncodingInQuoteTest.java @@ -52,7 +52,34 @@ public class JettyHttpProducerContentTypeEncodingInQuoteTest extends BaseJettyTe assertEquals("OK", out.getOut().getBody(String.class)); // camel-jetty will remove quotes from charset - assertEquals("text/foo; charset=utf-8", out.getOut().getHeader("Content-Type")); + assertEquals("text/plain;charset=UTF-8", out.getOut().getHeader("Content-Type")); + } + + @Test + public void testHttpProducerEncodingInQuoteAndActionParameterTest() throws Exception { + // these tests do not run well on Windows + if (isPlatform("windows")) { + return; + } + + // give Jetty time to startup properly + Thread.sleep(1000); + + MockEndpoint mock = getMockEndpoint("mock:result"); + mock.expectedMinimumMessageCount(1); + + Exchange out = template.send("jetty:http://localhost:{{port}}/myapp/myservice", new Processor() { + public void process(Exchange exchange) throws Exception { + exchange.getIn().setBody("Hello World"); + exchange.getIn().setHeader("Content-Type", "text/plain;charset=\"utf-8\";action=\"http://somewhere.com/foo\""); + } + }); + + assertMockEndpointsSatisfied(); + + assertEquals("OK", out.getOut().getBody(String.class)); + // camel-jetty will remove quotes from charset + assertEquals("text/plain;charset=utf-8;action=\"http://somewhere.com/foo\"", out.getOut().getHeader("Content-Type")); } @Override @@ -61,14 +88,7 @@ public class JettyHttpProducerContentTypeEncodingInQuoteTest extends BaseJettyTe public void configure() throws Exception { from("jetty:http://localhost:{{port}}/myapp/myservice") .to("mock:result") - .process(new Processor() { - public void process(Exchange exchange) throws Exception { - String body = exchange.getIn().getBody(String.class); - assertEquals("Hello World", body); - assertTrue("Content-Type is not text/plain; charset=\"utf-8\"", exchange.getIn().getHeader("Content-Type").equals("text/plain; charset=\"utf-8\"")); - } - }) - .transform(constant("OK")).setHeader("Content-Type", constant("text/foo; charset=\"utf-8\"")); + .transform(constant("OK")); } }; } http://git-wip-us.apache.org/repos/asf/camel/blob/2b3704f9/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpContentTypeTest.java ---------------------------------------------------------------------- diff --git a/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpContentTypeTest.java b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpContentTypeTest.java index 67f8031..7828856 100644 --- a/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpContentTypeTest.java +++ b/components/camel-netty-http/src/test/java/org/apache/camel/component/netty/http/NettyHttpContentTypeTest.java @@ -43,14 +43,14 @@ public class NettyHttpContentTypeTest extends BaseNettyTest { @Test public void testContentTypeWithAction() throws Exception { getMockEndpoint("mock:input").expectedBodiesReceived("Hello World"); - getMockEndpoint("mock:input").expectedHeaderReceived(Exchange.CONTENT_TYPE, "text/plain;charset=\"iso-8859-1\";action=\"http://somewhere.com/foo"); + getMockEndpoint("mock:input").expectedHeaderReceived(Exchange.CONTENT_TYPE, "text/plain;charset=\"iso-8859-1\";action=\"http://somewhere.com/foo\""); getMockEndpoint("mock:input").expectedHeaderReceived(Exchange.HTTP_CHARACTER_ENCODING, "iso-8859-1"); getMockEndpoint("mock:input").expectedHeaderReceived(Exchange.HTTP_URL, "http://0.0.0.0:" + getPort() + "/foo"); getMockEndpoint("mock:input").expectedPropertyReceived(Exchange.CHARSET_NAME, "iso-8859-1"); byte[] data = "Hello World".getBytes(Charset.forName("iso-8859-1")); String out = template.requestBodyAndHeader("netty-http:http://0.0.0.0:{{port}}/foo", data, - "content-type", "text/plain;charset=\"iso-8859-1\";action=\"http://somewhere.com/foo", String.class); + "content-type", "text/plain;charset=\"iso-8859-1\";action=\"http://somewhere.com/foo\"", String.class); assertEquals("Bye World", out); assertMockEndpointsSatisfied();