Author: ningjiang Date: Wed Apr 28 02:33:35 2010 New Revision: 938751 URL: http://svn.apache.org/viewvc?rev=938751&view=rev Log: CAMEL-2676 CAMEL-2679 Made camel-http support better for character encoding and from url encoding data
Added: camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/HttpBindingPreservePostFormUrlEncodedBodyTest.java (with props) camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/HttpCharacterEncodingTest.java (with props) Modified: camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/DefaultHttpBinding.java camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/HttpProducer.java camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/HttpClientRouteEnableChunkedTest.java camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/HttpProducerConcurrentTest.java camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/HttpToFileTest.java camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/JettyEnableJmxTest.java camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/JettyHttpEndpointDisconnectTest.java Modified: camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/DefaultHttpBinding.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/DefaultHttpBinding.java?rev=938751&r1=938750&r2=938751&view=diff ============================================================================== --- camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/DefaultHttpBinding.java (original) +++ camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/DefaultHttpBinding.java Wed Apr 28 02:33:35 2010 @@ -20,6 +20,8 @@ import java.io.File; import java.io.IOException; import java.io.InputStream; import java.io.PrintWriter; +import java.io.UnsupportedEncodingException; +import java.net.URLDecoder; import java.util.Enumeration; import java.util.Map; @@ -34,7 +36,9 @@ import org.apache.camel.Endpoint; import org.apache.camel.Exchange; import org.apache.camel.InvalidPayloadException; import org.apache.camel.Message; +import org.apache.camel.StreamCache; import org.apache.camel.component.http.helper.GZIPHelper; +import org.apache.camel.converter.stream.CachedOutputStream; import org.apache.camel.spi.HeaderFilterStrategy; import org.apache.camel.util.IOHelper; import org.apache.camel.util.MessageHelper; @@ -58,7 +62,7 @@ public class DefaultHttpBinding implemen } public void readRequest(HttpServletRequest request, HttpMessage message) { - + // lets force a parse of the body and headers message.getBody(); // populate the headers from the request @@ -78,8 +82,17 @@ public class DefaultHttpBinding implemen headers.put(name, value); } } + + if (request.getCharacterEncoding() != null) { + headers.put(Exchange.HTTP_CHARACTER_ENCODING, request.getCharacterEncoding()); + message.getExchange().setProperty(Exchange.CHARSET_NAME, request.getCharacterEncoding()); + } - popluateRequestParameters(request, message); + popluateRequestParameters(request, message); + + // reset the stream cache + StreamCache cache = message.getBody(StreamCache.class); + cache.reset(); // store the method and query and other info in headers headers.put(Exchange.HTTP_METHOD, request.getMethod()); @@ -88,7 +101,6 @@ public class DefaultHttpBinding implemen headers.put(Exchange.HTTP_URI, request.getRequestURI()); headers.put(Exchange.HTTP_PATH, request.getPathInfo()); headers.put(Exchange.CONTENT_TYPE, request.getContentType()); - headers.put(Exchange.HTTP_CHARACTER_ENCODING, request.getCharacterEncoding()); popluateAttachments(request, message); } @@ -105,6 +117,29 @@ public class DefaultHttpBinding implemen headers.put(name, value); } } + + if (request.getMethod().equals("POST") && request.getContentType() != null && request.getContentType().equals("application/x-www-form-urlencoded")) { + String charset = request.getCharacterEncoding(); + if (charset == null) { + charset = "UTF-8"; + } + // Push POST form params into the headers to retain compatibility with DefaultHttpBinding + String body = message.getBody(String.class); + try { + for (String param : body.split("&")) { + String[] pair = param.split("=", 2); + String name = URLDecoder.decode(pair[0], charset); + String value = URLDecoder.decode(pair[1], charset); + if (headerFilterStrategy != null + && !headerFilterStrategy.applyFilterToExternalHeaders(name, value, message.getExchange())) { + headers.put(name, value); + } + } + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); + } + } + } protected void popluateAttachments(HttpServletRequest request, HttpMessage message) { @@ -271,8 +306,16 @@ public class DefaultHttpBinding implemen if (isUseReaderForPayload()) { return request.getReader(); } else { - // otherwise use input stream - return HttpConverter.toInputStream(request); + // otherwise use input stream and we need to cache it first + InputStream is = HttpConverter.toInputStream(request); + try { + CachedOutputStream cos = new CachedOutputStream(httpMessage.getExchange()); + IOHelper.copy(is, cos); + return cos.getStreamCache(); + } finally { + is.close(); + } + } } Modified: camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/HttpProducer.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/HttpProducer.java?rev=938751&r1=938750&r2=938751&view=diff ============================================================================== --- camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/HttpProducer.java (original) +++ camel/trunk/components/camel-http/src/main/java/org/apache/camel/component/http/HttpProducer.java Wed Apr 28 02:33:35 2010 @@ -195,10 +195,21 @@ public class HttpProducer extends Defaul return null; } - Header header = method.getRequestHeader(Exchange.CONTENT_ENCODING); + Header header = method.getRequestHeader(Exchange.CONTENT_ENCODING); String contentEncoding = header != null ? header.getValue() : null; - + is = GZIPHelper.toGZIPInputStream(contentEncoding, is); + // Honor the character encoding + header = method.getResponseHeader("content-type"); + if (header != null) { + String contentType = header.getValue(); + // find the charset and set it to the Exchange + int index = contentType.indexOf("charset="); + if (index > 0) { + String charset = contentType.substring(index + 8); + exchange.setProperty(Exchange.CHARSET_NAME, charset); + } + } return doExtractResponseBody(is, exchange); } Added: camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/HttpBindingPreservePostFormUrlEncodedBodyTest.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/HttpBindingPreservePostFormUrlEncodedBodyTest.java?rev=938751&view=auto ============================================================================== --- camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/HttpBindingPreservePostFormUrlEncodedBodyTest.java (added) +++ camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/HttpBindingPreservePostFormUrlEncodedBodyTest.java Wed Apr 28 02:33:35 2010 @@ -0,0 +1,67 @@ +/** + * 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 org.apache.camel.Exchange; +import org.apache.camel.Processor; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.jetty.HttpCharacterEncodingTest.MyBookService; +import org.apache.camel.test.junit4.CamelTestSupport; +import org.junit.Test; + +public class HttpBindingPreservePostFormUrlEncodedBodyTest extends CamelTestSupport { + + @Test + public void testSendToJetty() throws Exception { + Exchange exchange = template.send("http://localhost:9080/myapp/myservice", new Processor() { + + public void process(Exchange exchange) throws Exception { + exchange.getIn().setBody("b1=x&b2=y"); + exchange.getIn().setHeader("content-type", "application/x-www-form-urlencoded"); + } + + }); + // convert the response to a String + String body = exchange.getOut().getBody(String.class); + assertEquals("Request message is OK", body); + } + + @Override + protected RouteBuilder createRouteBuilder() throws Exception { + return new RouteBuilder() { + public void configure() throws Exception { + from("jetty:http://localhost:9080/myapp/myservice").process(new Processor() { + + public void process(Exchange exchange) throws Exception { + String body = exchange.getIn().getBody(String.class); + + // for unit testing make sure we got right message + assertEquals("The body message is wrong", "b1=x&b2=y", body); + assertEquals("Get a wrong message header", exchange.getIn().getHeader("b1"), "x"); + assertEquals("Get a wrong message header", exchange.getIn().getHeader("b2"), "y"); + + // send a response + exchange.getOut().setBody("Request message is OK"); + + } + + }); + } + }; + } + +} Propchange: camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/HttpBindingPreservePostFormUrlEncodedBodyTest.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/HttpBindingPreservePostFormUrlEncodedBodyTest.java ------------------------------------------------------------------------------ svn:keywords = Rev Date Added: camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/HttpCharacterEncodingTest.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/HttpCharacterEncodingTest.java?rev=938751&view=auto ============================================================================== --- camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/HttpCharacterEncodingTest.java (added) +++ camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/HttpCharacterEncodingTest.java Wed Apr 28 02:33:35 2010 @@ -0,0 +1,69 @@ +/** + * 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 javax.servlet.http.HttpServletRequest; + +import org.apache.camel.Exchange; +import org.apache.camel.Processor; +import org.apache.camel.builder.RouteBuilder; +import org.apache.camel.component.jetty.JettyRouteTest.MyBookService; +import org.apache.camel.test.junit4.CamelTestSupport; +import org.junit.Test; + +public class HttpCharacterEncodingTest extends CamelTestSupport { + + @Test + public void testSendToJetty() throws Exception { + Exchange exchange = template.send("http://localhost:9080/myapp/myservice", new Processor() { + + public void process(Exchange exchange) throws Exception { + exchange.getIn().setBody("Hello World Thai Elephant \u0E08"); + exchange.getIn().setHeader("Content-Type", "text/html; charset=utf-8"); + } + + }); + // convert the response to a String + String body = exchange.getOut().getBody(String.class); + assertEquals("Response message is Thai Elephant \u0E08", body); + } + + @Override + protected RouteBuilder createRouteBuilder() throws Exception { + return new RouteBuilder() { + public void configure() throws Exception { + from("jetty:http://localhost:9080/myapp/myservice").process(new MyBookService()); + } + }; + } + + + public class MyBookService implements Processor { + public void process(Exchange exchange) throws Exception { + // just get the body as a string + String body = exchange.getIn().getBody(String.class); + + // for unit testing make sure we got right message + assertEquals("Hello World Thai Elephant \u0E08", body); + + // send a html response + exchange.getOut().setHeader("Content-Type", "text/html; charset=utf-8"); + exchange.getOut().setBody("Response message is Thai Elephant \u0E08"); + } + } + +} Propchange: camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/HttpCharacterEncodingTest.java ------------------------------------------------------------------------------ svn:eol-style = native Propchange: camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/HttpCharacterEncodingTest.java ------------------------------------------------------------------------------ svn:keywords = Rev Date Modified: camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/HttpClientRouteEnableChunkedTest.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/HttpClientRouteEnableChunkedTest.java?rev=938751&r1=938750&r2=938751&view=diff ============================================================================== --- camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/HttpClientRouteEnableChunkedTest.java (original) +++ camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/HttpClientRouteEnableChunkedTest.java Wed Apr 28 02:33:35 2010 @@ -69,12 +69,6 @@ public class HttpClientRouteEnableChunke return new RouteBuilder() { public void configure() { errorHandler(noErrorHandler()); - - Processor clientProc = new Processor() { - public void process(Exchange exchange) throws Exception { - assertIsInstanceOf(InputStream.class, exchange.getIn().getBody()); - } - }; from("direct:start2").to("http://localhost:9081/hello").to("mock:a"); Modified: camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/HttpProducerConcurrentTest.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/HttpProducerConcurrentTest.java?rev=938751&r1=938750&r2=938751&view=diff ============================================================================== --- camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/HttpProducerConcurrentTest.java (original) +++ camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/HttpProducerConcurrentTest.java Wed Apr 28 02:33:35 2010 @@ -51,7 +51,7 @@ public class HttpProducerConcurrentTest getMockEndpoint("mock:result").assertNoDuplicates(body()); ExecutorService executor = Executors.newFixedThreadPool(poolSize); - Map<Integer, Future> responses = new ConcurrentHashMap(); + Map<Integer, Future> responses = new ConcurrentHashMap<Integer, Future>(); for (int i = 0; i < files; i++) { final int index = i; Future out = executor.submit(new Callable<Object>() { @@ -67,7 +67,7 @@ public class HttpProducerConcurrentTest assertEquals(files, responses.size()); // get all responses - Set unique = new HashSet(); + Set<Object> unique = new HashSet<Object>(); for (Future future : responses.values()) { unique.add(future.get()); } Modified: camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/HttpToFileTest.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/HttpToFileTest.java?rev=938751&r1=938750&r2=938751&view=diff ============================================================================== --- camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/HttpToFileTest.java (original) +++ camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/HttpToFileTest.java Wed Apr 28 02:33:35 2010 @@ -27,7 +27,7 @@ import org.junit.Before; import org.junit.Test; /** - * Unit testing demonstrating how to store incomming requests as files and serving a reponse back. + * Unit testing demonstrating how to store incoming requests as files and serving a reponse back. */ public class HttpToFileTest extends CamelTestSupport { @@ -50,7 +50,7 @@ public class HttpToFileTest extends Came file = file.getAbsoluteFile(); assertTrue("File should exists", file.exists()); - String content = IOConverter.toString(file); + String content = IOConverter.toString(file, null); assertEquals("File content", "Hello World", content); } Modified: camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/JettyEnableJmxTest.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/JettyEnableJmxTest.java?rev=938751&r1=938750&r2=938751&view=diff ============================================================================== --- camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/JettyEnableJmxTest.java (original) +++ camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/JettyEnableJmxTest.java Wed Apr 28 02:33:35 2010 @@ -59,6 +59,7 @@ public class JettyEnableJmxTest extends mbsc = getMBeanConnection(); } + @SuppressWarnings("unchecked") @Test public void testEnableJmxProperty() throws Exception { MockEndpoint mock = getMockEndpoint("mock:result"); @@ -77,6 +78,7 @@ public class JettyEnableJmxTest extends assertEquals("Could not find 2 Jetty Server: " + s, 2, s.size()); } + @SuppressWarnings("unchecked") @Test public void testShutdown() throws Exception { Set<ObjectName> s = mbsc.queryNames(new ObjectName("org.eclipse.jetty.server:type=server,*"), null); @@ -88,6 +90,7 @@ public class JettyEnableJmxTest extends assertEquals("Could not find 0 Jetty Server: " + s, 0, s.size()); } + @SuppressWarnings("unchecked") @Test public void testEndpointDisconnect() throws Exception { Set<ObjectName> s = mbsc.queryNames(new ObjectName("org.eclipse.jetty.server:type=server,*"), null); @@ -142,6 +145,7 @@ public class JettyEnableJmxTest extends }; } + @SuppressWarnings("unchecked") protected void releaseMBeanServers() { List<MBeanServer> servers = MBeanServerFactory.findMBeanServer(null); Modified: camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/JettyHttpEndpointDisconnectTest.java URL: http://svn.apache.org/viewvc/camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/JettyHttpEndpointDisconnectTest.java?rev=938751&r1=938750&r2=938751&view=diff ============================================================================== --- camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/JettyHttpEndpointDisconnectTest.java (original) +++ camel/trunk/components/camel-jetty/src/test/java/org/apache/camel/component/jetty/JettyHttpEndpointDisconnectTest.java Wed Apr 28 02:33:35 2010 @@ -30,9 +30,7 @@ public class JettyHttpEndpointDisconnect @Test public void testContextShutdownRemovesHttpConnector() throws Exception { context.stop(); - - JettyHttpComponent component = (JettyHttpComponent) context.getComponent("jetty"); - assertEquals("Connector should have been removed", 0, component.CONNECTORS.size()); + assertEquals("Connector should have been removed", 0, JettyHttpComponent.CONNECTORS.size()); } protected RouteBuilder createRouteBuilder() throws Exception {