You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@camel.apache.org by da...@apache.org on 2015/09/07 14:30:26 UTC

camel git commit: CAMEL-9105: Camel DefaultHttpBinding should convert response Date headers to HTTP-friendly format. Thanks to Sergey Beryozkin for the patch.

Repository: camel
Updated Branches:
  refs/heads/master 41277fbdd -> a3de7e193


CAMEL-9105: Camel DefaultHttpBinding should convert response Date headers to HTTP-friendly format. Thanks to Sergey Beryozkin for the patch.


Project: http://git-wip-us.apache.org/repos/asf/camel/repo
Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/a3de7e19
Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/a3de7e19
Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/a3de7e19

Branch: refs/heads/master
Commit: a3de7e1931ef5ee22094e192174f55c50896adf5
Parents: 41277fb
Author: Claus Ibsen <da...@apache.org>
Authored: Mon Sep 7 14:18:44 2015 +0200
Committer: Claus Ibsen <da...@apache.org>
Committed: Mon Sep 7 14:18:44 2015 +0200

----------------------------------------------------------------------
 .../camel/http/common/DefaultHttpBinding.java   | 60 +++++++++++++++++-
 .../http/common/DefaultHttpBindingTest.java     | 66 ++++++++++++++++++++
 .../src/test/resources/log4j.properties         | 36 +++++++++++
 3 files changed, 160 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/a3de7e19/components/camel-http-common/src/main/java/org/apache/camel/http/common/DefaultHttpBinding.java
----------------------------------------------------------------------
diff --git a/components/camel-http-common/src/main/java/org/apache/camel/http/common/DefaultHttpBinding.java b/components/camel-http-common/src/main/java/org/apache/camel/http/common/DefaultHttpBinding.java
index dcb3f20..aa6c1e7 100644
--- a/components/camel-http-common/src/main/java/org/apache/camel/http/common/DefaultHttpBinding.java
+++ b/components/camel-http-common/src/main/java/org/apache/camel/http/common/DefaultHttpBinding.java
@@ -24,9 +24,13 @@ import java.io.OutputStream;
 import java.io.PrintWriter;
 import java.io.Serializable;
 import java.net.URLDecoder;
+import java.text.SimpleDateFormat;
+import java.util.Date;
 import java.util.Enumeration;
 import java.util.Iterator;
+import java.util.Locale;
 import java.util.Map;
+import java.util.TimeZone;
 import javax.activation.DataHandler;
 import javax.servlet.ServletOutputStream;
 import javax.servlet.http.HttpServletRequest;
@@ -54,7 +58,19 @@ import org.slf4j.LoggerFactory;
  */
 public class DefaultHttpBinding implements HttpBinding {
 
+    /**
+     * Whether Date/Locale should be converted to String types (enabled by default)
+     */
+    public static final String DATE_LOCALE_CONVERSION = "CamelHttpBindingDateLocaleConversion";
+
+    /**
+     * The data format used for storing java.util.Date instances as a String value.
+     */
+    public static final String DATE_FORMAT = "EEE, dd MMM yyyy HH:mm:ss zzz";
+
     private static final Logger LOG = LoggerFactory.getLogger(DefaultHttpBinding.class);
+    private static final TimeZone TIME_ZONE_GMT = TimeZone.getTimeZone("GMT");
+
     private boolean useReaderForPayload;
     private boolean eagerCheckContentAvailable;
     private boolean transferException;
@@ -282,7 +298,7 @@ public class DefaultHttpBinding implements HttpBinding {
             // use an iterator as there can be multiple values. (must not use a delimiter)
             final Iterator<?> it = ObjectHelper.createIterator(value, null);
             while (it.hasNext()) {
-                String headerValue = exchange.getContext().getTypeConverter().convertTo(String.class, it.next());
+                String headerValue = convertHeaderValueToString(exchange, it.next());
                 if (headerValue != null && headerFilterStrategy != null
                         && !headerFilterStrategy.applyFilterToCamelHeaders(key, headerValue, exchange)) {
                     response.addHeader(key, headerValue);
@@ -300,10 +316,28 @@ public class DefaultHttpBinding implements HttpBinding {
         }
     }
     
+    protected String convertHeaderValueToString(Exchange exchange, Object headerValue) {
+        if ((headerValue instanceof Date || headerValue instanceof Locale)
+            && convertDateAndLocaleLocally(exchange)) {
+            if (headerValue instanceof Date) {
+                return toHttpDate((Date)headerValue);
+            } else {
+                return toHttpLanguage((Locale)headerValue);
+            }
+        } else {
+            return exchange.getContext().getTypeConverter().convertTo(String.class, headerValue);
+        }
+    }
+
+    protected boolean convertDateAndLocaleLocally(Exchange exchange) {
+        // This check is done only if a given header value is Date or Locale
+        return exchange.getProperty(DATE_LOCALE_CONVERSION, Boolean.TRUE, Boolean.class);
+    }
+
     protected boolean isText(String contentType) {
         if (contentType != null) {
             String temp = contentType.toLowerCase();
-            if (temp.indexOf("text") >= 0 || temp.indexOf("html") >= 0) {
+            if (temp.contains("text") || temp.contains("html")) {
                 return true;
             }
         }
@@ -491,4 +525,26 @@ public class DefaultHttpBinding implements HttpBinding {
         this.headerFilterStrategy = headerFilterStrategy;
     }
 
+    protected static SimpleDateFormat getHttpDateFormat() {
+        SimpleDateFormat dateFormat = new SimpleDateFormat(DATE_FORMAT, Locale.US);
+        dateFormat.setTimeZone(TIME_ZONE_GMT);
+        return dateFormat;
+    }
+    
+    protected static String toHttpDate(Date date) {
+        SimpleDateFormat format = getHttpDateFormat();
+        return format.format(date);
+    }
+    
+    protected static String toHttpLanguage(Locale locale) {
+        StringBuilder sb = new StringBuilder();
+        sb.append(locale.getLanguage());
+        if (locale.getCountry() != null) {
+            // Locale.toString() will use a "_" separator instead, 
+            // while '-' is expected in headers such as Content-Language, etc:
+            // http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.10
+            sb.append('-').append(locale.getCountry());
+        }
+        return sb.toString();
+    }
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/a3de7e19/components/camel-http-common/src/test/java/org/apache/camel/http/common/DefaultHttpBindingTest.java
----------------------------------------------------------------------
diff --git a/components/camel-http-common/src/test/java/org/apache/camel/http/common/DefaultHttpBindingTest.java b/components/camel-http-common/src/test/java/org/apache/camel/http/common/DefaultHttpBindingTest.java
new file mode 100644
index 0000000..dbeb01f
--- /dev/null
+++ b/components/camel-http-common/src/test/java/org/apache/camel/http/common/DefaultHttpBindingTest.java
@@ -0,0 +1,66 @@
+/**
+ * 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.http.common;
+
+import java.util.Date;
+import java.util.Locale;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.test.junit4.CamelTestSupport;
+import org.junit.Test;
+
+public class DefaultHttpBindingTest extends CamelTestSupport {
+
+    @Test
+    public void testConvertDate() throws Exception {
+        DefaultHttpBinding binding = new DefaultHttpBinding();
+        Date date = new Date();
+        Exchange exchange = super.createExchangeWithBody(null);
+        
+        String value = binding.convertHeaderValueToString(exchange, date);
+        assertNotEquals(value, date.toString());
+        assertEquals(value, DefaultHttpBinding.getHttpDateFormat().format(date));
+    }
+    @Test
+    public void testConvertDateTypeConverter() throws Exception {
+        DefaultHttpBinding binding = new DefaultHttpBinding();
+        Date date = new Date();
+        Exchange exchange = super.createExchangeWithBody(null);
+        exchange.setProperty(DefaultHttpBinding.DATE_LOCALE_CONVERSION, false);
+        String value = binding.convertHeaderValueToString(exchange, date);
+        assertEquals(value, date.toString());
+    }
+    @Test
+    public void testConvertLocale() throws Exception {
+        DefaultHttpBinding binding = new DefaultHttpBinding();
+        Locale l = Locale.SIMPLIFIED_CHINESE;
+        Exchange exchange = super.createExchangeWithBody(null);
+        
+        String value = binding.convertHeaderValueToString(exchange, l);
+        assertNotEquals(value, l.toString());
+        assertEquals("zh-CN", value);
+    }
+    @Test
+    public void testConvertLocaleTypeConverter() throws Exception {
+        DefaultHttpBinding binding = new DefaultHttpBinding();
+        Locale l = Locale.SIMPLIFIED_CHINESE;
+        Exchange exchange = super.createExchangeWithBody(null);
+        exchange.setProperty(DefaultHttpBinding.DATE_LOCALE_CONVERSION, false);
+        String value = binding.convertHeaderValueToString(exchange, l);
+        assertEquals(value, l.toString());
+    }
+}

http://git-wip-us.apache.org/repos/asf/camel/blob/a3de7e19/components/camel-http-common/src/test/resources/log4j.properties
----------------------------------------------------------------------
diff --git a/components/camel-http-common/src/test/resources/log4j.properties b/components/camel-http-common/src/test/resources/log4j.properties
new file mode 100644
index 0000000..24f96f5
--- /dev/null
+++ b/components/camel-http-common/src/test/resources/log4j.properties
@@ -0,0 +1,36 @@
+## ------------------------------------------------------------------------
+## 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.
+## ------------------------------------------------------------------------
+
+#
+# The logging properties used for testing
+#
+log4j.rootLogger=INFO, file
+
+# uncomment the following to enable camel debugging
+#log4j.logger.org.apache.camel=DEBUG
+
+# CONSOLE appender not used by default
+log4j.appender.out=org.apache.log4j.ConsoleAppender
+log4j.appender.out.layout=org.apache.log4j.PatternLayout
+#log4j.appender.out.layout.ConversionPattern=[%30.30t] %-30.30c{1} %-5p %m%n
+log4j.appender.out.layout.ConversionPattern=%d [%-50.50t] %-5p %-30.30c{1} - %m%n
+
+# File appender
+log4j.appender.file=org.apache.log4j.FileAppender
+log4j.appender.file.layout=org.apache.log4j.PatternLayout
+log4j.appender.file.layout.ConversionPattern=%d [%-15.15t] %-5p %-30.30c{1} - %m%n
+log4j.appender.file.file=target/camel-http-common-test.log