This is an automated email from the ASF dual-hosted git repository. nfilotto pushed a commit to branch CAMEL-17792/doc-message-headers in repository https://gitbox.apache.org/repos/asf/camel.git
commit f37ec2e73dc2f7d5f11058d120eca8b1a4d3ef7f Author: Nicolas Filotto <[email protected]> AuthorDate: Fri Apr 1 15:05:10 2022 +0200 CAMEL-17792: Add doc about the message headers of camel-netty-http --- .../camel/component/netty/http/netty-http.json | 17 +++++- .../src/main/docs/netty-http-component.adoc | 70 +--------------------- .../netty/http/DefaultNettyHttpBinding.java | 56 ++++++++--------- .../netty/http/NettyHttpConfiguration.java | 9 +-- .../component/netty/http/NettyHttpConstants.java | 45 ++++++++++++++ .../component/netty/http/NettyHttpConverter.java | 2 +- .../component/netty/http/NettyHttpEndpoint.java | 2 +- .../component/netty/http/NettyHttpHelper.java | 12 ++-- .../component/netty/http/NettyHttpProducer.java | 7 +-- .../http/handlers/HttpClientChannelHandler.java | 5 +- .../http/handlers/HttpServerChannelHandler.java | 19 +++--- .../HttpServerMultiplexChannelHandler.java | 7 ++- 12 files changed, 125 insertions(+), 126 deletions(-) diff --git a/components/camel-netty-http/src/generated/resources/org/apache/camel/component/netty/http/netty-http.json b/components/camel-netty-http/src/generated/resources/org/apache/camel/component/netty/http/netty-http.json index 6f7a9ab..0e88bd0 100644 --- a/components/camel-netty-http/src/generated/resources/org/apache/camel/component/netty/http/netty-http.json +++ b/components/camel-netty-http/src/generated/resources/org/apache/camel/component/netty/http/netty-http.json @@ -101,12 +101,27 @@ "trustStoreResource": { "kind": "property", "displayName": "Trust Store Resource", "group": "security", "label": "security", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.netty.NettyConfiguration", "configurationField": "configuration", "description": "Server side certificate keystore to be used for encryption. Is loaded by default from classpath, but you [...] "useGlobalSslContextParameters": { "kind": "property", "displayName": "Use Global Ssl Context Parameters", "group": "security", "label": "security", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "description": "Enable usage of global SSL context parameters." } }, + "headers": { + "CamelHttpAuthentication": { "kind": "header", "displayName": "", "group": "common", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "If the user was authenticated using HTTP Basic then this header is added with the value Basic." }, + "Content-Type": { "kind": "header", "displayName": "", "group": "common", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "To set the content-type of the HTTP body. For example: text\/plain; charset=UTF-8." }, + "connection": { "kind": "header", "displayName": "", "group": "common", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The value of the HTTP header connection to use." }, + "CamelNettyCloseChannelWhenComplete": { "kind": "header", "displayName": "", "group": "common", "label": "", "required": false, "javaType": "Boolean", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Indicates whether the channel should be closed after complete." }, + "CamelHttpResponseCode": { "kind": "header", "displayName": "", "group": "common", "label": "", "required": false, "javaType": "Integer", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Allows to set the HTTP Status code to use. By default 200 is used for success, and 500 for failure." }, + "CamelHttpProtocolVersion": { "kind": "header", "displayName": "", "group": "common", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": "HTTP\/1.1", "description": "The version of the HTTP protocol." }, + "CamelHttpMethod": { "kind": "header", "displayName": "", "group": "common", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "defaultValue": "GET", "description": "The HTTP method used, such as GET, POST, TRACE etc." }, + "CamelHttpQuery": { "kind": "header", "displayName": "", "group": "common", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Any query parameters, such as foo=bar&beer=yes" }, + "CamelHttpPath": { "kind": "header", "displayName": "", "group": "common", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Allows to provide URI context-path and query parameters as a String value that overrides the endpoint configuration. This allows to reuse the same producer for calling same remote http server, but using a dynamic context-path and query parameters." }, + "CamelHttpRawQuery": { "kind": "header", "displayName": "", "group": "common", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "Any query parameters, such as foo=bar&beer=yes. Stored in the raw form, as they arrived to the consumer (i.e. before URL decoding)." }, + "CamelHttpUrl": { "kind": "header", "displayName": "", "group": "common", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The URL including protocol, host and port, etc: http:\/\/0.0.0.0:8080\/myapp." }, + "CamelHttpCharacterEncoding": { "kind": "header", "displayName": "", "group": "common", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The charset from the content-type header." }, + "CamelHttpUri": { "kind": "header", "displayName": "", "group": "common", "label": "", "required": false, "javaType": "String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "description": "The URI without protocol, host and port, etc: \/myapp." } + }, "properties": { "protocol": { "kind": "path", "displayName": "Protocol", "group": "common", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "enum": [ "http", "https" ], "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.netty.http.NettyHttpConfiguration", "configurationField": "configuration", "description": "The protocol to use which is either http, https or proxy - a consumer only option." }, "host": { "kind": "path", "displayName": "Host", "group": "common", "label": "", "required": true, "type": "string", "javaType": "java.lang.String", "deprecated": false, "deprecationNote": "", "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.netty.http.NettyHttpConfiguration", "configurationField": "configuration", "description": "The local hostname such as localhost, or 0.0.0.0 when being a consumer. The remote HTTP server hostname when using pr [...] "port": { "kind": "path", "displayName": "Port", "group": "common", "label": "", "required": false, "type": "integer", "javaType": "int", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.netty.http.NettyHttpConfiguration", "configurationField": "configuration", "description": "The host port number" }, "path": { "kind": "path", "displayName": "Path", "group": "common", "label": "", "required": false, "type": "string", "javaType": "java.lang.String", "deprecated": false, "autowired": false, "secret": false, "configurationClass": "org.apache.camel.component.netty.http.NettyHttpConfiguration", "configurationField": "configuration", "description": "Resource path" }, - "bridgeEndpoint": { "kind": "parameter", "displayName": "Bridge Endpoint", "group": "common", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.netty.http.NettyHttpConfiguration", "configurationField": "configuration", "description": "If the option is true, the producer will ignore the Exchange.HTTP_URI header, and use the endpoint [...] + "bridgeEndpoint": { "kind": "parameter", "displayName": "Bridge Endpoint", "group": "common", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.netty.http.NettyHttpConfiguration", "configurationField": "configuration", "description": "If the option is true, the producer will ignore the NettyHttpConstants.HTTP_URI header, and use th [...] "disconnect": { "kind": "parameter", "displayName": "Disconnect", "group": "common", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": false, "configurationClass": "org.apache.camel.component.netty.http.NettyHttpConfiguration", "configurationField": "configuration", "description": "Whether or not to disconnect(close) from Netty Channel right after use. Can be used for both consumer and p [...] "keepAlive": { "kind": "parameter", "displayName": "Keep Alive", "group": "common", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "configurationClass": "org.apache.camel.component.netty.http.NettyHttpConfiguration", "configurationField": "configuration", "description": "Setting to ensure socket is not closed due to inactivity" }, "reuseAddress": { "kind": "parameter", "displayName": "Reuse Address", "group": "common", "label": "", "required": false, "type": "boolean", "javaType": "boolean", "deprecated": false, "autowired": false, "secret": false, "defaultValue": true, "configurationClass": "org.apache.camel.component.netty.http.NettyHttpConfiguration", "configurationField": "configuration", "description": "Setting to facilitate socket multiplexing" }, diff --git a/components/camel-netty-http/src/main/docs/netty-http-component.adoc b/components/camel-netty-http/src/main/docs/netty-http-component.adoc index 4b2ec19..b3b64fe 100644 --- a/components/camel-netty-http/src/main/docs/netty-http-component.adoc +++ b/components/camel-netty-http/src/main/docs/netty-http-component.adoc @@ -98,73 +98,9 @@ include::partial$component-endpoint-options.adoc[] // endpoint options: END - - -== Message Headers - -The following headers can be used on the producer to control the HTTP -request. - -[width="100%",cols="10%,10%,80%",options="header",] -|======================================================================= -|Name |Type |Description - -|`CamelHttpMethod` |`String` |Allow to control what HTTP method to use such as GET, POST, TRACE etc. -The type can also be a `io.netty.handler.codec.http.HttpMethod` -instance. - -|`CamelHttpQuery` |`String` |Allows to provide URI query parameters as a `String` value that -overrides the endpoint configuration. Separate multiple parameters using -the & sign. For example: `foo=bar&beer=yes`. - -|`CamelHttpPath` |`String` |Allows to provide URI context-path and query parameters as a `String` -value that overrides the endpoint configuration. This allows to reuse -the same producer for calling same remote http server, but using a -dynamic context-path and query parameters. - -|`Content-Type` |`String` |To set the content-type of the HTTP body. For example: -`text/plain; charset="UTF-8"`. - -|`CamelHttpResponseCode` |`int` |Allows to set the HTTP Status code to use. By default 200 is used for -success, and 500 for failure. -|======================================================================= - -The following headers is provided as meta-data when a route starts from -an Netty HTTP endpoint: - -The description in the table takes offset in a route having: -`from("netty-http:http:0.0.0.0:8080/myapp")...` - -[width="100%",cols="10%,10%,80%",options="header",] -|======================================================================= -|Name |Type |Description - -|`CamelHttpMethod` |`String` |The HTTP method used, such as GET, POST, TRACE etc. - -|`CamelHttpUrl` |`String` |The URL including protocol, host and port, etc: -`\http://0.0.0.0:8080/myapp` - -|`CamelHttpUri` |`String` |The URI without protocol, host and port, etc: -`/myapp` - -|`CamelHttpQuery` |`String` |Any query parameters, such as `foo=bar&beer=yes` - -|`CamelHttpRawQuery` |`String` |Any query parameters, such as `foo=bar&beer=yes`. Stored in the raw -form, as they arrived to the consumer (i.e. before URL decoding). - -|`CamelHttpPath` |`String` |Additional context-path. This value is empty if the client called the -context-path `/myapp`. If the client calls `/myapp/mystuff`, then this -header value is `/mystuff`. In other words its the value after the -context-path configured on the route endpoint. - -|`CamelHttpCharacterEncoding` |`String` |The charset from the content-type header. - -|`CamelHttpAuthentication` |`String` |If the user was authenticated using HTTP Basic then this header is added -with the value `Basic`. - -|`Content-Type` |`String` |The content type if provided. For example: -`text/plain; charset="UTF-8"`. -|======================================================================= +// component headers: START +include::partial$component-endpoint-headers.adoc[] +// component headers: END == Access to Netty types diff --git a/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/DefaultNettyHttpBinding.java b/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/DefaultNettyHttpBinding.java index 7d8b373..2819d3d 100644 --- a/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/DefaultNettyHttpBinding.java +++ b/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/DefaultNettyHttpBinding.java @@ -50,7 +50,6 @@ import org.apache.camel.ExtendedExchange; import org.apache.camel.Message; import org.apache.camel.RuntimeCamelException; import org.apache.camel.TypeConverter; -import org.apache.camel.component.netty.NettyConstants; import org.apache.camel.component.netty.NettyConverter; import org.apache.camel.spi.HeaderFilterStrategy; import org.apache.camel.support.ExchangeHelper; @@ -144,7 +143,7 @@ public class DefaultNettyHttpBinding implements NettyHttpBinding, Cloneable { // NOTE: these headers is applied using the same logic as camel-http/camel-jetty to be consistent - headers.put(Exchange.HTTP_METHOD, request.method().name()); + headers.put(NettyHttpConstants.HTTP_METHOD, request.method().name()); // strip query parameters from the uri String s = request.uri(); if (s.contains("?")) { @@ -163,13 +162,13 @@ public class DefaultNettyHttpBinding implements NettyHttpBinding, Cloneable { } } - headers.put(Exchange.HTTP_URL, s); + headers.put(NettyHttpConstants.HTTP_URL, s); // uri is without the host and port URI uri = new URI(request.uri()); // uri is path and query parameters - headers.put(Exchange.HTTP_URI, uri.getPath()); - headers.put(Exchange.HTTP_QUERY, uri.getQuery()); - headers.put(Exchange.HTTP_RAW_QUERY, uri.getRawQuery()); + headers.put(NettyHttpConstants.HTTP_URI, uri.getPath()); + headers.put(NettyHttpConstants.HTTP_QUERY, uri.getQuery()); + headers.put(NettyHttpConstants.HTTP_RAW_QUERY, uri.getRawQuery()); headers.put(Exchange.HTTP_SCHEME, uri.getScheme()); headers.put(Exchange.HTTP_HOST, uri.getHost()); final int port = uri.getPort(); @@ -186,7 +185,7 @@ public class DefaultNettyHttpBinding implements NettyHttpBinding, Cloneable { } } // keep the path uri using the case the request provided (do not convert to lower case) - headers.put(Exchange.HTTP_PATH, path); + headers.put(NettyHttpConstants.HTTP_PATH, path); if (LOG.isTraceEnabled()) { LOG.trace("HTTP-Method {}", request.method().name()); @@ -196,7 +195,7 @@ public class DefaultNettyHttpBinding implements NettyHttpBinding, Cloneable { for (String name : request.headers().names()) { // mapping the content-type if (name.equalsIgnoreCase("content-type")) { - name = Exchange.CONTENT_TYPE; + name = NettyHttpConstants.CONTENT_TYPE; } if (name.equalsIgnoreCase("authorization")) { @@ -224,8 +223,8 @@ public class DefaultNettyHttpBinding implements NettyHttpBinding, Cloneable { // add uri parameters as headers to the Camel message; // when acting as a HTTP proxy we don't want to place query // parameters in Camel message headers as the query parameters - // will be passed via Exchange.HTTP_QUERY, otherwise we could have - // both the Exchange.HTTP_QUERY and the values from the message + // will be passed via NettyHttpConstants.HTTP_QUERY, otherwise we could have + // both the NettyHttpConstants.HTTP_QUERY and the values from the message // headers, so we end up with two values for the same query // parameter if (!configuration.isHttpProxy() && request.uri().contains("?")) { @@ -251,8 +250,9 @@ public class DefaultNettyHttpBinding implements NettyHttpBinding, Cloneable { // if body is application/x-www-form-urlencoded then extract the body as query string and append as headers // if it is a bridgeEndpoint we need to skip this part of work // if we're proxying the body is a buffer that we do not want to consume directly - if (request.method().name().equals("POST") && request.headers().get(Exchange.CONTENT_TYPE) != null - && request.headers().get(Exchange.CONTENT_TYPE).startsWith(NettyHttpConstants.CONTENT_TYPE_WWW_FORM_URLENCODED) + if (request.method().name().equals("POST") && request.headers().get(NettyHttpConstants.CONTENT_TYPE) != null + && request.headers().get(NettyHttpConstants.CONTENT_TYPE) + .startsWith(NettyHttpConstants.CONTENT_TYPE_WWW_FORM_URLENCODED) && !configuration.isBridgeEndpoint() && !configuration.isHttpProxy() && request instanceof FullHttpRequest) { String charset = "UTF-8"; @@ -299,7 +299,7 @@ public class DefaultNettyHttpBinding implements NettyHttpBinding, Cloneable { NettyHttpConfiguration configuration, String headerName, Object value, String charset) throws UnsupportedEncodingException { // do not decode Content-Type - if (Exchange.CONTENT_TYPE.equals(headerName)) { + if (NettyHttpConstants.CONTENT_TYPE.equals(headerName)) { return value.toString(); } else if (configuration.isUrlDecodeHeaders()) { return URLDecoder.decode(value.toString(), charset); @@ -353,13 +353,13 @@ public class DefaultNettyHttpBinding implements NettyHttpBinding, Cloneable { HttpResponse response, Map<String, Object> headers, Exchange exchange, NettyHttpConfiguration configuration) { LOG.trace("populateCamelHeaders: {}", response); - headers.put(Exchange.HTTP_RESPONSE_CODE, response.status().code()); + headers.put(NettyHttpConstants.HTTP_RESPONSE_CODE, response.status().code()); headers.put(Exchange.HTTP_RESPONSE_TEXT, response.status().reasonPhrase()); for (String name : response.headers().names()) { // mapping the content-type if (name.equalsIgnoreCase("content-type")) { - name = Exchange.CONTENT_TYPE; + name = NettyHttpConstants.CONTENT_TYPE; } // add the headers one by one, and use the header filter strategy List<String> values = response.headers().getAll(name); @@ -414,7 +414,7 @@ public class DefaultNettyHttpBinding implements NettyHttpBinding, Cloneable { // the body should be the serialized java object of the exception body = NettyConverter.toByteBuffer(bos.toByteArray()); // force content type to be serialized java object - message.setHeader(Exchange.CONTENT_TYPE, NettyHttpConstants.CONTENT_TYPE_JAVA_SERIALIZED_OBJECT); + message.setHeader(NettyHttpConstants.CONTENT_TYPE, NettyHttpConstants.CONTENT_TYPE_JAVA_SERIALIZED_OBJECT); } else { // we failed due an exception so print it as plain text StringWriter sw = new StringWriter(); @@ -424,7 +424,7 @@ public class DefaultNettyHttpBinding implements NettyHttpBinding, Cloneable { // the body should then be the stacktrace body = NettyConverter.toByteBuffer(sw.toString().getBytes()); // force content type to be text/plain as that is what the stacktrace is - message.setHeader(Exchange.CONTENT_TYPE, "text/plain"); + message.setHeader(NettyHttpConstants.CONTENT_TYPE, "text/plain"); } // and mark the exception as failure handled, as we handled it by returning it as the response @@ -433,7 +433,7 @@ public class DefaultNettyHttpBinding implements NettyHttpBinding, Cloneable { // empty body body = NettyConverter.toByteBuffer("".getBytes()); // force content type to be text/plain - message.setHeader(Exchange.CONTENT_TYPE, "text/plain"); + message.setHeader(NettyHttpConstants.CONTENT_TYPE, "text/plain"); // and mark the exception as failure handled, as we handled it by actively muting it ExchangeHelper.setFailureHandled(message.getExchange()); @@ -516,10 +516,10 @@ public class DefaultNettyHttpBinding implements NettyHttpBinding, Cloneable { // configure connection to accordingly to keep alive configuration // favor using the header from the message - String connection = message.getHeader(HttpHeaderNames.CONNECTION.toString(), String.class); + String connection = message.getHeader(NettyHttpConstants.CONNECTION, String.class); // Read the connection header from the exchange property if (connection == null) { - connection = message.getExchange().getProperty(HttpHeaderNames.CONNECTION.toString(), String.class); + connection = message.getExchange().getProperty(NettyHttpConstants.CONNECTION, String.class); } if (connection == null) { // fallback and use the keep alive from the configuration @@ -529,10 +529,10 @@ public class DefaultNettyHttpBinding implements NettyHttpBinding, Cloneable { connection = HttpHeaderValues.CLOSE.toString(); } } - response.headers().set(HttpHeaderNames.CONNECTION.toString(), connection); + response.headers().set(NettyHttpConstants.CONNECTION, connection); // Just make sure we close the channel when the connection value is close if (connection.equalsIgnoreCase(HttpHeaderValues.CLOSE.toString())) { - message.setHeader(NettyConstants.NETTY_CLOSE_CHANNEL_WHEN_COMPLETE, true); + message.setHeader(NettyHttpConstants.NETTY_CLOSE_CHANNEL_WHEN_COMPLETE, true); } LOG.trace("Connection: {}", connection); @@ -547,7 +547,7 @@ public class DefaultNettyHttpBinding implements NettyHttpBinding, Cloneable { int defaultCode = failed ? 500 : 200; Message message = camelExchange.getMessage(); - Integer currentCode = message.getHeader(Exchange.HTTP_RESPONSE_CODE, Integer.class); + Integer currentCode = message.getHeader(NettyHttpConstants.HTTP_RESPONSE_CODE, Integer.class); int codeToUse = currentCode == null ? defaultCode : currentCode; if (codeToUse != 500) { @@ -583,7 +583,7 @@ public class DefaultNettyHttpBinding implements NettyHttpBinding, Cloneable { } } - final String headerProtocolVersion = message.getHeader(Exchange.HTTP_PROTOCOL_VERSION, String.class); + final String headerProtocolVersion = message.getHeader(NettyHttpConstants.HTTP_PROTOCOL_VERSION, String.class); final HttpVersion protocol; if (headerProtocolVersion == null) { protocol = HttpVersion.HTTP_1_1; @@ -591,7 +591,7 @@ public class DefaultNettyHttpBinding implements NettyHttpBinding, Cloneable { protocol = HttpVersion.valueOf(headerProtocolVersion); } - final String headerMethod = message.getHeader(Exchange.HTTP_METHOD, String.class); + final String headerMethod = message.getHeader(NettyHttpConstants.HTTP_METHOD, String.class); final HttpMethod httpMethod; if (headerMethod == null) { @@ -667,7 +667,7 @@ public class DefaultNettyHttpBinding implements NettyHttpBinding, Cloneable { // duplicated headers to the receiver, so use this skipRequestHeaders as the list of headers to skip Map<String, Object> skipRequestHeaders = null; if (configuration.isBridgeEndpoint()) { - String queryString = message.getHeader(Exchange.HTTP_QUERY, String.class); + String queryString = message.getHeader(NettyHttpConstants.HTTP_QUERY, String.class); if (queryString != null) { skipRequestHeaders = URISupport.parseQuery(queryString, false, true); } @@ -718,7 +718,7 @@ public class DefaultNettyHttpBinding implements NettyHttpBinding, Cloneable { // configure connection to accordingly to keep alive configuration // favor using the header from the message - String connection = message.getHeader(HttpHeaderNames.CONNECTION.toString(), String.class); + String connection = message.getHeader(NettyHttpConstants.CONNECTION, String.class); if (connection == null) { // fallback and use the keep alive from the configuration if (configuration.isKeepAlive()) { @@ -728,7 +728,7 @@ public class DefaultNettyHttpBinding implements NettyHttpBinding, Cloneable { } } - request.headers().set(HttpHeaderNames.CONNECTION.toString(), connection); + request.headers().set(NettyHttpConstants.CONNECTION, connection); LOG.trace("Connection: {}", connection); return request; diff --git a/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpConfiguration.java b/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpConfiguration.java index 5949dcd..5c24266 100644 --- a/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpConfiguration.java +++ b/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpConfiguration.java @@ -253,10 +253,11 @@ public class NettyHttpConfiguration extends NettyConfiguration { } /** - * If the option is true, the producer will ignore the Exchange.HTTP_URI header, and use the endpoint's URI for - * request. You may also set the throwExceptionOnFailure to be false to let the producer send all the fault response - * back. The consumer working in the bridge mode will skip the gzip compression and WWW URL form encoding (by adding - * the Exchange.SKIP_GZIP_ENCODING and Exchange.SKIP_WWW_FORM_URLENCODED headers to the consumed exchange). + * If the option is true, the producer will ignore the NettyHttpConstants.HTTP_URI header, and use the endpoint's + * URI for request. You may also set the throwExceptionOnFailure to be false to let the producer send all the fault + * response back. The consumer working in the bridge mode will skip the gzip compression and WWW URL form encoding + * (by adding the Exchange.SKIP_GZIP_ENCODING and Exchange.SKIP_WWW_FORM_URLENCODED headers to the consumed + * exchange). */ public void setBridgeEndpoint(boolean bridgeEndpoint) { this.bridgeEndpoint = bridgeEndpoint; diff --git a/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpConstants.java b/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpConstants.java index 3dc3a1f..f22d82a 100644 --- a/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpConstants.java +++ b/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpConstants.java @@ -16,7 +16,10 @@ */ package org.apache.camel.component.netty.http; +import io.netty.handler.codec.http.HttpHeaderNames; import org.apache.camel.Exchange; +import org.apache.camel.component.netty.NettyConstants; +import org.apache.camel.spi.Metadata; /** * Netty HTTP constants. @@ -27,8 +30,50 @@ public final class NettyHttpConstants { public static final String CONTENT_TYPE_WWW_FORM_URLENCODED = "application/x-www-form-urlencoded"; @Deprecated public static final String HTTP_RESPONSE_TEXT = Exchange.HTTP_RESPONSE_TEXT; + @Metadata(description = "If the user was authenticated using HTTP Basic then this header is added\n" + + "with the value `Basic`.", + javaType = "String") public static final String HTTP_AUTHENTICATION = "CamelHttpAuthentication"; + @Metadata(description = "To set the content-type of the HTTP body. For example:\n" + + "`text/plain; charset=\"UTF-8\"`.", + javaType = "String") + public static final String CONTENT_TYPE = Exchange.CONTENT_TYPE; + @Metadata(description = "The value of the HTTP header connection to use.", javaType = "String") + public static final String CONNECTION = HttpHeaderNames.CONNECTION.toString(); + @Metadata(description = "Indicates whether the channel should be closed after complete.", javaType = "Boolean") + public static final String NETTY_CLOSE_CHANNEL_WHEN_COMPLETE = NettyConstants.NETTY_CLOSE_CHANNEL_WHEN_COMPLETE; + @Metadata(description = "Allows to set the HTTP Status code to use. By default 200 is used for\n" + + "success, and 500 for failure.", + javaType = "Integer") + public static final String HTTP_RESPONSE_CODE = Exchange.HTTP_RESPONSE_CODE; + @Metadata(description = "The version of the HTTP protocol.", javaType = "String", defaultValue = "HTTP/1.1") + public static final String HTTP_PROTOCOL_VERSION = Exchange.HTTP_PROTOCOL_VERSION; + @Metadata(description = "The HTTP method used, such as GET, POST, TRACE etc.", javaType = "String", defaultValue = "GET") + public static final String HTTP_METHOD = Exchange.HTTP_METHOD; + @Metadata(description = "Any query parameters, such as `foo=bar&beer=yes`", javaType = "String") + public static final String HTTP_QUERY = Exchange.HTTP_QUERY; + @Metadata(description = "Allows to provide URI context-path and query parameters as a `String`\n" + + "value that overrides the endpoint configuration. This allows to reuse\n" + + "the same producer for calling same remote http server, but using a\n" + + "dynamic context-path and query parameters.", + javaType = "String") + public static final String HTTP_PATH = Exchange.HTTP_PATH; + @Metadata(description = "Any query parameters, such as `foo=bar&beer=yes`. Stored in the raw\n" + + "form, as they arrived to the consumer (i.e. before URL decoding).", + javaType = "String") + public static final String HTTP_RAW_QUERY = Exchange.HTTP_RAW_QUERY; + @Metadata(description = "The URL including protocol, host and port, etc: \n" + + "`\\http://0.0.0.0:8080/myapp`.", + javaType = "String") + public static final String HTTP_URL = Exchange.HTTP_URL; + @Metadata(description = "The charset from the content-type header.", javaType = "String") + public static final String HTTP_CHARACTER_ENCODING = Exchange.HTTP_CHARACTER_ENCODING; + @Metadata(description = "The URI without protocol, host and port, etc:\n" + + "`/myapp`.", + javaType = "String") + public static final String HTTP_URI = Exchange.HTTP_URI; + private NettyHttpConstants() { } } diff --git a/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpConverter.java b/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpConverter.java index 57a1a5f..f7afabf 100644 --- a/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpConverter.java +++ b/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpConverter.java @@ -86,7 +86,7 @@ public final class NettyHttpConverter { @Converter public static String toString(FullHttpResponse response, Exchange exchange) { - String contentType = response.headers().get(Exchange.CONTENT_TYPE); + String contentType = response.headers().get(NettyHttpConstants.CONTENT_TYPE); String charset = NettyHttpHelper.getCharsetFromContentType(contentType); if (charset == null && exchange != null) { charset = exchange.getProperty(ExchangePropertyKey.CHARSET_NAME, String.class); diff --git a/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpEndpoint.java b/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpEndpoint.java index 5b93f30..65b41a1 100644 --- a/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpEndpoint.java +++ b/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpEndpoint.java @@ -43,7 +43,7 @@ import org.slf4j.LoggerFactory; */ @UriEndpoint(firstVersion = "2.14.0", scheme = "netty-http", extendsScheme = "netty", title = "Netty HTTP", syntax = "netty-http:protocol://host:port/path", category = { Category.NETWORKING, Category.HTTP }, - lenientProperties = true) + lenientProperties = true, headersClass = NettyHttpConstants.class) @Metadata(excludeProperties = "textline,delimiter,autoAppendDelimiter,decoderMaxLineLength,encoding,allowDefaultCodec,udpConnectionlessSending,networkInterface" + ",clientMode,reconnect,reconnectInterval,useByteBuf,udpByteArrayCodec,broadcast,correlationManager") public class NettyHttpEndpoint extends NettyEndpoint implements AsyncEndpoint, HeaderFilterStrategyAware { diff --git a/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpHelper.java b/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpHelper.java index 25ade42..3c4fdec 100644 --- a/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpHelper.java +++ b/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpHelper.java @@ -104,11 +104,11 @@ public final class NettyHttpHelper { */ public static HttpMethod createMethod(Message message, boolean hasPayload) { // use header first - HttpMethod m = message.getHeader(Exchange.HTTP_METHOD, HttpMethod.class); + HttpMethod m = message.getHeader(NettyHttpConstants.HTTP_METHOD, HttpMethod.class); if (m != null) { return m; } - String name = message.getHeader(Exchange.HTTP_METHOD, String.class); + String name = message.getHeader(NettyHttpConstants.HTTP_METHOD, String.class); if (name != null) { // must be in upper case name = name.toUpperCase(); @@ -140,7 +140,7 @@ public final class NettyHttpHelper { } if (transferException) { - String contentType = response.headers().get(Exchange.CONTENT_TYPE); + String contentType = response.headers().get(NettyHttpConstants.CONTENT_TYPE); if (NettyHttpConstants.CONTENT_TYPE_JAVA_SERIALIZED_OBJECT.equals(contentType)) { // if the response was a serialized exception then use that InputStream is = exchange.getContext().getTypeConverter().convertTo(InputStream.class, response); @@ -201,7 +201,7 @@ public final class NettyHttpHelper { } // append HTTP_PATH to HTTP_URI if it is provided in the header - String path = exchange.getIn().getHeader(Exchange.HTTP_PATH, String.class); + String path = exchange.getIn().getHeader(NettyHttpConstants.HTTP_PATH, String.class); // NOW the HTTP_PATH is just related path, we don't need to trim it if (path != null && !path.isEmpty()) { if (path.startsWith("/")) { @@ -247,10 +247,10 @@ public final class NettyHttpHelper { // is a query string provided in the endpoint URI or in a header // (header overrules endpoint, raw query header overrules query header) if (queryString == null) { - queryString = exchange.getIn().getHeader(Exchange.HTTP_RAW_QUERY, String.class); + queryString = exchange.getIn().getHeader(NettyHttpConstants.HTTP_RAW_QUERY, String.class); } if (queryString == null) { - queryString = exchange.getIn().getHeader(Exchange.HTTP_QUERY, String.class); + queryString = exchange.getIn().getHeader(NettyHttpConstants.HTTP_QUERY, String.class); } if (queryString == null) { // use raw as we encode just below diff --git a/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpProducer.java b/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpProducer.java index 05c7132..42f83ca 100644 --- a/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpProducer.java +++ b/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/NettyHttpProducer.java @@ -28,7 +28,6 @@ import org.apache.camel.AsyncCallback; import org.apache.camel.Exchange; import org.apache.camel.ExtendedExchange; import org.apache.camel.component.netty.NettyConfiguration; -import org.apache.camel.component.netty.NettyConstants; import org.apache.camel.component.netty.NettyProducer; import org.apache.camel.http.base.cookie.CookieHandler; import org.apache.camel.support.SynchronizationAdapter; @@ -91,11 +90,11 @@ public class NettyHttpProducer extends NettyProducer { final NettyHttpBinding nettyHttpBinding = endpoint.getNettyHttpBinding(); final HttpRequest request = nettyHttpBinding.toNettyRequest(exchange.getIn(), u.toString(), getConfiguration()); - exchange.getIn().setHeader(Exchange.HTTP_URL, uri); + exchange.getIn().setHeader(NettyHttpConstants.HTTP_URL, uri); // Need to check if we need to close the connection or not if (!HttpUtil.isKeepAlive(request)) { // just want to make sure we close the channel if the keepAlive is not true - exchange.setProperty(NettyConstants.NETTY_CLOSE_CHANNEL_WHEN_COMPLETE, true); + exchange.setProperty(NettyHttpConstants.NETTY_CLOSE_CHANNEL_WHEN_COMPLETE, true); } if (getConfiguration().isBridgeEndpoint()) { // Need to remove the Host key as it should be not used when bridging/proxying @@ -155,7 +154,7 @@ public class NettyHttpProducer extends NettyProducer { }); // the actual url is stored on the IN message in the getRequestBody method as its accessed on-demand - String actualUrl = exchange.getIn().getHeader(Exchange.HTTP_URL, String.class); + String actualUrl = exchange.getIn().getHeader(NettyHttpConstants.HTTP_URL, String.class); int code = response.status() != null ? response.status().code() : -1; LOG.debug("Http responseCode: {}", code); diff --git a/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/handlers/HttpClientChannelHandler.java b/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/handlers/HttpClientChannelHandler.java index f5bcdee..1485af2 100644 --- a/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/handlers/HttpClientChannelHandler.java +++ b/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/handlers/HttpClientChannelHandler.java @@ -31,6 +31,7 @@ import org.apache.camel.Message; import org.apache.camel.component.netty.NettyConstants; import org.apache.camel.component.netty.handlers.ClientChannelHandler; import org.apache.camel.component.netty.http.InboundStreamHttpResponse; +import org.apache.camel.component.netty.http.NettyHttpConstants; import org.apache.camel.component.netty.http.NettyHttpProducer; /** @@ -70,11 +71,11 @@ public class HttpClientChannelHandler extends ClientChannelHandler { if (!HttpUtil.isKeepAlive(response)) { // just want to make sure we close the channel if the keepAlive is not true - exchange.setProperty(NettyConstants.NETTY_CLOSE_CHANNEL_WHEN_COMPLETE, true); + exchange.setProperty(NettyHttpConstants.NETTY_CLOSE_CHANNEL_WHEN_COMPLETE, true); } // handle cookies if (producer.getEndpoint().getCookieHandler() != null) { - String actualUri = exchange.getIn().getHeader(Exchange.HTTP_URL, String.class); + String actualUri = exchange.getIn().getHeader(NettyHttpConstants.HTTP_URL, String.class); URI uri = new URI(actualUri); Map<String, List<String>> m = new HashMap<>(); for (String name : response.headers().names()) { diff --git a/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/handlers/HttpServerChannelHandler.java b/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/handlers/HttpServerChannelHandler.java index dea2054..4b36183 100644 --- a/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/handlers/HttpServerChannelHandler.java +++ b/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/handlers/HttpServerChannelHandler.java @@ -45,6 +45,7 @@ import org.apache.camel.component.netty.handlers.ServerChannelHandler; import org.apache.camel.component.netty.http.HttpPrincipal; import org.apache.camel.component.netty.http.InboundStreamHttpRequest; import org.apache.camel.component.netty.http.NettyHttpConfiguration; +import org.apache.camel.component.netty.http.NettyHttpConstants; import org.apache.camel.component.netty.http.NettyHttpConsumer; import org.apache.camel.component.netty.http.NettyHttpHelper; import org.apache.camel.component.netty.http.NettyHttpSecurityConfiguration; @@ -101,7 +102,7 @@ public class HttpServerChannelHandler extends ServerChannelHandler { } } HttpResponse response = new DefaultHttpResponse(HTTP_1_1, BAD_REQUEST); - response.headers().set(Exchange.CONTENT_TYPE, "text/plain"); + response.headers().set(NettyHttpConstants.CONTENT_TYPE, "text/plain"); response.headers().set(Exchange.CONTENT_LENGTH, 0); ctx.writeAndFlush(response); ctx.channel().close(); @@ -112,7 +113,7 @@ public class HttpServerChannelHandler extends ServerChannelHandler { // are we suspended? LOG.debug("Consumer suspended, cannot service request {}", request); HttpResponse response = new DefaultHttpResponse(HTTP_1_1, SERVICE_UNAVAILABLE); - response.headers().set(Exchange.CONTENT_TYPE, "text/plain"); + response.headers().set(NettyHttpConstants.CONTENT_TYPE, "text/plain"); response.headers().set(Exchange.CONTENT_LENGTH, 0); ctx.writeAndFlush(response); ctx.channel().close(); @@ -122,7 +123,7 @@ public class HttpServerChannelHandler extends ServerChannelHandler { if (consumer.getEndpoint().getHttpMethodRestrict() != null && !consumer.getEndpoint().getHttpMethodRestrict().contains(request.method().name())) { HttpResponse response = new DefaultHttpResponse(HTTP_1_1, METHOD_NOT_ALLOWED); - response.headers().set(Exchange.CONTENT_TYPE, "text/plain"); + response.headers().set(NettyHttpConstants.CONTENT_TYPE, "text/plain"); response.headers().set(Exchange.CONTENT_LENGTH, 0); ctx.writeAndFlush(response); ctx.channel().close(); @@ -130,7 +131,7 @@ public class HttpServerChannelHandler extends ServerChannelHandler { } if ("TRACE".equals(request.method().name()) && !consumer.getEndpoint().isTraceEnabled()) { HttpResponse response = new DefaultHttpResponse(HTTP_1_1, METHOD_NOT_ALLOWED); - response.headers().set(Exchange.CONTENT_TYPE, "text/plain"); + response.headers().set(NettyHttpConstants.CONTENT_TYPE, "text/plain"); response.headers().set(Exchange.CONTENT_LENGTH, 0); ctx.writeAndFlush(response); ctx.channel().close(); @@ -140,7 +141,7 @@ public class HttpServerChannelHandler extends ServerChannelHandler { if (!request.headers().contains(HttpHeaderNames.HOST.toString())) { HttpResponse response = new DefaultHttpResponse(HTTP_1_1, BAD_REQUEST); //response.setChunked(false); - response.headers().set(Exchange.CONTENT_TYPE, "text/plain"); + response.headers().set(NettyHttpConstants.CONTENT_TYPE, "text/plain"); response.headers().set(Exchange.CONTENT_LENGTH, 0); ctx.writeAndFlush(response); ctx.channel().close(); @@ -208,7 +209,7 @@ public class HttpServerChannelHandler extends ServerChannelHandler { // restricted resource, so send back 401 to require valid username/password HttpResponse response = new DefaultHttpResponse(HTTP_1_1, UNAUTHORIZED); response.headers().set("WWW-Authenticate", "Basic realm=\"" + security.getRealm() + "\""); - response.headers().set(Exchange.CONTENT_TYPE, "text/plain"); + response.headers().set(NettyHttpConstants.CONTENT_TYPE, "text/plain"); response.headers().set(Exchange.CONTENT_LENGTH, 0); ctx.writeAndFlush(response); // close the channel @@ -312,7 +313,7 @@ public class HttpServerChannelHandler extends ServerChannelHandler { boolean keepAlive = HttpUtil.isKeepAlive(request); if (!keepAlive) { // Just make sure we close the connection this time. - exchange.setProperty(HttpHeaderNames.CONNECTION.toString(), HttpHeaderValues.CLOSE.toString()); + exchange.setProperty(NettyHttpConstants.CONNECTION, HttpHeaderValues.CLOSE.toString()); } final Message in = exchange.getIn(); @@ -359,11 +360,11 @@ public class HttpServerChannelHandler extends ServerChannelHandler { consumer.getEndpoint().updateMessageHeader(in, ctx); // honor the character encoding - String contentType = in.getHeader(Exchange.CONTENT_TYPE, String.class); + String contentType = in.getHeader(NettyHttpConstants.CONTENT_TYPE, String.class); String charset = NettyHttpHelper.getCharsetFromContentType(contentType); if (charset != null) { exchange.setProperty(ExchangePropertyKey.CHARSET_NAME, charset); - in.setHeader(Exchange.HTTP_CHARACTER_ENCODING, charset); + in.setHeader(NettyHttpConstants.HTTP_CHARACTER_ENCODING, charset); } return exchange; diff --git a/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/handlers/HttpServerMultiplexChannelHandler.java b/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/handlers/HttpServerMultiplexChannelHandler.java index d6dfa99..3cfa386 100644 --- a/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/handlers/HttpServerMultiplexChannelHandler.java +++ b/components/camel-netty-http/src/main/java/org/apache/camel/component/netty/http/handlers/HttpServerMultiplexChannelHandler.java @@ -39,6 +39,7 @@ import org.apache.camel.Exchange; import org.apache.camel.component.netty.http.HttpServerConsumerChannelFactory; import org.apache.camel.component.netty.http.InboundStreamHttpRequest; import org.apache.camel.component.netty.http.NettyHttpConfiguration; +import org.apache.camel.component.netty.http.NettyHttpConstants; import org.apache.camel.component.netty.http.NettyHttpConsumer; import org.apache.camel.support.RestConsumerContextPathMatcher; import org.apache.camel.util.UnsafeUriCharactersEncoder; @@ -145,7 +146,7 @@ public class HttpServerMultiplexChannelHandler extends SimpleChannelInboundHandl } HttpResponse response = new DefaultHttpResponse(HTTP_1_1, OK); - response.headers().set(Exchange.CONTENT_TYPE, "text/plain"); + response.headers().set(NettyHttpConstants.CONTENT_TYPE, "text/plain"); response.headers().set(Exchange.CONTENT_LENGTH, 0); response.headers().set("Allow", allowedMethods); ctx.writeAndFlush(response); @@ -173,7 +174,7 @@ public class HttpServerMultiplexChannelHandler extends SimpleChannelInboundHandl // this resource is not found, return 404 response = new DefaultHttpResponse(HTTP_1_1, NOT_FOUND); } - response.headers().set(Exchange.CONTENT_TYPE, "text/plain"); + response.headers().set(NettyHttpConstants.CONTENT_TYPE, "text/plain"); response.headers().set(Exchange.CONTENT_LENGTH, 0); ctx.writeAndFlush(response); ctx.close(); @@ -198,7 +199,7 @@ public class HttpServerMultiplexChannelHandler extends SimpleChannelInboundHandl cause); // Now we just send 404 back to the client HttpResponse response = new DefaultHttpResponse(HTTP_1_1, NOT_FOUND); - response.headers().set(Exchange.CONTENT_TYPE, "text/plain"); + response.headers().set(NettyHttpConstants.CONTENT_TYPE, "text/plain"); response.headers().set(Exchange.CONTENT_LENGTH, 0); ctx.writeAndFlush(response); ctx.close();
