Skip to content

Commit

Permalink
Factor our the common channel provider and the proxy channel provider…
Browse files Browse the repository at this point in the history
… as singletons
  • Loading branch information
vietj committed May 25, 2016
1 parent b7dfbfb commit 12a2a7b
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 93 deletions.
36 changes: 4 additions & 32 deletions src/main/java/io/vertx/core/http/impl/ConnectionManager.java
Expand Up @@ -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;
Expand All @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -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<AsyncResult<Channel>> channelHandler) {
bootstrap.handler(new ChannelInitializer<Channel>() {
@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<AsyncResult<Channel>> channelHandler = res -> {
Expand Down Expand Up @@ -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) {
Expand Down
71 changes: 64 additions & 7 deletions src/main/java/io/vertx/core/net/impl/ChannelProvider.java
Expand Up @@ -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 <a href="mailto:julien@julienviet.com">Julien Viet</a>
*/
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<AsyncResult<Channel>> channelHandler);
public void connect(VertxInternal vertx,
Bootstrap bootstrap,
ProxyOptions options,
String host,
int port,
Handler<AsyncResult<Channel>> 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<AsyncResult<Channel>> channelHandler) {
bootstrap.handler(new ChannelInitializer<Channel>() {
@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()));
}
});
}
}
36 changes: 3 additions & 33 deletions src/main/java/io/vertx/core/net/impl/NetClientImpl.java
Expand Up @@ -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;
Expand All @@ -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;
Expand Down Expand Up @@ -161,33 +158,13 @@ private void connect(int port, String host, Handler<AsyncResult<NetSocket>> conn
bootstrap.group(context.nettyEventLoop());
bootstrap.channel(NioSocketChannel.class);

bootstrap.handler(new ChannelInitializer<Channel>() {
@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<AsyncResult<Channel>> 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<AsyncResult<Channel>> channelHandler = res -> {
Expand Down Expand Up @@ -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<AsyncResult<NetSocket>> connectHandler) {
Expand Down
@@ -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;
Expand All @@ -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 <a href="http://oss.lehmann.cx/">Alexander Lehmann</a>
* A channel provider that connects via a Proxy : HTTP or Socks
*
* @author <a href="mailto:julien@julienviet.com">Julien Viet</a>
*/
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<AsyncResult<Channel>> channelHandler) {
protected void doConnect(VertxInternal vertx, Bootstrap bootstrap, ProxyOptions options, String host, int port,
Handler<AsyncResult<Channel>> channelHandler) {

final String proxyHost = options.getProxyHost();
final int proxyPort = options.getProxyPort();
Expand All @@ -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);
Expand Down

0 comments on commit 12a2a7b

Please sign in to comment.