public class ClientToProxyConnection extends io.netty.channel.SimpleChannelInboundHandler<Object>
Represents a connection from a client to our proxy. Each
ClientToProxyConnection can have multiple ProxyToServerConnections,
at most one per outbound host:port.
Once a ProxyToServerConnection has been created for a given server, it is
continually reused. The ProxyToServerConnection goes through its own
lifecycle of connects and disconnects, with different underlying
Channels, but only a single ProxyToServerConnection object is used
per server. The one exception to this is CONNECT tunneling - if a connection
has been used for CONNECT tunneling, that connection will never be reused.
As the ProxyToServerConnections receive responses from their servers, they
feed these back to the client by calling
respond(ProxyToServerConnection, HttpFilters, HttpRequest, HttpResponse, HttpObject)
.
| 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()
When the ClientToProxyConnection becomes saturated, stop reading on all
associated ProxyToServerConnections.
|
protected void |
becameWritable()
When the ClientToProxyConnection becomes writable, resume reading on all
associated ProxyToServerConnections.
|
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()
On connect of the client, start waiting for an initial
HttpRequest. |
protected void |
disconnected()
On disconnect of the client, disconnect all server connections.
|
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. |
InetSocketAddress |
getClientAddress() |
protected org.littleshoot.proxy.impl.ConnectionState |
getCurrentState() |
SSLEngine |
getSslEngine() |
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. |
boolean |
isMitming() |
protected boolean |
isSaturated()
Indicates whether or not this connection is saturated (i.e.
|
boolean |
isTunneling() |
protected void |
read(Object msg)
Read is invoked automatically by Netty as messages arrive on the socket.
|
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.HttpRequest httpRequest)
Reading
|
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 |
serverBecameSaturated(ProxyToServerConnection serverConnection)
When a server becomes saturated, we stop reading from the client.
|
protected void |
serverBecameWriteable(ProxyToServerConnection serverConnection)
When a server becomes writeable, we check to see if all servers are
writeable and if they are, we resume reading.
|
protected boolean |
serverConnectionFailed(ProxyToServerConnection serverConnection,
org.littleshoot.proxy.impl.ConnectionState lastStateBeforeFailure,
Throwable cause)
If the
ProxyToServerConnection fails to complete its connection
lifecycle successfully, this method is called to let us know about it. |
protected void |
serverConnectionFlowStarted(ProxyToServerConnection serverConnection)
Called when
ProxyToServerConnection starts its connection flow. |
protected void |
serverConnectionSucceeded(ProxyToServerConnection serverConnection,
boolean shouldForwardInitialRequest)
If the
ProxyToServerConnection completes its connection lifecycle
successfully, this method is called to let us know about it. |
protected void |
serverDisconnected(ProxyToServerConnection serverConnection)
On disconnect of the server, track that we have one fewer connected
servers and then disconnect the client if necessary.
|
protected void |
setMitming(boolean isMitming) |
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 org.littleshoot.proxy.impl.ConnectionState readHTTPInitial(io.netty.handler.codec.http.HttpRequest httpRequest)
protected void readHTTPChunk(io.netty.handler.codec.http.HttpContent chunk)
protected void readRaw(io.netty.buffer.ByteBuf buf)
protected void connected()
HttpRequest.protected void timedOut()
Channel times out due
to an idle timeout.protected void disconnected()
protected void serverConnectionFlowStarted(ProxyToServerConnection serverConnection)
ProxyToServerConnection starts its connection flow.serverConnection - protected void serverConnectionSucceeded(ProxyToServerConnection serverConnection, boolean shouldForwardInitialRequest)
ProxyToServerConnection completes its connection lifecycle
successfully, this method is called to let us know about it.serverConnection - shouldForwardInitialRequest - protected boolean serverConnectionFailed(ProxyToServerConnection serverConnection, org.littleshoot.proxy.impl.ConnectionState lastStateBeforeFailure, Throwable cause)
ProxyToServerConnection fails to complete its connection
lifecycle successfully, this method is called to let us know about it.
After failing to connect to the server, one of two things can happen:
serverConnection - lastStateBeforeFailure - cause - what caused the failureprotected void serverDisconnected(ProxyToServerConnection serverConnection)
serverConnection - protected void becameSaturated()
protected void becameWritable()
protected void serverBecameSaturated(ProxyToServerConnection serverConnection)
serverConnection - protected void serverBecameWriteable(ProxyToServerConnection serverConnection)
serverConnection - protected void exceptionCaught(Throwable cause)
Channel.public boolean isMitming()
protected void setMitming(boolean isMitming)
public InetSocketAddress getClientAddress()
protected void read(Object msg)
msg - protected void writeHttp(io.netty.handler.codec.http.HttpObject httpObject)
httpObject - protected void writeRaw(io.netty.buffer.ByteBuf buf)
buf - protected io.netty.channel.ChannelFuture writeToChannel(Object msg)
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.