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 2019/10/31 12:45:46 UTC

[camel] branch master updated: CAMEL-14118: Add getWithBody option to camel-http and also fix so an explicit GET wont attempt to read body as its not in use, this helps CAMEL-14115

This is an automated email from the ASF dual-hosted git repository.

davsclaus pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/camel.git


The following commit(s) were added to refs/heads/master by this push:
     new cf8c9a6  CAMEL-14118: Add getWithBody option to camel-http and also fix so an explicit GET wont attempt to read body as its not in use, this helps CAMEL-14115
cf8c9a6 is described below

commit cf8c9a6505556e0df7ab426d787de4c1ced24131
Author: Claus Ibsen <cl...@gmail.com>
AuthorDate: Thu Oct 31 13:41:59 2019 +0100

    CAMEL-14118: Add getWithBody option to camel-http and also fix so an explicit GET wont attempt to read body as its not in use, this helps CAMEL-14115
---
 .../camel-http/src/main/docs/http-component.adoc   |  5 +--
 .../apache/camel/component/http/HttpEndpoint.java  | 22 +++++++++++--
 .../component/http/HttpGetWithBodyMethod.java      | 37 ++++++++++++++++++++++
 .../apache/camel/component/http/HttpProducer.java  | 11 +++++--
 .../component/http/helper/HttpMethodHelper.java    | 10 ++----
 .../camel/component/http/HttpMethodsTest.java      | 15 +++++++++
 6 files changed, 85 insertions(+), 15 deletions(-)

diff --git a/components/camel-http/src/main/docs/http-component.adoc b/components/camel-http/src/main/docs/http-component.adoc
index e965f86..8b1dcf0 100644
--- a/components/camel-http/src/main/docs/http-component.adoc
+++ b/components/camel-http/src/main/docs/http-component.adoc
@@ -101,7 +101,7 @@ with the following path and query parameters:
 |===
 
 
-=== Query Parameters (50 parameters):
+=== Query Parameters (51 parameters):
 
 
 [width="100%",cols="2,5,^1,2",options="header"]
@@ -117,7 +117,8 @@ with the following path and query parameters:
 | *connectionClose* (producer) | Specifies whether a Connection Close header must be added to HTTP Request. By default connectionClose is false. | false | boolean
 | *cookieStore* (producer) | To use a custom CookieStore. By default the BasicCookieStore is used which is an in-memory only cookie store. Notice if bridgeEndpoint=true then the cookie store is forced to be a noop cookie store as cookie shouldn't be stored as we are just bridging (eg acting as a proxy). If a cookieHandler is set then the cookie store is also forced to be a noop cookie store as cookie handling is then performed by the cookieHandler. |  | CookieStore
 | *copyHeaders* (producer) | If this option is true then IN exchange headers will be copied to OUT exchange headers according to copy strategy. Setting this to false, allows to only include the headers from the HTTP response (not propagating IN headers). | true | boolean
-| *deleteWithBody* (producer) | Whether the HTTP DELETE should include the message body or not. By default HTTP DELETE do not include any HTTP message. However in some rare cases users may need to be able to include the message body. | false | boolean
+| *deleteWithBody* (producer) | Whether the HTTP DELETE should include the message body or not. By default HTTP DELETE do not include any HTTP body. However in some rare cases users may need to be able to include the message body. | false | boolean
+| *getWithBody* (producer) | Whether the HTTP GET should include the message body or not. By default HTTP GET do not include any HTTP body. However in some rare cases users may need to be able to include the message body. | false | boolean
 | *httpMethod* (producer) | Configure the HTTP method to use. The HttpMethod header cannot override this option if set. |  | HttpMethods
 | *ignoreResponseBody* (producer) | If this option is true, The http producer won't read response body and cache the input stream | false | boolean
 | *lazyStartProducer* (producer) | Whether the producer should be started lazy (on the first message). By starting lazy you can use this to allow CamelContext and routes to startup in situations where a producer may otherwise fail during starting and cause the route to fail being started. By deferring this startup to be lazy then the startup failure can be handled during routing messages via Camel's routing error handlers. Beware that when the first message is processed then creating and [...]
diff --git a/components/camel-http/src/main/java/org/apache/camel/component/http/HttpEndpoint.java b/components/camel-http/src/main/java/org/apache/camel/component/http/HttpEndpoint.java
index c48d9e8..82d894e 100644
--- a/components/camel-http/src/main/java/org/apache/camel/component/http/HttpEndpoint.java
+++ b/components/camel-http/src/main/java/org/apache/camel/component/http/HttpEndpoint.java
@@ -105,10 +105,12 @@ public class HttpEndpoint extends HttpCommonEndpoint {
     private boolean clearExpiredCookies = true;
     @UriParam(label = "producer", description = "If this option is true, camel-http sends preemptive basic authentication to the server.")
     private boolean authenticationPreemptive;
+    @UriParam(label = "producer", description = "Whether the HTTP GET should include the message body or not."
+        + " By default HTTP GET do not include any HTTP body. However in some rare cases users may need to be able to include the message body.")
+    private boolean getWithBody;
     @UriParam(label = "producer", description = "Whether the HTTP DELETE should include the message body or not."
-        + " By default HTTP DELETE do not include any HTTP message. However in some rare cases users may need to be able to include the message body.")
+        + " By default HTTP DELETE do not include any HTTP body. However in some rare cases users may need to be able to include the message body.")
     private boolean deleteWithBody;
-
     @UriParam(label = "advanced", defaultValue = "200", description = "The maximum number of connections.")
     private int maxTotalConnections;
     @UriParam(label = "advanced", defaultValue = "20", description = "The maximum number of connections per route.")
@@ -309,13 +311,27 @@ public class HttpEndpoint extends HttpCommonEndpoint {
     /**
      * Whether the HTTP DELETE should include the message body or not.
      * <p/>
-     * By default HTTP DELETE do not include any HTTP message. However in some rare cases users may need to be able to include the
+     * By default HTTP DELETE do not include any HTTP body. However in some rare cases users may need to be able to include the
      * message body.
      */
     public void setDeleteWithBody(boolean deleteWithBody) {
         this.deleteWithBody = deleteWithBody;
     }
 
+    public boolean isGetWithBody() {
+        return getWithBody;
+    }
+
+    /**
+     * Whether the HTTP GET should include the message body or not.
+     * <p/>
+     * By default HTTP GET do not include any HTTP body. However in some rare cases users may need to be able to include the
+     * message body.
+     */
+    public void setGetWithBody(boolean getWithBody) {
+        this.getWithBody = getWithBody;
+    }
+
     public CookieStore getCookieStore() {
         return cookieStore;
     }
diff --git a/components/camel-http/src/main/java/org/apache/camel/component/http/HttpGetWithBodyMethod.java b/components/camel-http/src/main/java/org/apache/camel/component/http/HttpGetWithBodyMethod.java
new file mode 100644
index 0000000..47aa477
--- /dev/null
+++ b/components/camel-http/src/main/java/org/apache/camel/component/http/HttpGetWithBodyMethod.java
@@ -0,0 +1,37 @@
+/*
+ * 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.http;
+
+import java.net.URI;
+
+import org.apache.http.HttpEntity;
+import org.apache.http.client.methods.HttpEntityEnclosingRequestBase;
+
+public class HttpGetWithBodyMethod extends HttpEntityEnclosingRequestBase {
+
+    public static final String METHOD_NAME = "GET";
+
+    public HttpGetWithBodyMethod(String uri, HttpEntity entity) {
+        setURI(URI.create(uri));
+        setEntity(entity);
+    }
+
+    @Override
+    public String getMethod() {
+        return METHOD_NAME;
+    }
+}
diff --git a/components/camel-http/src/main/java/org/apache/camel/component/http/HttpProducer.java b/components/camel-http/src/main/java/org/apache/camel/component/http/HttpProducer.java
index 94c12cd..544c48f 100644
--- a/components/camel-http/src/main/java/org/apache/camel/component/http/HttpProducer.java
+++ b/components/camel-http/src/main/java/org/apache/camel/component/http/HttpProducer.java
@@ -440,18 +440,23 @@ public class HttpProducer extends DefaultProducer {
         url = uri.toASCIIString();
 
         // create http holder objects for the request
-        HttpEntity requestEntity = createRequestEntity(exchange);
-        HttpMethods methodToUse = HttpMethodHelper.createMethod(exchange, getEndpoint(), requestEntity != null);
+        HttpMethods methodToUse = HttpMethodHelper.createMethod(exchange, getEndpoint());
         HttpRequestBase method = methodToUse.createMethod(url);
 
-        // special for HTTP DELETE if the message body should be included
+        // special for HTTP DELETE/GET if the message body should be included
         if (getEndpoint().isDeleteWithBody() && "DELETE".equals(method.getMethod())) {
+            HttpEntity requestEntity = createRequestEntity(exchange);
             method = new HttpDeleteWithBodyMethod(url, requestEntity);
+        } else if (getEndpoint().isGetWithBody() && "GET".equals(method.getMethod())) {
+            HttpEntity requestEntity = createRequestEntity(exchange);
+            method = new HttpGetWithBodyMethod(url, requestEntity);
         }
 
         log.trace("Using URL: {} with method: {}", url, method);
 
         if (methodToUse.isEntityEnclosing()) {
+            // only create entity for http payload if the HTTP method carries payload (such as POST)
+            HttpEntity requestEntity = createRequestEntity(exchange);
             ((HttpEntityEnclosingRequestBase) method).setEntity(requestEntity);
             if (requestEntity != null && requestEntity.getContentType() == null) {
                 log.debug("No Content-Type provided for URL: {} with exchange: {}", url, exchange);
diff --git a/components/camel-http/src/main/java/org/apache/camel/component/http/helper/HttpMethodHelper.java b/components/camel-http/src/main/java/org/apache/camel/component/http/helper/HttpMethodHelper.java
index a88c906..64a8053 100644
--- a/components/camel-http/src/main/java/org/apache/camel/component/http/helper/HttpMethodHelper.java
+++ b/components/camel-http/src/main/java/org/apache/camel/component/http/helper/HttpMethodHelper.java
@@ -32,13 +32,9 @@ public final class HttpMethodHelper {
     }
 
     /**
-     * Creates the HttpMethod to use to call the remote server, often either its GET or POST.
-     *
-     * @param exchange the exchange
-     * @return the created method
-     * @throws URISyntaxException
+     * Creates the HttpMethod to use to call the remote server, often either its GET or POST
      */
-    public static HttpMethods createMethod(Exchange exchange, HttpEndpoint endpoint, boolean hasPayload) throws URISyntaxException {
+    public static HttpMethods createMethod(Exchange exchange, HttpEndpoint endpoint) throws URISyntaxException {
         // is a query string provided in the endpoint URI or in a header (header
         // overrules endpoint)
         String queryString = exchange.getIn().getHeader(Exchange.HTTP_QUERY, String.class);
@@ -76,7 +72,7 @@ public final class HttpMethodHelper {
                 answer = HttpMethods.GET;
             } else {
                 // fallback to POST if we have payload, otherwise GET
-                answer = hasPayload ? HttpMethods.POST : HttpMethods.GET;
+                answer = exchange.getMessage().getBody() != null ? HttpMethods.POST : HttpMethods.GET;
             }
         }
 
diff --git a/components/camel-http/src/test/java/org/apache/camel/component/http/HttpMethodsTest.java b/components/camel-http/src/test/java/org/apache/camel/component/http/HttpMethodsTest.java
index d4732f1..e7782d1 100644
--- a/components/camel-http/src/test/java/org/apache/camel/component/http/HttpMethodsTest.java
+++ b/components/camel-http/src/test/java/org/apache/camel/component/http/HttpMethodsTest.java
@@ -219,6 +219,21 @@ public class HttpMethodsTest extends BaseHttpTest {
     }
 
     @Test
+    public void httpGetWithBody() throws Exception {
+
+        Exchange exchange = template.request("http://" + localServer.getInetAddress().getHostName() + ":" + localServer.getLocalPort() + "/get?getWithBody=true", new Processor() {
+            public void process(Exchange exchange) throws Exception {
+                exchange.getIn().setHeader(Exchange.HTTP_METHOD, "GET");
+                exchange.getIn().setBody("rocks camel?");
+            }
+        });
+
+        assertExchange(exchange);
+
+        // the http server will not provide body on HTTP GET so we cannot test the server side
+    }
+
+    @Test
     public void httpHead() throws Exception {
 
         Exchange exchange = template.request("http://" + localServer.getInetAddress().getHostName() + ":" + localServer.getLocalPort() + "/head", new Processor() {