@ChannelHandler.Sharable public class ProxyToServerConnection extends io.netty.channel.SimpleChannelInboundHandler<Object>
Represents a connection from our proxy to a server on the web. ProxyConnections are reused fairly liberally, and can go from disconnected to connected, back to disconnected and so on.
Connecting a ProxyToServerConnection can involve more than just
connecting the underlying Channel. In particular, the connection may
use encryption (i.e. TLS) and it may also establish an HTTP CONNECT tunnel.
The various steps involved in fully establishing a connection are
encapsulated in the property connectionFlow, which is initialized in
initializeConnectionFlow().
| Modifier and Type | Field and Description |
|---|---|
protected io.netty.channel.Channel |
channel |
protected io.netty.channel.ChannelHandlerContext |
ctx |
protected long |
lastReadTime |
protected org.littleshoot.proxy.impl.ProxyConnectionLogger |
LOG |
protected DefaultHttpProxyServer |
proxyServer |
protected boolean |
runsAsSslClient |
protected SSLEngine |
sslEngine
If using encryption, this holds our
SSLEngine. |
protected org.littleshoot.proxy.impl.ConnectionFlowStep |
StartTunneling
Enables tunneling on this connection by dropping the HTTP related
encoders and decoders, as well as idle timers.
|
| Modifier and Type | Method and Description |
|---|---|
protected void |
aggregateContentForFiltering(io.netty.channel.ChannelPipeline pipeline,
int numberOfBytesToBuffer)
Enables decompression and aggregation of content, which is useful for
certain types of filtering activity.
|
protected void |
becameSaturated()
Lifecycle
|
protected void |
becameWritable()
Callback that's invoked when this connection becomes writeable again.
|
protected void |
become(org.littleshoot.proxy.impl.ConnectionState state)
Udpates the current state to the given value.
|
void |
channelActive(io.netty.channel.ChannelHandlerContext ctx)
Only once the Netty Channel is active to we recognize the ProxyConnection
as connected.
|
void |
channelInactive(io.netty.channel.ChannelHandlerContext ctx)
As soon as the Netty Channel is inactive, we recognize the
ProxyConnection as disconnected.
|
protected void |
channelRead0(io.netty.channel.ChannelHandlerContext ctx,
Object msg)
Adapting the Netty API
|
void |
channelRegistered(io.netty.channel.ChannelHandlerContext ctx) |
void |
channelWritabilityChanged(io.netty.channel.ChannelHandlerContext ctx) |
protected void |
connected()
This method is called as soon as the underlying
Channel is
connected. |
protected boolean |
connectionFailed(Throwable cause)
Called to let us know that connection failed.
|
protected void |
disconnected()
This method is called as soon as the underlying
Channel becomes
disconnected. |
protected io.netty.util.concurrent.Future<io.netty.channel.Channel> |
encrypt(io.netty.channel.ChannelPipeline pipeline,
SSLEngine sslEngine,
boolean authenticateClients)
Encrypts traffic on this connection with SSL/TLS.
|
protected io.netty.util.concurrent.Future<io.netty.channel.Channel> |
encrypt(SSLEngine sslEngine,
boolean authenticateClients)
Encrypts traffic on this connection with SSL/TLS.
|
protected org.littleshoot.proxy.impl.ConnectionFlowStep |
EncryptChannel(SSLEngine sslEngine)
Encrypts the channel using the provided
SSLEngine. |
void |
exceptionCaught(io.netty.channel.ChannelHandlerContext ctx,
Throwable cause) |
protected void |
exceptionCaught(Throwable cause)
Override this to handle exceptions that occurred during asynchronous
processing on the
Channel. |
ChainedProxy |
getChainedProxy() |
InetSocketAddress |
getChainedProxyAddress() |
protected org.littleshoot.proxy.impl.ConnectionState |
getCurrentState() |
io.netty.handler.codec.http.HttpRequest |
getInitialRequest() |
InetSocketAddress |
getRemoteAddress() |
String |
getServerHostAndPort() |
SSLEngine |
getSslEngine() |
TransportProtocol |
getTransportProtocol()
State Management
|
boolean |
hasDownstreamChainedProxy() |
protected boolean |
is(org.littleshoot.proxy.impl.ConnectionState state)
Utility for checking current state.
|
protected boolean |
isConnecting()
If this connection is currently in the process of going through a
ConnectionFlow, this will return true. |
protected boolean |
isSaturated()
Indicates whether or not this connection is saturated (i.e.
|
boolean |
isTunneling() |
protected void |
read(Object msg)
Reading
|
protected void |
readHTTPChunk(io.netty.handler.codec.http.HttpContent chunk)
Implement this to handle reading a chunk in a chunked transfer.
|
protected org.littleshoot.proxy.impl.ConnectionState |
readHTTPInitial(io.netty.handler.codec.http.HttpResponse httpResponse)
Implement this to handle reading the initial object (e.g.
|
protected void |
readRaw(io.netty.buffer.ByteBuf buf)
Implement this to handle reading a raw buffer as they are used in HTTP
tunneling.
|
protected void |
resumeReading()
Call this to resume reading.
|
protected void |
stopReading()
Call this to stop reading.
|
protected void |
timedOut()
This method is called when the underlying
Channel times out due
to an idle timeout. |
void |
userEventTriggered(io.netty.channel.ChannelHandlerContext ctx,
Object evt)
We're looking for
IdleStateEvents to see if we need to
disconnect. |
protected void |
writeHttp(io.netty.handler.codec.http.HttpObject httpObject)
Writes HttpObjects to the connection asynchronously.
|
protected void |
writeRaw(io.netty.buffer.ByteBuf buf)
Writes raw buffers to the connection.
|
protected io.netty.channel.ChannelFuture |
writeToChannel(Object msg) |
acceptInboundMessage, channelReadchannelReadComplete, channelUnregisteredhandlerAdded, handlerRemoved, isSharableprotected final org.littleshoot.proxy.impl.ProxyConnectionLogger LOG
protected final DefaultHttpProxyServer proxyServer
protected final boolean runsAsSslClient
protected volatile io.netty.channel.ChannelHandlerContext ctx
protected volatile io.netty.channel.Channel channel
protected volatile long lastReadTime
protected org.littleshoot.proxy.impl.ConnectionFlowStep StartTunneling
Enables tunneling on this connection by dropping the HTTP related encoders and decoders, as well as idle timers.
Note - the work is done on the ChannelHandlerContext's executor
because ChannelPipeline.remove(String) can deadlock if called
directly.
protected void read(Object msg)
protected org.littleshoot.proxy.impl.ConnectionState readHTTPInitial(io.netty.handler.codec.http.HttpResponse httpResponse)
HttpRequest or HttpResponse).protected void readHTTPChunk(io.netty.handler.codec.http.HttpContent chunk)
protected void readRaw(io.netty.buffer.ByteBuf buf)
protected void writeHttp(io.netty.handler.codec.http.HttpObject httpObject)
protected void becameSaturated()
protected void becameWritable()
protected void timedOut()
Channel times out due
to an idle timeout.protected void disconnected()
Channel becomes
disconnected.protected void exceptionCaught(Throwable cause)
Channel.public TransportProtocol getTransportProtocol()
public InetSocketAddress getRemoteAddress()
public String getServerHostAndPort()
public boolean hasDownstreamChainedProxy()
public InetSocketAddress getChainedProxyAddress()
public ChainedProxy getChainedProxy()
public io.netty.handler.codec.http.HttpRequest getInitialRequest()
protected boolean connectionFailed(Throwable cause) throws UnknownHostException
Called to let us know that connection failed.
Try connecting to a new address, using a new set of connection parameters.
cause - the reason that our attempt to connect failed (can be null)UnknownHostExceptionprotected void writeRaw(io.netty.buffer.ByteBuf buf)
buf - protected io.netty.channel.ChannelFuture writeToChannel(Object msg)
protected void connected()
Channel is
connected. Note that for proxies with complex ConnectionFlows
that include SSL handshaking and other such things, just because the
Channel is connected doesn't mean that our connection is fully
established.protected io.netty.util.concurrent.Future<io.netty.channel.Channel> encrypt(SSLEngine sslEngine, boolean authenticateClients)
sslEngine - the SSLEngine for doing the encryptionauthenticateClients - determines whether to authenticate clients or notprotected io.netty.util.concurrent.Future<io.netty.channel.Channel> encrypt(io.netty.channel.ChannelPipeline pipeline,
SSLEngine sslEngine,
boolean authenticateClients)
pipeline - the ChannelPipeline on which to enable encryptionsslEngine - the SSLEngine for doing the encryptionauthenticateClients - determines whether to authenticate clients or notprotected org.littleshoot.proxy.impl.ConnectionFlowStep EncryptChannel(SSLEngine sslEngine)
SSLEngine.sslEngine - the SSLEngine for doing the encryptionprotected void aggregateContentForFiltering(io.netty.channel.ChannelPipeline pipeline,
int numberOfBytesToBuffer)
pipeline - numberOfBytesToBuffer - protected boolean isSaturated()
protected boolean is(org.littleshoot.proxy.impl.ConnectionState state)
state - protected boolean isConnecting()
ConnectionFlow, this will return true.protected void become(org.littleshoot.proxy.impl.ConnectionState state)
state - protected org.littleshoot.proxy.impl.ConnectionState getCurrentState()
public boolean isTunneling()
public SSLEngine getSslEngine()
protected void stopReading()
protected void resumeReading()
protected final void channelRead0(io.netty.channel.ChannelHandlerContext ctx,
Object msg)
throws Exception
public void channelRegistered(io.netty.channel.ChannelHandlerContext ctx)
throws Exception
channelRegistered in interface io.netty.channel.ChannelInboundHandlerchannelRegistered in class io.netty.channel.ChannelInboundHandlerAdapterExceptionpublic final void channelActive(io.netty.channel.ChannelHandlerContext ctx)
throws Exception
channelActive in interface io.netty.channel.ChannelInboundHandlerchannelActive in class io.netty.channel.ChannelInboundHandlerAdapterExceptionpublic void channelInactive(io.netty.channel.ChannelHandlerContext ctx)
throws Exception
channelInactive in interface io.netty.channel.ChannelInboundHandlerchannelInactive in class io.netty.channel.ChannelInboundHandlerAdapterExceptionpublic final void channelWritabilityChanged(io.netty.channel.ChannelHandlerContext ctx)
throws Exception
channelWritabilityChanged in interface io.netty.channel.ChannelInboundHandlerchannelWritabilityChanged in class io.netty.channel.ChannelInboundHandlerAdapterExceptionpublic final void exceptionCaught(io.netty.channel.ChannelHandlerContext ctx,
Throwable cause)
throws Exception
exceptionCaught in interface io.netty.channel.ChannelHandlerexceptionCaught in interface io.netty.channel.ChannelInboundHandlerexceptionCaught in class io.netty.channel.ChannelInboundHandlerAdapterExceptionpublic final void userEventTriggered(io.netty.channel.ChannelHandlerContext ctx,
Object evt)
throws Exception
We're looking for IdleStateEvents to see if we need to
disconnect.
Note - we don't care what kind of IdleState we got. Thanks to qbast for pointing this out.
userEventTriggered in interface io.netty.channel.ChannelInboundHandleruserEventTriggered in class io.netty.channel.ChannelInboundHandlerAdapterExceptionCopyright © 2009-2013 LittleShoot. All Rights Reserved.