You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by ni...@apache.org on 2010/04/28 04:33:36 UTC

svn commit: r938751 - in /camel/trunk/components: camel-http/src/main/java/org/apache/camel/component/http/ camel-jetty/src/test/java/org/apache/camel/component/jetty/

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 {