Skip to content

Commit

Permalink
Capturing bound InetSocketAddress after starting the server to allow …
Browse files Browse the repository at this point in the history
…binding to port 0
  • Loading branch information
jekh committed Dec 10, 2014
1 parent 3339f39 commit cab0908
Showing 1 changed file with 29 additions and 17 deletions.
Expand Up @@ -90,7 +90,15 @@ public class DefaultHttpProxyServer implements HttpProxyServer {
private final ServerGroup serverGroup;

private final TransportProtocol transportProtocol;
private final InetSocketAddress address;
/*
* The address that the server will attempt to bind to.
*/
private final InetSocketAddress requestedAddress;
/*
* The actual address to which the server is bound. May be different from the requestedAddress in some circumstances,
* for example when the requested port is 0.
*/
private volatile InetSocketAddress boundAddress;
private final SslEngineSource sslEngineSource;
private final boolean authenticateSslClients;
private final ProxyAuthenticator proxyAuthenticator;
Expand Down Expand Up @@ -149,7 +157,7 @@ public static HttpProxyServerBootstrap bootstrapFromFile(String path) {
* our ServerGroup for shared thread pools and such
* @param transportProtocol
* The protocol to use for data transport
* @param address
* @param boundAddress
* The address on which this server will listen
* @param sslEngineSource
* (optional) if specified, this Proxy will encrypt inbound
Expand Down Expand Up @@ -184,7 +192,7 @@ public static HttpProxyServerBootstrap bootstrapFromFile(String path) {
*/
private DefaultHttpProxyServer(ServerGroup serverGroup,
TransportProtocol transportProtocol,
InetSocketAddress address,
InetSocketAddress boundAddress,
SslEngineSource sslEngineSource,
boolean authenticateSslClients,
ProxyAuthenticator proxyAuthenticator,
Expand All @@ -198,7 +206,7 @@ private DefaultHttpProxyServer(ServerGroup serverGroup,
HostResolver serverResolver) {
this.serverGroup = serverGroup;
this.transportProtocol = transportProtocol;
this.address = address;
this.requestedAddress = boundAddress;
this.sslEngineSource = sslEngineSource;
this.authenticateSslClients = authenticateSslClients;
this.proxyAuthenticator = proxyAuthenticator;
Expand Down Expand Up @@ -236,14 +244,14 @@ public HostResolver getServerResolver() {

@Override
public InetSocketAddress getListenAddress() {
return address;
return boundAddress;
}

@Override
public HttpProxyServerBootstrap clone() {
return new DefaultHttpProxyServerBootstrap(this, transportProtocol,
new InetSocketAddress(address.getAddress(),
address.getPort() + 1),
new InetSocketAddress(boundAddress.getAddress(),
boundAddress.getPort() + 1),
sslEngineSource, authenticateSslClients, proxyAuthenticator,
chainProxyManager,
mitmManager, filtersSource, transparent,
Expand All @@ -257,7 +265,7 @@ public void stop() {
}

private HttpProxyServer start() {
LOG.info("Starting proxy at address: " + this.address);
LOG.info("Starting proxy at address: " + this.requestedAddress);

synchronized (serverGroup) {
if (!serverGroup.stopped) {
Expand Down Expand Up @@ -305,7 +313,7 @@ public ServerChannel newChannel() {
throw new UnknownTransportProtocolError(transportProtocol);
}
serverBootstrap.childHandler(initializer);
ChannelFuture future = serverBootstrap.bind(address)
ChannelFuture future = serverBootstrap.bind(requestedAddress)
.addListener(new ChannelFutureListener() {
@Override
public void operationComplete(ChannelFuture future)
Expand All @@ -315,10 +323,14 @@ public void operationComplete(ChannelFuture future)
}
}
}).awaitUninterruptibly();

Throwable cause = future.cause();
if (cause != null) {
throw new RuntimeException(cause);
}

this.boundAddress = ((InetSocketAddress) future.channel().localAddress());
LOG.info("Proxy started at address: " + this.boundAddress);
}

/**
Expand Down Expand Up @@ -535,7 +547,7 @@ private static class DefaultHttpProxyServerBootstrap implements
HttpProxyServerBootstrap {
private String name = "LittleProxy";
private TransportProtocol transportProtocol = TCP;
private InetSocketAddress address;
private InetSocketAddress requestedAddress;
private int port = 8080;
private boolean allowLocalOnly = true;
private boolean listenOnAllAddresses = true;
Expand All @@ -558,7 +570,7 @@ private DefaultHttpProxyServerBootstrap() {
private DefaultHttpProxyServerBootstrap(
DefaultHttpProxyServer original,
TransportProtocol transportProtocol,
InetSocketAddress address,
InetSocketAddress requestedAddress,
SslEngineSource sslEngineSource,
boolean authenticateSslClients,
ProxyAuthenticator proxyAuthenticator,
Expand All @@ -570,8 +582,8 @@ private DefaultHttpProxyServerBootstrap(
int connectTimeout, HostResolver serverResolver) {
this.original = original;
this.transportProtocol = transportProtocol;
this.address = address;
this.port = address.getPort();
this.requestedAddress = requestedAddress;
this.port = requestedAddress.getPort();
this.sslEngineSource = sslEngineSource;
this.authenticateSslClients = authenticateSslClients;
this.proxyAuthenticator = proxyAuthenticator;
Expand Down Expand Up @@ -612,13 +624,13 @@ public HttpProxyServerBootstrap withTransportProtocol(

@Override
public HttpProxyServerBootstrap withAddress(InetSocketAddress address) {
this.address = address;
this.requestedAddress = address;
return this;
}

@Override
public HttpProxyServerBootstrap withPort(int port) {
this.address = null;
this.requestedAddress = null;
this.port = port;
return this;
}
Expand Down Expand Up @@ -757,8 +769,8 @@ transportProtocol, determineListenAddress(),
}

private InetSocketAddress determineListenAddress() {
if (address != null) {
return address;
if (requestedAddress != null) {
return requestedAddress;
} else {
// Binding only to localhost can significantly improve the
// security of the proxy.
Expand Down

0 comments on commit cab0908

Please sign in to comment.