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 2013/10/21 10:11:17 UTC

[3/4] git commit: CAMEL-6879: camel-restlet consumer should send back HTTP headers, such as Location etc.

CAMEL-6879: camel-restlet consumer should send back HTTP headers, such as Location etc.


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

Branch: refs/heads/camel-2.12.x
Commit: 66648ee0478a6834d9191b38caa0c290ab253f12
Parents: 204d6ef
Author: Claus Ibsen <da...@apache.org>
Authored: Mon Oct 21 10:00:30 2013 +0200
Committer: Claus Ibsen <da...@apache.org>
Committed: Mon Oct 21 10:09:49 2013 +0200

----------------------------------------------------------------------
 .../restlet/DefaultRestletBinding.java          | 45 ++++++++++---
 .../restlet/RestletHeaderFilterStrategy.java    |  7 +-
 .../component/restlet/RestletRedirectTest.java  | 68 ++++++++++++++++++++
 3 files changed, 108 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/camel/blob/66648ee0/components/camel-restlet/src/main/java/org/apache/camel/component/restlet/DefaultRestletBinding.java
----------------------------------------------------------------------
diff --git a/components/camel-restlet/src/main/java/org/apache/camel/component/restlet/DefaultRestletBinding.java b/components/camel-restlet/src/main/java/org/apache/camel/component/restlet/DefaultRestletBinding.java
index f84511e..055d251 100644
--- a/components/camel-restlet/src/main/java/org/apache/camel/component/restlet/DefaultRestletBinding.java
+++ b/components/camel-restlet/src/main/java/org/apache/camel/component/restlet/DefaultRestletBinding.java
@@ -49,10 +49,14 @@ import org.restlet.data.MediaType;
 import org.restlet.data.Method;
 import org.restlet.data.Preference;
 import org.restlet.data.Status;
+import org.restlet.engine.adapter.HttpResponse;
+import org.restlet.engine.header.Header;
 import org.restlet.engine.header.HeaderConstants;
+import org.restlet.engine.header.HeaderUtils;
 import org.restlet.representation.FileRepresentation;
 import org.restlet.representation.InputRepresentation;
 import org.restlet.representation.Representation;
+import org.restlet.util.Series;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -250,14 +254,31 @@ public class DefaultRestletBinding implements RestletBinding, HeaderFilterStrate
         }
 
         // set headers at the end, as the entity must be set first
+        // NOTE: setting HTTP headers on restlet is cumbersome and its API is "weird" and has some flaws
+        // so we need to headers two times, and the 2nd time we add the non-internal headers once more
+        Series<Header> series = new Series<Header>(Header.class);
         for (Map.Entry<String, Object> entry : out.getHeaders().entrySet()) {
             String key = entry.getKey();
             Object value = entry.getValue();
             if (!headerFilterStrategy.applyFilterToCamelHeaders(key, value, exchange)) {
-                setResponseHeader(exchange, response, key, value);
-                LOG.debug("Populate Restlet HTTP header in response from exchange header: {} value: {}", key, value);
+                boolean added = setResponseHeader(exchange, response, key, value);
+                if (!added) {
+                    // we only want non internal headers
+                    if (!key.startsWith("Camel") && !key.startsWith("org.restlet")) {
+                        String text = exchange.getContext().getTypeConverter().tryConvertTo(String.class, exchange, value);
+                        if (text != null) {
+                            series.add(key, text);
+                        }
+                    }
+                }
             }
         }
+
+        // set HTTP headers so we return these in the response
+        if (!series.isEmpty()) {
+            Series<Header> httpHeaders = (Series<Header>) response.getAttributes().get(HeaderConstants.ATTRIBUTE_HEADERS);
+            httpHeaders.addAll(series);
+        }
     }
 
     public void populateExchangeFromRestletResponse(Exchange exchange, Response response) throws Exception {
@@ -295,17 +316,16 @@ public class DefaultRestletBinding implements RestletBinding, HeaderFilterStrate
         MessageHelper.copyHeaders(exchange.getIn(), exchange.getOut(), false);
     }
 
-    
     @SuppressWarnings("unchecked")
-    protected void setResponseHeader(Exchange exchange, org.restlet.Message message, String header, Object value) {
-        // put the header first
-        message.getAttributes().put(header, value);
-
+    protected boolean setResponseHeader(Exchange exchange, org.restlet.Message message, String header, Object value) {
         // there must be a value going forward
         if (value == null) {
-            return;
+            return true;
         }
-        
+
+        // must put to attributes
+        message.getAttributes().put(header, value);
+
         // special for certain headers
         if (message.getEntity() != null) {
             if (header.equalsIgnoreCase(HeaderConstants.HEADER_CACHE_CONTROL)) {
@@ -318,6 +338,7 @@ public class DefaultRestletBinding implements RestletBinding, HeaderFilterStrate
                     list.add(new CacheDirective((String) value));
                     message.setCacheDirectives(list);
                 }
+                return true;
             }
             if (header.equalsIgnoreCase(HeaderConstants.HEADER_EXPIRES)) {
                 if (value instanceof Calendar) {
@@ -333,6 +354,7 @@ public class DefaultRestletBinding implements RestletBinding, HeaderFilterStrate
                         LOG.debug("Header {} with value {} cannot be converted as a Date. The value will be ignored.", HeaderConstants.HEADER_EXPIRES, value);
                     }
                 }
+                return true;
             }
 
             if (header.equalsIgnoreCase(HeaderConstants.HEADER_LAST_MODIFIED)) {
@@ -349,6 +371,7 @@ public class DefaultRestletBinding implements RestletBinding, HeaderFilterStrate
                         LOG.debug("Header {} with value {} cannot be converted as a Date. The value will be ignored.", HeaderConstants.HEADER_LAST_MODIFIED, value);
                     }
                 }
+                return true;
             }
 
             if (header.equalsIgnoreCase(HeaderConstants.HEADER_CONTENT_LENGTH)) {
@@ -364,6 +387,7 @@ public class DefaultRestletBinding implements RestletBinding, HeaderFilterStrate
                         LOG.debug("Header {} with value {} cannot be converted as a Long. The value will be ignored.", HeaderConstants.HEADER_CONTENT_LENGTH, value);
                     }
                 }
+                return true;
             }
 
             if (header.equalsIgnoreCase(HeaderConstants.HEADER_CONTENT_TYPE)) {
@@ -378,8 +402,11 @@ public class DefaultRestletBinding implements RestletBinding, HeaderFilterStrate
                         LOG.debug("Header {} with value {} cannot be converted as a MediaType. The value will be ignored.", HeaderConstants.HEADER_CONTENT_TYPE, value);
                     }
                 }
+                return true;
             }
         }
+
+        return false;
     }
 
     public HeaderFilterStrategy getHeaderFilterStrategy() {

http://git-wip-us.apache.org/repos/asf/camel/blob/66648ee0/components/camel-restlet/src/main/java/org/apache/camel/component/restlet/RestletHeaderFilterStrategy.java
----------------------------------------------------------------------
diff --git a/components/camel-restlet/src/main/java/org/apache/camel/component/restlet/RestletHeaderFilterStrategy.java b/components/camel-restlet/src/main/java/org/apache/camel/component/restlet/RestletHeaderFilterStrategy.java
index b873230..4ef196b 100644
--- a/components/camel-restlet/src/main/java/org/apache/camel/component/restlet/RestletHeaderFilterStrategy.java
+++ b/components/camel-restlet/src/main/java/org/apache/camel/component/restlet/RestletHeaderFilterStrategy.java
@@ -38,8 +38,9 @@ public class RestletHeaderFilterStrategy extends DefaultHeaderFilterStrategy {
         // The "CamelAcceptContentType" header is not added to the outgoing HTTP 
         // headers but it will be going out as "Accept.
         getOutFilter().add(Exchange.ACCEPT_CONTENT_TYPE);
-        
-        // Remove the restlet headers from the out message.
-        getOutFilter().add(HeaderConstants.ATTRIBUTE_HEADERS);
+
+        // Remove Camel and org.restlet internal headers
+//        setOutFilterPattern("(Camel.*)|(org\\.restlet\\..*)");
+//        setOutFilterPattern("org\\.restlet\\..*");
     }
 }

http://git-wip-us.apache.org/repos/asf/camel/blob/66648ee0/components/camel-restlet/src/test/java/org/apache/camel/component/restlet/RestletRedirectTest.java
----------------------------------------------------------------------
diff --git a/components/camel-restlet/src/test/java/org/apache/camel/component/restlet/RestletRedirectTest.java b/components/camel-restlet/src/test/java/org/apache/camel/component/restlet/RestletRedirectTest.java
new file mode 100644
index 0000000..a54c5c1
--- /dev/null
+++ b/components/camel-restlet/src/test/java/org/apache/camel/component/restlet/RestletRedirectTest.java
@@ -0,0 +1,68 @@
+/**
+ * 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.restlet;
+
+import org.apache.camel.Exchange;
+import org.apache.camel.builder.RouteBuilder;
+import org.apache.http.Header;
+import org.apache.http.HttpResponse;
+import org.apache.http.client.HttpClient;
+import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.params.ClientPNames;
+import org.apache.http.impl.client.DefaultHttpClient;
+import org.junit.Test;
+
+/**
+ *
+ * @version 
+ */
+public class RestletRedirectTest extends RestletTestSupport {
+
+    @Test
+    public void testRedirect() throws Exception {
+        HttpGet get = new HttpGet("http://localhost:" + portNum + "/users/homer");
+
+        // do not follow redirects
+        HttpClient client = new DefaultHttpClient();
+        client.getParams().setBooleanParameter(ClientPNames.HANDLE_REDIRECTS, false);
+
+        HttpResponse response = client.execute(get);
+
+        for (Header header : response.getAllHeaders()) {
+            log.info("Header {}", header);
+        }
+
+        assertEquals(302, response.getStatusLine().getStatusCode());
+        assertTrue("Should have location header", response.containsHeader("Location"));
+        assertEquals("http://somewhere.com", response.getFirstHeader("Location").getValue());
+        assertEquals("bar", response.getFirstHeader("Foo").getValue());
+    }
+
+    @Override
+    protected RouteBuilder createRouteBuilder() {
+        return new RouteBuilder() {
+            @Override
+            public void configure() throws Exception {
+                from("restlet:http://localhost:" + portNum + "/users/{username}")
+                    .setHeader(Exchange.HTTP_RESPONSE_CODE, constant(302))
+                    .setHeader("Location", constant("http://somewhere.com"))
+                    .setHeader("Foo", constant("bar"));
+            }
+        };
+    }
+
+}
\ No newline at end of file