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