CAMEL-9831: Camel-http4: Make possible to use System Properties for configuration
Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/6c0b37a4 Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/6c0b37a4 Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/6c0b37a4 Branch: refs/heads/master Commit: 6c0b37a4f404f3df635f71069b82c3f8a38f4017 Parents: 592e1cd Author: Andrea Cosentino <anco...@gmail.com> Authored: Thu Apr 7 12:07:10 2016 +0200 Committer: Andrea Cosentino <anco...@gmail.com> Committed: Thu Apr 7 13:04:31 2016 +0200 ---------------------------------------------------------------------- .../camel/component/http4/HttpEndpoint.java | 38 +++-- ...HttpProxyServerWithSystemPropertiesTest.java | 165 +++++++++++++++++++ 2 files changed, 192 insertions(+), 11 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/6c0b37a4/components/camel-http4/src/main/java/org/apache/camel/component/http4/HttpEndpoint.java ---------------------------------------------------------------------- diff --git a/components/camel-http4/src/main/java/org/apache/camel/component/http4/HttpEndpoint.java b/components/camel-http4/src/main/java/org/apache/camel/component/http4/HttpEndpoint.java index 63c6ba2..6809713 100644 --- a/components/camel-http4/src/main/java/org/apache/camel/component/http4/HttpEndpoint.java +++ b/components/camel-http4/src/main/java/org/apache/camel/component/http4/HttpEndpoint.java @@ -62,6 +62,8 @@ public class HttpEndpoint extends HttpCommonEndpoint { private HttpClientBuilder clientBuilder; @UriParam(label = "advanced") private HttpClient httpClient; + @UriParam(label = "advanced", defaultValue = "false") + private boolean useSystemProperties; @UriParam(label = "producer") private CookieStore cookieStore = new BasicCookieStore(); @@ -140,18 +142,22 @@ public class HttpEndpoint extends HttpCommonEndpoint { clientBuilder.setConnectionManagerShared(true); } - // configure http proxy from camelContext - if (ObjectHelper.isNotEmpty(getCamelContext().getProperty("http.proxyHost")) && ObjectHelper.isNotEmpty(getCamelContext().getProperty("http.proxyPort"))) { - String host = getCamelContext().getProperty("http.proxyHost"); - int port = Integer.parseInt(getCamelContext().getProperty("http.proxyPort")); - String scheme = getCamelContext().getProperty("http.proxyScheme"); - // fallback and use either http or https depending on secure - if (scheme == null) { - scheme = HttpHelper.isSecureConnection(getEndpointUri()) ? "https" : "http"; + if (!useSystemProperties) { + // configure http proxy from camelContext + if (ObjectHelper.isNotEmpty(getCamelContext().getProperty("http.proxyHost")) && ObjectHelper.isNotEmpty(getCamelContext().getProperty("http.proxyPort"))) { + String host = getCamelContext().getProperty("http.proxyHost"); + int port = Integer.parseInt(getCamelContext().getProperty("http.proxyPort")); + String scheme = getCamelContext().getProperty("http.proxyScheme"); + // fallback and use either http or https depending on secure + if (scheme == null) { + scheme = HttpHelper.isSecureConnection(getEndpointUri()) ? "https" : "http"; + } + LOG.debug("CamelContext properties http.proxyHost, http.proxyPort, and http.proxyScheme detected. Using http proxy host: {} port: {} scheme: {}", new Object[]{host, port, scheme}); + HttpHost proxy = new HttpHost(host, port, scheme); + clientBuilder.setProxy(proxy); } - LOG.debug("CamelContext properties http.proxyHost, http.proxyPort, and http.proxyScheme detected. Using http proxy host: {} port: {} scheme: {}", new Object[]{host, port, scheme}); - HttpHost proxy = new HttpHost(host, port, scheme); - clientBuilder.setProxy(proxy); + } else { + clientBuilder.useSystemProperties(); } if (isAuthenticationPreemptive()) { @@ -290,4 +296,14 @@ public class HttpEndpoint extends HttpCommonEndpoint { this.httpClientOptions = httpClientOptions; } + public boolean isUseSystemProperties() { + return useSystemProperties; + } + + /** + * To use System Properties as fallback for configuration + */ + public void setUseSystemProperties(boolean useSystemProperties) { + this.useSystemProperties = useSystemProperties; + } } http://git-wip-us.apache.org/repos/asf/camel/blob/6c0b37a4/components/camel-http4/src/test/java/org/apache/camel/component/http4/HttpProxyServerWithSystemPropertiesTest.java ---------------------------------------------------------------------- diff --git a/components/camel-http4/src/test/java/org/apache/camel/component/http4/HttpProxyServerWithSystemPropertiesTest.java b/components/camel-http4/src/test/java/org/apache/camel/component/http4/HttpProxyServerWithSystemPropertiesTest.java new file mode 100644 index 0000000..0243e7a --- /dev/null +++ b/components/camel-http4/src/test/java/org/apache/camel/component/http4/HttpProxyServerWithSystemPropertiesTest.java @@ -0,0 +1,165 @@ +/** + * 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.http4; + +import java.io.IOException; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.camel.Exchange; +import org.apache.camel.Processor; +import org.apache.camel.component.http4.handler.HeaderValidationHandler; +import org.apache.camel.util.URISupport; +import org.apache.commons.codec.BinaryDecoder; +import org.apache.commons.codec.DecoderException; +import org.apache.commons.codec.binary.Base64; +import org.apache.http.Header; +import org.apache.http.HttpException; +import org.apache.http.HttpRequest; +import org.apache.http.HttpRequestInterceptor; +import org.apache.http.HttpResponse; +import org.apache.http.HttpResponseInterceptor; +import org.apache.http.HttpStatus; +import org.apache.http.ProtocolException; +import org.apache.http.auth.AUTH; +import org.apache.http.impl.bootstrap.HttpServer; +import org.apache.http.impl.bootstrap.ServerBootstrap; +import org.apache.http.protocol.HttpContext; +import org.apache.http.protocol.HttpProcessor; +import org.apache.http.protocol.ImmutableHttpProcessor; +import org.apache.http.protocol.ResponseContent; +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +/** + * + * @version + */ +public class HttpProxyServerWithSystemPropertiesTest extends BaseHttpTest { + + private HttpServer proxy; + + @Before + @Override + public void setUp() throws Exception { + Map<String, String> expectedHeaders = new HashMap<String, String>(); + expectedHeaders.put("Proxy-Connection", "Keep-Alive"); + proxy = ServerBootstrap.bootstrap(). + setHttpProcessor(getBasicHttpProcessor()). + setConnectionReuseStrategy(getConnectionReuseStrategy()). + setResponseFactory(getHttpResponseFactory()). + setExpectationVerifier(getHttpExpectationVerifier()). + setSslContext(getSSLContext()). + registerHandler("*", new HeaderValidationHandler("GET", null, null, getExpectedContent(), expectedHeaders)).create(); + proxy.start(); + + System.getProperties().setProperty("http.proxyHost", getProxyHost()); + System.getProperties().setProperty("http.proxyPort", String.valueOf(getProxyPort())); + + super.setUp(); + } + + @After + @Override + public void tearDown() throws Exception { + super.tearDown(); + + if (proxy != null) { + proxy.stop(); + } + } + + @Override + protected HttpProcessor getBasicHttpProcessor() { + List<HttpRequestInterceptor> requestInterceptors = new ArrayList<HttpRequestInterceptor>(); + requestInterceptors.add(new RequestProxyBasicAuth()); + List<HttpResponseInterceptor> responseInterceptors = new ArrayList<HttpResponseInterceptor>(); + responseInterceptors.add(new ResponseContent()); + responseInterceptors.add(new ResponseProxyBasicUnauthorized()); + ImmutableHttpProcessor httpproc = new ImmutableHttpProcessor(requestInterceptors, responseInterceptors); + return httpproc; + } + + + @Test + public void httpGetWithProxyFromSystemProperties() throws Exception { + + Exchange exchange = template.request("http4://" + getProxyHost() + ":" + getProxyPort() + "?useSystemProperties=true", new Processor() { + public void process(Exchange exchange) throws Exception { + } + }); + + assertExchange(exchange); + } + + private String getProxyHost() { + return proxy.getInetAddress().getHostName(); + } + + private int getProxyPort() { + return proxy.getLocalPort(); + } + + class RequestProxyBasicAuth implements HttpRequestInterceptor { + public void process(final HttpRequest request, final HttpContext context) throws HttpException, IOException { + String auth = null; + + String requestLine = request.getRequestLine().toString(); + // assert we set a write GET URI + if (requestLine.contains("http4://localhost")) { + throw new HttpException("Get a wrong proxy GET url"); + } + Header h = request.getFirstHeader(AUTH.PROXY_AUTH_RESP); + if (h != null) { + String s = h.getValue(); + if (s != null) { + auth = s.trim(); + } + } + + if (auth != null) { + int i = auth.indexOf(' '); + if (i == -1) { + throw new ProtocolException("Invalid Authorization header: " + auth); + } + String authscheme = auth.substring(0, i); + if (authscheme.equalsIgnoreCase("basic")) { + String s = auth.substring(i + 1).trim(); + byte[] credsRaw = s.getBytes("ASCII"); + BinaryDecoder codec = new Base64(); + try { + String creds = new String(codec.decode(credsRaw), "ASCII"); + context.setAttribute("proxy-creds", creds); + } catch (DecoderException ex) { + throw new ProtocolException("Malformed BASIC credentials"); + } + } + } + } + } + + class ResponseProxyBasicUnauthorized implements HttpResponseInterceptor { + public void process(final HttpResponse response, final HttpContext context) throws HttpException, IOException { + if (response.getStatusLine().getStatusCode() == HttpStatus.SC_PROXY_AUTHENTICATION_REQUIRED) { + response.addHeader(AUTH.PROXY_AUTH, "Basic realm=\"test realm\""); + } + } + } +} \ No newline at end of file