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
commit 30e9be4b31b6e4c00857ad5c631766fc876134ae Author: Claus Ibsen <claus.ib...@gmail.com> AuthorDate: Fri Feb 26 07:04:41 2021 +0100 CAMEL-16264: camel-http - Add option to ignore response headers --- .../apache/camel/catalog/docs/http-component.adoc | 3 +- .../component/http/HttpEndpointConfigurer.java | 6 +++ .../component/http/HttpEndpointUriFactory.java | 3 +- .../org/apache/camel/component/http/http.json | 1 + .../org/apache/camel/component/http/https.json | 1 + .../camel-http/src/main/docs/http-component.adoc | 3 +- .../apache/camel/component/http/HttpEndpoint.java | 16 ++++++ .../apache/camel/component/http/HttpProducer.java | 58 ++++++++++++---------- .../endpoint/dsl/HttpEndpointBuilderFactory.java | 39 +++++++++++++++ .../modules/ROOT/pages/http-component.adoc | 3 +- 10 files changed, 102 insertions(+), 31 deletions(-) diff --git a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/http-component.adoc b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/http-component.adoc index cc642c4..61d5f5f 100644 --- a/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/http-component.adoc +++ b/catalog/camel-catalog/src/generated/resources/org/apache/camel/catalog/docs/http-component.adoc @@ -126,7 +126,7 @@ with the following path and query parameters: |=== -=== Query Parameters (48 parameters): +=== Query Parameters (49 parameters): [width="100%",cols="2,5,^1,2",options="header"] @@ -161,6 +161,7 @@ with the following path and query parameters: | *httpContext* (advanced) | To use a custom HttpContext instance | | HttpContext | *maxTotalConnections* (advanced) | The maximum number of connections. | 200 | int | *useSystemProperties* (advanced) | To use System Properties as fallback for configuration | false | boolean +| *skipResponseHeaders* (producer.advanced) | Whether to skip mapping all the HTTP response headers to Camel headers. If there are no data needed from HTTP headers then this can avoid parsing overhead with many object allocations for the JVM garbage collector. | false | boolean | *proxyAuthDomain* (proxy) | Proxy authentication domain to use with NTML | | String | *proxyAuthHost* (proxy) | Proxy authentication host | | String | *proxyAuthMethod* (proxy) | Proxy authentication method to use. There are 3 enums and the value can be one of: Basic, Digest, NTLM | | String diff --git a/components/camel-http/src/generated/java/org/apache/camel/component/http/HttpEndpointConfigurer.java b/components/camel-http/src/generated/java/org/apache/camel/component/http/HttpEndpointConfigurer.java index 61e9b9b..237aa97 100644 --- a/components/camel-http/src/generated/java/org/apache/camel/component/http/HttpEndpointConfigurer.java +++ b/components/camel-http/src/generated/java/org/apache/camel/component/http/HttpEndpointConfigurer.java @@ -106,6 +106,8 @@ public class HttpEndpointConfigurer extends PropertyConfigurerSupport implements case "proxyHost": target.setProxyHost(property(camelContext, java.lang.String.class, value)); return true; case "proxyport": case "proxyPort": target.setProxyPort(property(camelContext, int.class, value)); return true; + case "skipresponseheaders": + case "skipResponseHeaders": target.setSkipResponseHeaders(property(camelContext, boolean.class, value)); return true; case "sslcontextparameters": case "sslContextParameters": target.setSslContextParameters(property(camelContext, org.apache.camel.support.jsse.SSLContextParameters.class, value)); return true; case "throwexceptiononfailure": @@ -208,6 +210,8 @@ public class HttpEndpointConfigurer extends PropertyConfigurerSupport implements case "proxyHost": return java.lang.String.class; case "proxyport": case "proxyPort": return int.class; + case "skipresponseheaders": + case "skipResponseHeaders": return boolean.class; case "sslcontextparameters": case "sslContextParameters": return org.apache.camel.support.jsse.SSLContextParameters.class; case "throwexceptiononfailure": @@ -311,6 +315,8 @@ public class HttpEndpointConfigurer extends PropertyConfigurerSupport implements case "proxyHost": return target.getProxyHost(); case "proxyport": case "proxyPort": return target.getProxyPort(); + case "skipresponseheaders": + case "skipResponseHeaders": return target.isSkipResponseHeaders(); case "sslcontextparameters": case "sslContextParameters": return target.getSslContextParameters(); case "throwexceptiononfailure": diff --git a/components/camel-http/src/generated/java/org/apache/camel/component/http/HttpEndpointUriFactory.java b/components/camel-http/src/generated/java/org/apache/camel/component/http/HttpEndpointUriFactory.java index 8d2ce0c..9b247bd 100644 --- a/components/camel-http/src/generated/java/org/apache/camel/component/http/HttpEndpointUriFactory.java +++ b/components/camel-http/src/generated/java/org/apache/camel/component/http/HttpEndpointUriFactory.java @@ -21,7 +21,7 @@ public class HttpEndpointUriFactory extends org.apache.camel.support.component.E private static final Set<String> PROPERTY_NAMES; private static final Set<String> SECRET_PROPERTY_NAMES; static { - Set<String> props = new HashSet<>(49); + Set<String> props = new HashSet<>(50); props.add("clientBuilder"); props.add("authMethodPriority"); props.add("ignoreResponseBody"); @@ -54,6 +54,7 @@ public class HttpEndpointUriFactory extends org.apache.camel.support.component.E props.add("proxyAuthScheme"); props.add("sslContextParameters"); props.add("httpMethod"); + props.add("skipResponseHeaders"); props.add("deleteWithBody"); props.add("httpUri"); props.add("headerFilterStrategy"); diff --git a/components/camel-http/src/generated/resources/org/apache/camel/component/http/http.json b/components/camel-http/src/generated/resources/org/apache/camel/component/http/http.json index 10af0bc..fc55d55 100644 --- a/components/camel-http/src/generated/resources/org/apache/camel/component/http/http.json +++ b/components/camel-http/src/generated/resources/org/apache/camel/component/http/http.json @@ -90,6 +90,7 @@ "httpContext": { "kind": "parameter", "displayName": "Http Context", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "org.apache.http.protocol.HttpContext", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom HttpContext instance" }, "maxTotalConnections": { "kind": "parameter", "displayName": "Max Total Connections", "group": "advanced", "label": "advanced", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": false, "secret": false, "defaultValue": 200, "description": "The maximum number of connections." }, "useSystemProperties": { "kind": "parameter", "displayName": "Use System Properties", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "To use System Properties as fallback for configuration" }, + "skipResponseHeaders": { "kind": "parameter", "displayName": "Skip Response Headers", "group": "producer.advanced", "label": "producer.advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to skip mapping all the HTTP response headers to Camel headers. If there are no data needed from HTTP headers then this can avoid parsing overhead with many object allocations [...] "proxyAuthDomain": { "kind": "parameter", "displayName": "Proxy Auth Domain", "group": "proxy", "label": "producer,proxy", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Proxy authentication domain to use with NTML" }, "proxyAuthHost": { "kind": "parameter", "displayName": "Proxy Auth Host", "group": "proxy", "label": "producer,proxy", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Proxy authentication host" }, "proxyAuthMethod": { "kind": "parameter", "displayName": "Proxy Auth Method", "group": "proxy", "label": "producer,proxy", "required": false, "type": "string", "javaType": "java.lang.String", "enum": [ "Basic", "Digest", "NTLM" ], "deprecated": false, "autowired": false, "secret": false, "description": "Proxy authentication method to use" }, diff --git a/components/camel-http/src/generated/resources/org/apache/camel/component/http/https.json b/components/camel-http/src/generated/resources/org/apache/camel/component/http/https.json index f109756..b2e1527 100644 --- a/components/camel-http/src/generated/resources/org/apache/camel/component/http/https.json +++ b/components/camel-http/src/generated/resources/org/apache/camel/component/http/https.json @@ -90,6 +90,7 @@ "httpContext": { "kind": "parameter", "displayName": "Http Context", "group": "advanced", "label": "advanced", "required": false, "type": "object", "javaType": "org.apache.http.protocol.HttpContext", "deprecated": false, "autowired": false, "secret": false, "description": "To use a custom HttpContext instance" }, "maxTotalConnections": { "kind": "parameter", "displayName": "Max Total Connections", "group": "advanced", "label": "advanced", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": false, "secret": false, "defaultValue": 200, "description": "The maximum number of connections." }, "useSystemProperties": { "kind": "parameter", "displayName": "Use System Properties", "group": "advanced", "label": "advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "To use System Properties as fallback for configuration" }, + "skipResponseHeaders": { "kind": "parameter", "displayName": "Skip Response Headers", "group": "producer.advanced", "label": "producer.advanced", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Whether to skip mapping all the HTTP response headers to Camel headers. If there are no data needed from HTTP headers then this can avoid parsing overhead with many object allocations [...] "proxyAuthDomain": { "kind": "parameter", "displayName": "Proxy Auth Domain", "group": "proxy", "label": "producer,proxy", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Proxy authentication domain to use with NTML" }, "proxyAuthHost": { "kind": "parameter", "displayName": "Proxy Auth Host", "group": "proxy", "label": "producer,proxy", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "description": "Proxy authentication host" }, "proxyAuthMethod": { "kind": "parameter", "displayName": "Proxy Auth Method", "group": "proxy", "label": "producer,proxy", "required": false, "type": "string", "javaType": "java.lang.String", "enum": [ "Basic", "Digest", "NTLM" ], "deprecated": false, "autowired": false, "secret": false, "description": "Proxy authentication method to use" }, diff --git a/components/camel-http/src/main/docs/http-component.adoc b/components/camel-http/src/main/docs/http-component.adoc index cc642c4..61d5f5f 100644 --- a/components/camel-http/src/main/docs/http-component.adoc +++ b/components/camel-http/src/main/docs/http-component.adoc @@ -126,7 +126,7 @@ with the following path and query parameters: |=== -=== Query Parameters (48 parameters): +=== Query Parameters (49 parameters): [width="100%",cols="2,5,^1,2",options="header"] @@ -161,6 +161,7 @@ with the following path and query parameters: | *httpContext* (advanced) | To use a custom HttpContext instance | | HttpContext | *maxTotalConnections* (advanced) | The maximum number of connections. | 200 | int | *useSystemProperties* (advanced) | To use System Properties as fallback for configuration | false | boolean +| *skipResponseHeaders* (producer.advanced) | Whether to skip mapping all the HTTP response headers to Camel headers. If there are no data needed from HTTP headers then this can avoid parsing overhead with many object allocations for the JVM garbage collector. | false | boolean | *proxyAuthDomain* (proxy) | Proxy authentication domain to use with NTML | | String | *proxyAuthHost* (proxy) | Proxy authentication host | | String | *proxyAuthMethod* (proxy) | Proxy authentication method to use. There are 3 enums and the value can be one of: Basic, Digest, NTLM | | String 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 5783ec4..52e6c42 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 @@ -137,6 +137,10 @@ public class HttpEndpoint extends HttpCommonEndpoint { @UriParam(label = "producer", description = "To use custom host header for producer. When not set in query will " + "be ignored. When set will override host header derived from url.") private String customHostHeader; + @UriParam(label = "producer.advanced", + description = "Whether to skip mapping all the HTTP response headers to Camel headers." + + " If there are no data needed from HTTP headers then this can avoid parsing overhead with many object allocations for the JVM garbage collector.") + private boolean skipResponseHeaders; public HttpEndpoint() { } @@ -533,6 +537,18 @@ public class HttpEndpoint extends HttpCommonEndpoint { return customHostHeader; } + public boolean isSkipResponseHeaders() { + return skipResponseHeaders; + } + + /** + * Whether to skip mapping all the HTTP response headers to Camel headers. If there are no data needed from HTTP + * headers then this can avoid parsing overhead with many object allocations for the JVM garbage collector. + */ + public void setSkipResponseHeaders(boolean skipResponseHeaders) { + this.skipResponseHeaders = skipResponseHeaders; + } + @ManagedAttribute(description = "Maximum number of allowed persistent connections") public int getClientConnectionsPoolStatsMax() { ConnPoolControl<?> pool = null; 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 b789c40..4b6497d 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 @@ -321,37 +321,41 @@ public class HttpProducer extends DefaultProducer { } answer.setBody(response); - // propagate HTTP response headers - Map<String, List<String>> cookieHeaders = null; - if (getEndpoint().getCookieHandler() != null) { - cookieHeaders = new HashMap<>(); - } - - // optimize to walk headers with an iterator which does not create a new array as getAllHeaders does - boolean found = false; - HeaderIterator it = httpResponse.headerIterator(); - while (it.hasNext()) { - Header header = it.nextHeader(); - String name = header.getName(); - String value = header.getValue(); - if (cookieHeaders != null) { - cookieHeaders.computeIfAbsent(name, k -> new ArrayList<>()).add(value); + if (!getEndpoint().isSkipResponseHeaders()) { + + // propagate HTTP response headers + Map<String, List<String>> cookieHeaders = null; + if (getEndpoint().getCookieHandler() != null) { + cookieHeaders = new HashMap<>(); } - if (!found && name.equalsIgnoreCase("content-type")) { - name = Exchange.CONTENT_TYPE; - exchange.setProperty(Exchange.CHARSET_NAME, IOHelper.getCharsetNameFromContentType(value)); - found = true; + + // optimize to walk headers with an iterator which does not create a new array as getAllHeaders does + boolean found = false; + HeaderIterator it = httpResponse.headerIterator(); + while (it.hasNext()) { + Header header = it.nextHeader(); + String name = header.getName(); + String value = header.getValue(); + if (cookieHeaders != null) { + cookieHeaders.computeIfAbsent(name, k -> new ArrayList<>()).add(value); + } + if (!found && name.equalsIgnoreCase("content-type")) { + name = Exchange.CONTENT_TYPE; + exchange.setProperty(Exchange.CHARSET_NAME, IOHelper.getCharsetNameFromContentType(value)); + found = true; + } + // use http helper to extract parameter value as it may contain multiple values + Object extracted = HttpHelper.extractHttpParameterValue(value); + if (strategy != null && !strategy.applyFilterToExternalHeaders(name, extracted, exchange)) { + HttpHelper.appendHeader(answer.getHeaders(), name, extracted); + } } - // use http helper to extract parameter value as it may contain multiple values - Object extracted = HttpHelper.extractHttpParameterValue(value); - if (strategy != null && !strategy.applyFilterToExternalHeaders(name, extracted, exchange)) { - HttpHelper.appendHeader(answer.getHeaders(), name, extracted); + // handle cookies + if (getEndpoint().getCookieHandler() != null) { + getEndpoint().getCookieHandler().storeCookies(exchange, httpRequest.getURI(), cookieHeaders); } } - // handle cookies - if (getEndpoint().getCookieHandler() != null) { - getEndpoint().getCookieHandler().storeCookies(exchange, httpRequest.getURI(), cookieHeaders); - } + // endpoint might be configured to copy headers from in to out // to avoid overriding existing headers with old values just // filter the http protocol headers diff --git a/core/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/HttpEndpointBuilderFactory.java b/core/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/HttpEndpointBuilderFactory.java index 0816bd8..2561783 100644 --- a/core/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/HttpEndpointBuilderFactory.java +++ b/core/camel-endpointdsl/src/generated/java/org/apache/camel/builder/endpoint/dsl/HttpEndpointBuilderFactory.java @@ -1439,6 +1439,45 @@ public interface HttpEndpointBuilderFactory { doSetProperty("useSystemProperties", useSystemProperties); return this; } + /** + * Whether to skip mapping all the HTTP response headers to Camel + * headers. If there are no data needed from HTTP headers then this can + * avoid parsing overhead with many object allocations for the JVM + * garbage collector. + * + * The option is a: <code>boolean</code> type. + * + * Default: false + * Group: producer.advanced + * + * @param skipResponseHeaders the value to set + * @return the dsl builder + */ + default AdvancedHttpEndpointBuilder skipResponseHeaders( + boolean skipResponseHeaders) { + doSetProperty("skipResponseHeaders", skipResponseHeaders); + return this; + } + /** + * Whether to skip mapping all the HTTP response headers to Camel + * headers. If there are no data needed from HTTP headers then this can + * avoid parsing overhead with many object allocations for the JVM + * garbage collector. + * + * The option will be converted to a <code>boolean</code> + * type. + * + * Default: false + * Group: producer.advanced + * + * @param skipResponseHeaders the value to set + * @return the dsl builder + */ + default AdvancedHttpEndpointBuilder skipResponseHeaders( + String skipResponseHeaders) { + doSetProperty("skipResponseHeaders", skipResponseHeaders); + return this; + } } /** diff --git a/docs/components/modules/ROOT/pages/http-component.adoc b/docs/components/modules/ROOT/pages/http-component.adoc index 6274022..3d3f2a6 100644 --- a/docs/components/modules/ROOT/pages/http-component.adoc +++ b/docs/components/modules/ROOT/pages/http-component.adoc @@ -128,7 +128,7 @@ with the following path and query parameters: |=== -=== Query Parameters (48 parameters): +=== Query Parameters (49 parameters): [width="100%",cols="2,5,^1,2",options="header"] @@ -163,6 +163,7 @@ with the following path and query parameters: | *httpContext* (advanced) | To use a custom HttpContext instance | | HttpContext | *maxTotalConnections* (advanced) | The maximum number of connections. | 200 | int | *useSystemProperties* (advanced) | To use System Properties as fallback for configuration | false | boolean +| *skipResponseHeaders* (producer.advanced) | Whether to skip mapping all the HTTP response headers to Camel headers. If there are no data needed from HTTP headers then this can avoid parsing overhead with many object allocations for the JVM garbage collector. | false | boolean | *proxyAuthDomain* (proxy) | Proxy authentication domain to use with NTML | | String | *proxyAuthHost* (proxy) | Proxy authentication host | | String | *proxyAuthMethod* (proxy) | Proxy authentication method to use. There are 3 enums and the value can be one of: Basic, Digest, NTLM | | String