CAMEL-8272: Camel-box socks proxy implementation is incomplete. Thanks to Julian Cable for the patch.
Project: http://git-wip-us.apache.org/repos/asf/camel/repo Commit: http://git-wip-us.apache.org/repos/asf/camel/commit/984de3dd Tree: http://git-wip-us.apache.org/repos/asf/camel/tree/984de3dd Diff: http://git-wip-us.apache.org/repos/asf/camel/diff/984de3dd Branch: refs/heads/master Commit: 984de3dd78b73132a6d740718efa92cde78e0c82 Parents: 01c6c0a Author: Claus Ibsen <davscl...@apache.org> Authored: Fri Feb 6 12:34:33 2015 +0100 Committer: Claus Ibsen <davscl...@apache.org> Committed: Fri Feb 6 12:34:33 2015 +0100 ---------------------------------------------------------------------- .../camel/component/box/BoxConverter.java | 2 +- .../component/box/internal/BoxClientHelper.java | 92 +++++++++++++------- 2 files changed, 63 insertions(+), 31 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/camel/blob/984de3dd/components/camel-box/src/main/java/org/apache/camel/component/box/BoxConverter.java ---------------------------------------------------------------------- diff --git a/components/camel-box/src/main/java/org/apache/camel/component/box/BoxConverter.java b/components/camel-box/src/main/java/org/apache/camel/component/box/BoxConverter.java index c5a5b14..3713f83 100644 --- a/components/camel-box/src/main/java/org/apache/camel/component/box/BoxConverter.java +++ b/components/camel-box/src/main/java/org/apache/camel/component/box/BoxConverter.java @@ -16,9 +16,9 @@ */ package org.apache.camel.component.box; +import java.io.ByteArrayInputStream; import java.io.File; import java.io.InputStream; -import java.io.ByteArrayInputStream; import com.box.restclientv2.requestsbase.BoxFileUploadRequestObject; import org.apache.camel.Converter; http://git-wip-us.apache.org/repos/asf/camel/blob/984de3dd/components/camel-box/src/main/java/org/apache/camel/component/box/internal/BoxClientHelper.java ---------------------------------------------------------------------- diff --git a/components/camel-box/src/main/java/org/apache/camel/component/box/internal/BoxClientHelper.java b/components/camel-box/src/main/java/org/apache/camel/component/box/internal/BoxClientHelper.java index 54c3e49..71f1aca 100644 --- a/components/camel-box/src/main/java/org/apache/camel/component/box/internal/BoxClientHelper.java +++ b/components/camel-box/src/main/java/org/apache/camel/component/box/internal/BoxClientHelper.java @@ -17,31 +17,34 @@ package org.apache.camel.component.box.internal; import java.io.IOException; +import java.net.InetSocketAddress; +import java.net.Proxy; +import java.net.Socket; import java.security.GeneralSecurityException; import java.util.Map; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; +import javax.net.ssl.SSLContext; import com.box.boxjavalibv2.BoxClient; import com.box.boxjavalibv2.BoxConnectionManagerBuilder; import com.box.boxjavalibv2.BoxRESTClient; import com.box.boxjavalibv2.authorization.IAuthFlowUI; import com.box.boxjavalibv2.authorization.IAuthSecureStorage; -import com.box.boxjavalibv2.exceptions.AuthFatalFailureException; -import com.box.boxjavalibv2.exceptions.BoxServerException; import com.box.restclientv2.IBoxRESTClient; -import com.box.restclientv2.exceptions.BoxRestException; - import org.apache.camel.RuntimeCamelException; import org.apache.camel.component.box.BoxConfiguration; import org.apache.camel.util.ObjectHelper; import org.apache.camel.util.jsse.SSLContextParameters; +import org.apache.http.HttpHost; import org.apache.http.client.HttpClient; import org.apache.http.conn.ClientConnectionManager; +import org.apache.http.conn.params.ConnRoutePNames; import org.apache.http.conn.scheme.Scheme; import org.apache.http.conn.scheme.SchemeRegistry; import org.apache.http.conn.ssl.SSLSocketFactory; import org.apache.http.params.HttpParams; +import org.apache.http.protocol.HttpContext; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -67,17 +70,17 @@ public final class BoxClientHelper { final String userPassword = configuration.getUserPassword(); if ((authSecureStorage == null && ObjectHelper.isEmpty(userPassword)) - || ObjectHelper.isEmpty(userName) || ObjectHelper.isEmpty(clientId) || ObjectHelper.isEmpty(clientSecret)) { + || ObjectHelper.isEmpty(userName) || ObjectHelper.isEmpty(clientId) || ObjectHelper.isEmpty(clientSecret)) { throw new IllegalArgumentException( - "Missing one or more required properties " - + "clientId, clientSecret, userName and either authSecureStorage or userPassword"); + "Missing one or more required properties " + + "clientId, clientSecret, userName and either authSecureStorage or userPassword"); } LOG.debug("Creating BoxClient for login:{}, client_id:{} ...", userName, clientId); // if set, use configured connection manager builder final BoxConnectionManagerBuilder connectionManagerBuilder = configuration.getConnectionManagerBuilder(); final BoxConnectionManagerBuilder connectionManager = connectionManagerBuilder != null - ? connectionManagerBuilder : new BoxConnectionManagerBuilder(); + ? connectionManagerBuilder : new BoxConnectionManagerBuilder(); // create REST client for BoxClient final ClientConnectionManager[] clientConnectionManager = new ClientConnectionManager[1]; @@ -91,33 +94,48 @@ public final class BoxClientHelper { if (sslContextParameters == null) { sslContextParameters = new SSLContextParameters(); } - try { - final SSLSocketFactory socketFactory = new SSLSocketFactory( - sslContextParameters.createSSLContext(), - SSLSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); - schemeRegistry.register(new Scheme("https", socketFactory, 443)); - } catch (GeneralSecurityException e) { - throw ObjectHelper.wrapRuntimeCamelException(e); - } catch (IOException e) { - throw ObjectHelper.wrapRuntimeCamelException(e); - } - - // set custom HTTP params final Map<String, Object> configParams = configuration.getHttpParams(); + boolean useSocksProxy = false; + HttpHost proxyHost = null; if (configParams != null && !configParams.isEmpty()) { + final Boolean socksProxy = (Boolean) configParams.get("http.route.socks-proxy"); + if (socksProxy != null && socksProxy) { + useSocksProxy = true; + proxyHost = (HttpHost) configParams.get(ConnRoutePNames.DEFAULT_PROXY); + } + // set custom HTTP params LOG.debug("Setting {} HTTP Params", configParams.size()); final HttpParams httpParams = httpClient.getParams(); for (Map.Entry<String, Object> param : configParams.entrySet()) { - httpParams.setParameter(param.getKey(), param.getValue()); + // don't add proxy params if socks + if (!(useSocksProxy && (param.getKey().equals("http.route.socks-proxy") || param.getKey().equals(ConnRoutePNames.DEFAULT_PROXY)))) { + httpParams.setParameter(param.getKey(), param.getValue()); + } } + } + SSLContext sslContext; + try { + sslContext = sslContextParameters.createSSLContext(); + } catch (IOException e) { + throw ObjectHelper.wrapRuntimeCamelException(e); + } catch (GeneralSecurityException e) { + throw ObjectHelper.wrapRuntimeCamelException(e); + } + SSLSocketFactory socketFactory; + if (useSocksProxy) { + socketFactory = new SocksSSLSocketFactory(sslContext, proxyHost); + } else { + socketFactory = new SSLSocketFactory(sslContext, SSLSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); + } + schemeRegistry.register(new Scheme("https", socketFactory, 443)); return httpClient; } }; final BoxClient boxClient = new BoxClient(clientId, clientSecret, null, null, - restClient, configuration.getBoxConfig()); + restClient, configuration.getBoxConfig()); // enable OAuth auto-refresh boxClient.setAutoRefreshOAuth(true); @@ -134,8 +152,7 @@ public final class BoxClientHelper { return cachedBoxClient; } - public static void getOAuthToken(BoxConfiguration configuration, CachedBoxClient cachedBoxClient) - throws AuthFatalFailureException, BoxRestException, BoxServerException, InterruptedException { + public static void getOAuthToken(BoxConfiguration configuration, CachedBoxClient cachedBoxClient) throws Exception { final BoxClient boxClient = cachedBoxClient.getBoxClient(); synchronized (boxClient) { @@ -169,7 +186,7 @@ public final class BoxClientHelper { final Exception ex = listener.getException(); if (ex != null) { throw new RuntimeCamelException(String.format("Login error for %s: %s", - cachedBoxClient, ex.getMessage()), ex); + cachedBoxClient, ex.getMessage()), ex); } } @@ -188,8 +205,7 @@ public final class BoxClientHelper { } } - public static void shutdownBoxClient(BoxConfiguration configuration, CachedBoxClient cachedBoxClient) - throws BoxServerException, BoxRestException, AuthFatalFailureException { + public static void shutdownBoxClient(BoxConfiguration configuration, CachedBoxClient cachedBoxClient) throws Exception { final BoxClient boxClient = cachedBoxClient.getBoxClient(); synchronized (boxClient) { @@ -218,8 +234,7 @@ public final class BoxClientHelper { } } - private static void revokeOAuthToken(BoxConfiguration configuration, CachedBoxClient cachedBoxClient) - throws BoxServerException, BoxRestException, AuthFatalFailureException { + private static void revokeOAuthToken(BoxConfiguration configuration, CachedBoxClient cachedBoxClient) throws Exception { final BoxClient boxClient = cachedBoxClient.getBoxClient(); synchronized (boxClient) { @@ -230,7 +245,7 @@ public final class BoxClientHelper { // revoke OAuth token boxClient.getOAuthManager().revokeOAuth(boxClient.getAuthData().getAccessToken(), - configuration.getClientId(), configuration.getClientSecret()); + configuration.getClientId(), configuration.getClientSecret()); // notify the OAuthListener of revoked token cachedBoxClient.getListener().onRefresh(null); @@ -239,4 +254,21 @@ public final class BoxClientHelper { } } } + + static class SocksSSLSocketFactory extends SSLSocketFactory { + HttpHost proxyHost; + + public SocksSSLSocketFactory(SSLContext sslContext, HttpHost proxyHost) { + super(sslContext, SSLSocketFactory.BROWSER_COMPATIBLE_HOSTNAME_VERIFIER); + this.proxyHost = proxyHost; + } + + @Override + public Socket createSocket(final HttpContext context) throws IOException { + InetSocketAddress socksaddr = new InetSocketAddress(proxyHost.getHostName(), proxyHost.getPort()); + Proxy proxy = new Proxy(Proxy.Type.SOCKS, socksaddr); + return new Socket(proxy); + } + + } }