From 12a2a7bf870240a8980007ffd4d476010591e079 Mon Sep 17 00:00:00 2001 From: Julien Viet Date: Wed, 25 May 2016 21:38:02 +0200 Subject: [PATCH] Factor our the common channel provider and the proxy channel provider as singletons --- .../core/http/impl/ConnectionManager.java | 36 ++-------- .../vertx/core/net/impl/ChannelProvider.java | 71 +++++++++++++++++-- .../io/vertx/core/net/impl/NetClientImpl.java | 36 +--------- .../{proxy => }/ProxyChannelProvider.java | 32 +++------ 4 files changed, 82 insertions(+), 93 deletions(-) rename src/main/java/io/vertx/core/net/impl/{proxy => }/ProxyChannelProvider.java (81%) diff --git a/src/main/java/io/vertx/core/http/impl/ConnectionManager.java b/src/main/java/io/vertx/core/http/impl/ConnectionManager.java index cdcd7a5c00a..62477b0c39e 100644 --- a/src/main/java/io/vertx/core/http/impl/ConnectionManager.java +++ b/src/main/java/io/vertx/core/http/impl/ConnectionManager.java @@ -20,7 +20,6 @@ import io.netty.channel.Channel; import io.netty.channel.ChannelHandlerContext; import io.netty.channel.ChannelInboundHandlerAdapter; -import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelOption; import io.netty.channel.ChannelPipeline; import io.netty.channel.FixedRecvByteBufAllocator; @@ -38,7 +37,6 @@ import io.netty.handler.ssl.SslHandler; import io.netty.handler.timeout.IdleStateHandler; import io.vertx.core.AsyncResult; -import io.vertx.core.Future; import io.vertx.core.Handler; import io.vertx.core.http.ConnectionPoolTooBusyException; import io.vertx.core.http.HttpClientOptions; @@ -47,11 +45,9 @@ import io.vertx.core.impl.VertxInternal; import io.vertx.core.logging.Logger; import io.vertx.core.logging.LoggerFactory; -import io.vertx.core.net.ProxyOptions; -import io.vertx.core.net.impl.AsyncResolveBindConnectHelper; import io.vertx.core.net.impl.PartialPooledByteBufAllocator; +import io.vertx.core.net.impl.ProxyChannelProvider; import io.vertx.core.net.impl.SSLHelper; -import io.vertx.core.net.impl.proxy.ProxyChannelProvider; import io.vertx.core.net.impl.ChannelProvider; import javax.net.ssl.SSLHandshakeException; @@ -377,26 +373,9 @@ protected void internalConnect(ConnQueue queue, HttpVersion version, String host ChannelProvider channelProvider; if (options.getProxyOptions() == null) { - channelProvider = new ChannelProvider() { - @Override - public void connect(VertxInternal vertx, Bootstrap bootstrap, ProxyOptions options, String host, int port, Handler> channelHandler) { - bootstrap.handler(new ChannelInitializer() { - @Override - protected void initChannel(Channel ch) throws Exception { - } - }); - AsyncResolveBindConnectHelper future = AsyncResolveBindConnectHelper.doConnect(vertx, port, host, bootstrap); - future.addListener(res -> { - if (res.succeeded()) { - channelHandler.handle(Future.succeededFuture(res.result())); - } else { - channelHandler.handle(Future.failedFuture(res.cause())); - } - }); - } - }; + channelProvider = ChannelProvider.INSTANCE; } else { - channelProvider = new ProxyChannelProvider(); + channelProvider = ProxyChannelProvider.INSTANCE; } Handler> channelHandler = res -> { @@ -500,14 +479,7 @@ public void upgradeTo(ChannelHandlerContext ctx, FullHttpResponse upgradeRespons } }; - try { - channelProvider.connect(vertx, bootstrap, options.getProxyOptions(), host, port, channelHandler); - } catch (NoClassDefFoundError e) { - if (options.getProxyOptions() != null && e.getMessage().contains("io/netty/handler/proxy")) { - log.warn("Depedency io.netty:netty-handler-proxy missing - check your classpath"); - channelHandler.handle(Future.failedFuture(e)); - } - } + channelProvider.connect(vertx, bootstrap, options.getProxyOptions(), host, port, channelHandler); } void applyConnectionOptions(HttpClientOptions options, Bootstrap bootstrap) { diff --git a/src/main/java/io/vertx/core/net/impl/ChannelProvider.java b/src/main/java/io/vertx/core/net/impl/ChannelProvider.java index 47d7c81e12c..42d85e332fa 100644 --- a/src/main/java/io/vertx/core/net/impl/ChannelProvider.java +++ b/src/main/java/io/vertx/core/net/impl/ChannelProvider.java @@ -2,21 +2,78 @@ import io.netty.bootstrap.Bootstrap; import io.netty.channel.Channel; +import io.netty.channel.ChannelFuture; +import io.netty.channel.ChannelHandlerContext; +import io.netty.channel.ChannelInboundHandlerAdapter; +import io.netty.channel.ChannelInitializer; +import io.netty.channel.ChannelPipeline; +import io.netty.handler.proxy.HttpProxyHandler; +import io.netty.handler.proxy.ProxyConnectionEvent; +import io.netty.handler.proxy.ProxyHandler; +import io.netty.handler.proxy.Socks4ProxyHandler; +import io.netty.handler.proxy.Socks5ProxyHandler; +import io.netty.resolver.NoopAddressResolverGroup; import io.vertx.core.AsyncResult; +import io.vertx.core.Future; import io.vertx.core.Handler; import io.vertx.core.impl.VertxInternal; +import io.vertx.core.logging.Logger; +import io.vertx.core.logging.LoggerFactory; import io.vertx.core.net.ProxyOptions; +import io.vertx.core.net.ProxyType; + +import java.net.InetAddress; +import java.net.InetSocketAddress; /** + * The logic for connecting to an host, this implementations performs a connection + * to the host after resolving its internet address. + * * @author Julien Viet */ -public interface ChannelProvider { +public class ChannelProvider { + + public static final ChannelProvider INSTANCE = new ChannelProvider(); + + protected ChannelProvider() { + } + + static final Logger log = LoggerFactory.getLogger(NetClientImpl.class); - void connect(VertxInternal vertx, - Bootstrap bootstrap, - ProxyOptions options, - String host, - int port, - Handler> channelHandler); + public void connect(VertxInternal vertx, + Bootstrap bootstrap, + ProxyOptions options, + String host, + int port, + Handler> channelHandler) { + try { + doConnect(vertx, bootstrap, options, host, port, channelHandler); + } catch (NoClassDefFoundError e) { + if (e.getMessage().contains("io/netty/handler/proxy")) { + log.warn("Dependency io.netty:netty-handler-proxy missing - check your classpath"); + channelHandler.handle(Future.failedFuture(e)); + } + } + } + protected void doConnect(VertxInternal vertx, + Bootstrap bootstrap, + ProxyOptions options, + String host, + int port, + Handler> channelHandler) { + bootstrap.handler(new ChannelInitializer() { + @Override + protected void initChannel(Channel ch) throws Exception { + } + }); + AsyncResolveBindConnectHelper future = AsyncResolveBindConnectHelper.doConnect(vertx, port, host, bootstrap); + future.addListener(res -> { + if (res.succeeded()) { + channelHandler.handle(Future.succeededFuture(res.result())); + } else { + channelHandler.handle(Future.failedFuture(res.cause())); + } + }); + } } diff --git a/src/main/java/io/vertx/core/net/impl/NetClientImpl.java b/src/main/java/io/vertx/core/net/impl/NetClientImpl.java index cd6e960abea..021be7b075e 100644 --- a/src/main/java/io/vertx/core/net/impl/NetClientImpl.java +++ b/src/main/java/io/vertx/core/net/impl/NetClientImpl.java @@ -22,7 +22,6 @@ import io.netty.bootstrap.Bootstrap; import io.netty.channel.Channel; -import io.netty.channel.ChannelInitializer; import io.netty.channel.ChannelOption; import io.netty.channel.ChannelPipeline; import io.netty.channel.FixedRecvByteBufAllocator; @@ -42,8 +41,6 @@ import io.vertx.core.net.NetClient; import io.vertx.core.net.NetClientOptions; import io.vertx.core.net.NetSocket; -import io.vertx.core.net.ProxyOptions; -import io.vertx.core.net.impl.proxy.ProxyChannelProvider; import io.vertx.core.spi.metrics.Metrics; import io.vertx.core.spi.metrics.MetricsProvider; import io.vertx.core.spi.metrics.TCPMetrics; @@ -161,33 +158,13 @@ private void connect(int port, String host, Handler> conn bootstrap.group(context.nettyEventLoop()); bootstrap.channel(NioSocketChannel.class); - bootstrap.handler(new ChannelInitializer() { - @Override - protected void initChannel(Channel ch) throws Exception { - // Nothing to do - } - }); - applyConnectionOptions(bootstrap); ChannelProvider channelProvider; if (options.getProxyOptions() == null) { - channelProvider = new ChannelProvider() { - @Override - public void connect(VertxInternal vertx, Bootstrap bootstrap, ProxyOptions options, String host, int port, - Handler> channelHandler) { - AsyncResolveBindConnectHelper future = AsyncResolveBindConnectHelper.doConnect(vertx, port, host, bootstrap); - future.addListener(res -> { - if (res.succeeded()) { - channelHandler.handle(Future.succeededFuture(res.result())); - } else { - channelHandler.handle(Future.failedFuture(res.cause())); - } - }); - } - }; + channelProvider = ChannelProvider.INSTANCE; } else { - channelProvider = new ProxyChannelProvider(); + channelProvider = ProxyChannelProvider.INSTANCE; } Handler> channelHandler = res -> { @@ -228,14 +205,7 @@ public void connect(VertxInternal vertx, Bootstrap bootstrap, ProxyOptions optio } }; - try { - channelProvider.connect(vertx, bootstrap, options.getProxyOptions(), host, port, channelHandler); - } catch (NoClassDefFoundError e) { - if (options.getProxyOptions() != null && e.getMessage().contains("io/netty/handler/proxy")) { - log.warn("Depedency io.netty:netty-handler-proxy missing - check your classpath"); - channelHandler.handle(Future.failedFuture(e)); - } - } + channelProvider.connect(vertx, bootstrap, options.getProxyOptions(), host, port, channelHandler); } private void connected(ContextImpl context, Channel ch, Handler> connectHandler) { diff --git a/src/main/java/io/vertx/core/net/impl/proxy/ProxyChannelProvider.java b/src/main/java/io/vertx/core/net/impl/ProxyChannelProvider.java similarity index 81% rename from src/main/java/io/vertx/core/net/impl/proxy/ProxyChannelProvider.java rename to src/main/java/io/vertx/core/net/impl/ProxyChannelProvider.java index 9a9eb705bac..64afa3554fc 100644 --- a/src/main/java/io/vertx/core/net/impl/proxy/ProxyChannelProvider.java +++ b/src/main/java/io/vertx/core/net/impl/ProxyChannelProvider.java @@ -1,10 +1,4 @@ -/** - * - */ -package io.vertx.core.net.impl.proxy; - -import java.net.InetAddress; -import java.net.InetSocketAddress; +package io.vertx.core.net.impl; import io.netty.bootstrap.Bootstrap; import io.netty.channel.Channel; @@ -23,28 +17,27 @@ import io.vertx.core.Future; import io.vertx.core.Handler; import io.vertx.core.impl.VertxInternal; -import io.vertx.core.logging.Logger; -import io.vertx.core.logging.LoggerFactory; import io.vertx.core.net.ProxyOptions; import io.vertx.core.net.ProxyType; -import io.vertx.core.net.impl.ChannelProvider; + +import java.net.InetAddress; +import java.net.InetSocketAddress; /** - * @author Alexander Lehmann + * A channel provider that connects via a Proxy : HTTP or Socks * + * @author Julien Viet */ -public class ProxyChannelProvider implements ChannelProvider { - - // Could become a singleton as it does not hold state +public class ProxyChannelProvider extends ChannelProvider { - private static final Logger log = LoggerFactory.getLogger(ProxyChannelProvider.class); + public static final ChannelProvider INSTANCE = new ProxyChannelProvider(); - public ProxyChannelProvider() { + private ProxyChannelProvider() { } @Override - public void connect(VertxInternal vertx, Bootstrap bootstrap, ProxyOptions options, String host, int port, - Handler> channelHandler) { + protected void doConnect(VertxInternal vertx, Bootstrap bootstrap, ProxyOptions options, String host, int port, + Handler> channelHandler) { final String proxyHost = options.getProxyHost(); final int proxyPort = options.getProxyPort(); @@ -61,17 +54,14 @@ public void connect(VertxInternal vertx, Bootstrap bootstrap, ProxyOptions optio switch (proxyType) { default: case HTTP: - log.debug("configuring http connect proxy"); proxy = proxyUsername != null && proxyPassword != null ? new HttpProxyHandler(proxyAddr, proxyUsername, proxyPassword) : new HttpProxyHandler(proxyAddr); break; case SOCKS5: - log.debug("configuring socks5 proxy"); proxy = proxyUsername != null && proxyPassword != null ? new Socks5ProxyHandler(proxyAddr, proxyUsername, proxyPassword) : new Socks5ProxyHandler(proxyAddr); break; case SOCKS4: - log.debug("configuring socks4 proxy"); // apparently SOCKS4 only supports a username? proxy = proxyUsername != null ? new Socks4ProxyHandler(proxyAddr, proxyUsername) : new Socks4ProxyHandler(proxyAddr);