Class ProxyConnection<I extends HttpObject>
- java.lang.Object
-
- io.netty.channel.ChannelHandlerAdapter
-
- io.netty.channel.ChannelInboundHandlerAdapter
-
- io.netty.channel.SimpleChannelInboundHandler<Object>
-
- org.littleshoot.proxy.impl.ProxyConnection<I>
-
- Type Parameters:
I- the type of "initial" message. This will be eitherHttpResponseorHttpRequest.
- All Implemented Interfaces:
ChannelHandler,ChannelInboundHandler
- Direct Known Subclasses:
ClientToProxyConnection,ProxyToServerConnection
abstract class ProxyConnection<I extends HttpObject> extends SimpleChannelInboundHandler<Object>
Base class for objects that represent a connection to/from our proxy.
A ProxyConnection models a bidirectional message flow on top of a Netty
Channel.The
read(Object)method is called whenever a new message arrives on the underlying socket.The
write(Object)method can be called by anyone wanting to write data out of the connection.ProxyConnection has a lifecycle and its current state within that lifecycle is recorded as a
ConnectionState. The allowed states and transitions vary a little depending on the concrete implementation of ProxyConnection. However, all ProxyConnections share the following lifecycle events:connected()- Once the underlying channel is active, the ProxyConnection is considered connected and moves intoConnectionState.AWAITING_INITIAL. The Channel is recorded at this time for later referencing.disconnected()- When the underlying channel goes inactive, the ProxyConnection moves intoConnectionState.DISCONNECTEDbecameWritable()- When the underlying channel becomes writeable, this callback is invoked.
By default, incoming data on the underlying channel is automatically read and passed to the
read(Object)method. Reading can be stopped and resumed usingstopReading()andresumeReading().
-
-
Nested Class Summary
Nested Classes Modifier and Type Class Description protected classProxyConnection.BytesReadMonitorUtility handler for monitoring bytes read on this connection.protected classProxyConnection.BytesWrittenMonitorUtility handler for monitoring bytes written on this connection.protected classProxyConnection.RequestReadMonitorUtility handler for monitoring requests read on this connection.protected static classProxyConnection.RequestWrittenMonitorUtility handler for monitoring requests written on this connection.protected classProxyConnection.ResponseReadMonitorUtility handler for monitoring responses read on this connection.protected classProxyConnection.ResponseWrittenMonitorUtility handler for monitoring responses written on this connection.-
Nested classes/interfaces inherited from interface io.netty.channel.ChannelHandler
ChannelHandler.Sharable
-
-
Field Summary
Fields Modifier and Type Field Description protected Channelchannelprotected ChannelHandlerContextctxprivate ConnectionStatecurrentStateprotected longlastReadTimeprotected ProxyConnectionLoggerLOGprotected DefaultHttpProxyServerproxyServerprotected booleanrunsAsSslClientprotected SSLEnginesslEngineIf using encryption, this holds ourSSLEngine.protected ConnectionFlowStepStartTunnelingEnables tunneling on this connection by dropping the HTTP related encoders and decoders, as well as idle timers.private booleantunneling
-
Constructor Summary
Constructors Modifier Constructor Description protectedProxyConnection(ConnectionState initialState, DefaultHttpProxyServer proxyServer, boolean runsAsSslClient)Construct a new ProxyConnection.
-
Method Summary
All Methods Instance Methods Abstract Methods Concrete Methods Modifier and Type Method Description protected voidaggregateContentForFiltering(ChannelPipeline pipeline, int numberOfBytesToBuffer)Enables decompression and aggregation of content, which is useful for certain types of filtering activity.protected voidbecameSaturated()Callback that's invoked if this connection becomes saturated.protected voidbecameWritable()Callback that's invoked when this connection becomes writeable again.protected voidbecome(ConnectionState state)Updates the current state to the given value.voidchannelActive(ChannelHandlerContext ctx)Only once the Netty Channel is active to we recognize the ProxyConnection as connected.voidchannelInactive(ChannelHandlerContext ctx)As soon as the Netty Channel is inactive, we recognize the ProxyConnection as disconnected.protected voidchannelRead0(ChannelHandlerContext ctx, Object msg)voidchannelRegistered(ChannelHandlerContext ctx)voidchannelUnregistered(ChannelHandlerContext ctx)voidchannelWritabilityChanged(ChannelHandlerContext ctx)private voidcloseChannel(Promise<Void> promise)protected voidconnected()This method is called as soon as the underlyingChannelis connected.(package private) Future<Void>disconnect()Disconnects.protected voiddisconnected()This method is called as soon as the underlyingChannelbecomes disconnected.(package private) voiddoWrite(Object msg)protected Future<Channel>encrypt(ChannelPipeline pipeline, SSLEngine sslEngine, boolean authenticateClients)Encrypts traffic on this connection with SSL/TLS.protected Future<Channel>encrypt(SSLEngine sslEngine, boolean authenticateClients)Encrypts traffic on this connection with SSL/TLS.protected ConnectionFlowStepEncryptChannel(SSLEngine sslEngine)Encrypts the channel using the providedSSLEngine.voidexceptionCaught(ChannelHandlerContext ctx, Throwable cause)protected voidexceptionCaught(Throwable cause)Override this to handle exceptions that occurred during asynchronous processing on theChannel.protected ConnectionStategetCurrentState()protected HttpFiltersgetHttpFiltersFromProxyServer(HttpRequest httpRequest)Request the ProxyServer for Filters.(package private) ProxyConnectionLoggergetLOG()SSLEnginegetSslEngine()protected booleanis(ConnectionState state)Utility for checking current state.protected booleanisConnecting()If this connection is currently in the process of going through aConnectionFlow, this will return true.protected booleanisSaturated()Indicates whether or not this connection is saturated (i.e.booleanisTunneling()protected voidread(Object msg)Read is invoked automatically by Netty as messages arrive on the socket.protected abstract voidreadHAProxyMessage(HAProxyMessage msg)Read anHAProxyMessageprivate voidreadHTTP(HttpObject httpObject)Handles readingHttpObjects.protected abstract voidreadHTTPChunk(HttpContent chunk)Implement this to handle reading a chunk in a chunked transfer.protected abstract ConnectionStatereadHTTPInitial(I httpObject)Implement this to handle reading the initial object (e.g.protected abstract voidreadRaw(ByteBuf buf)Implement this to handle reading a raw buffer as they are used in HTTP tunneling.protected booleanremoveHandlerIfPresent(ChannelPipeline pipeline, String handlerName)Removes the handler with the given name if it is present in the pipeline.protected voidresumeReading()Call this to resume reading.protected voidstopReading()Call this to stop reading.protected voidtimedOut()This method is called when the underlyingChanneltimes out due to an idle timeout.voiduserEventTriggered(ChannelHandlerContext ctx, Object evt)We're looking forIdleStateEvents to see if we need to disconnect.(package private) voidwrite(Object msg)This method is called by users of the ProxyConnection to send stuff out over the socket.protected voidwriteHttp(HttpObject httpObject)Writes HttpObjects to the connection asynchronously.protected voidwriteRaw(ByteBuf buf)Writes raw buffers to the connection.protected ChannelFuturewriteToChannel(Object msg)-
Methods inherited from class io.netty.channel.SimpleChannelInboundHandler
acceptInboundMessage, channelRead
-
Methods inherited from class io.netty.channel.ChannelInboundHandlerAdapter
channelReadComplete
-
Methods inherited from class io.netty.channel.ChannelHandlerAdapter
ensureNotSharable, handlerAdded, handlerRemoved, isSharable
-
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-
Methods inherited from interface io.netty.channel.ChannelHandler
handlerAdded, handlerRemoved
-
-
-
-
Field Detail
-
LOG
protected final ProxyConnectionLogger LOG
-
proxyServer
protected final DefaultHttpProxyServer proxyServer
-
runsAsSslClient
protected final boolean runsAsSslClient
-
ctx
protected volatile ChannelHandlerContext ctx
-
channel
protected volatile Channel channel
-
currentState
private volatile ConnectionState currentState
-
tunneling
private volatile boolean tunneling
-
lastReadTime
protected volatile long lastReadTime
-
StartTunneling
protected 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 becauseChannelPipeline.remove(String)can deadlock if called directly.
-
-
Constructor Detail
-
ProxyConnection
protected ProxyConnection(ConnectionState initialState, DefaultHttpProxyServer proxyServer, boolean runsAsSslClient)
Construct a new ProxyConnection.- Parameters:
initialState- the state in which this connection starts outproxyServer- theDefaultHttpProxyServerin which we're runningrunsAsSslClient- determines whether this connection acts as an SSL client or server (determines who does the handshake)
-
-
Method Detail
-
read
protected void read(Object msg)
Read is invoked automatically by Netty as messages arrive on the socket.
-
readHAProxyMessage
protected abstract void readHAProxyMessage(HAProxyMessage msg)
Read anHAProxyMessage- Parameters:
msg-HAProxyMessage
-
readHTTP
private void readHTTP(HttpObject httpObject)
Handles readingHttpObjects.
-
readHTTPInitial
protected abstract ConnectionState readHTTPInitial(I httpObject)
Implement this to handle reading the initial object (e.g.HttpRequestorHttpResponse).
-
readHTTPChunk
protected abstract void readHTTPChunk(HttpContent chunk)
Implement this to handle reading a chunk in a chunked transfer.
-
readRaw
protected abstract void readRaw(ByteBuf buf)
Implement this to handle reading a raw buffer as they are used in HTTP tunneling.
-
write
void write(Object msg)
This method is called by users of the ProxyConnection to send stuff out over the socket.
-
doWrite
void doWrite(Object msg)
-
writeHttp
protected void writeHttp(HttpObject httpObject)
Writes HttpObjects to the connection asynchronously.
-
writeRaw
protected void writeRaw(ByteBuf buf)
Writes raw buffers to the connection.
-
writeToChannel
protected ChannelFuture writeToChannel(Object msg)
-
connected
protected void connected()
This method is called as soon as the underlyingChannelis connected. Note that for proxies with complexConnectionFlows that include SSL handshaking and other such things, just because theChannelis connected doesn't mean that our connection is fully established.
-
disconnected
protected void disconnected()
This method is called as soon as the underlyingChannelbecomes disconnected.
-
timedOut
protected void timedOut()
This method is called when the underlyingChanneltimes out due to an idle timeout.
-
encrypt
protected Future<Channel> encrypt(SSLEngine sslEngine, boolean authenticateClients)
Encrypts traffic on this connection with SSL/TLS.- Parameters:
sslEngine- theSSLEnginefor doing the encryptionauthenticateClients- determines whether to authenticate clients or not- Returns:
- a Future for when the SSL handshake has completed
-
encrypt
protected Future<Channel> encrypt(ChannelPipeline pipeline, SSLEngine sslEngine, boolean authenticateClients)
Encrypts traffic on this connection with SSL/TLS.- Parameters:
pipeline- the ChannelPipeline on which to enable encryptionsslEngine- theSSLEnginefor doing the encryptionauthenticateClients- determines whether to authenticate clients or not- Returns:
- a Future for when the SSL handshake has completed
-
EncryptChannel
protected ConnectionFlowStep EncryptChannel(SSLEngine sslEngine)
Encrypts the channel using the providedSSLEngine.- Parameters:
sslEngine- theSSLEnginefor doing the encryption
-
aggregateContentForFiltering
protected void aggregateContentForFiltering(ChannelPipeline pipeline, int numberOfBytesToBuffer)
Enables decompression and aggregation of content, which is useful for certain types of filtering activity.
-
becameSaturated
protected void becameSaturated()
Callback that's invoked if this connection becomes saturated.
-
becameWritable
protected void becameWritable()
Callback that's invoked when this connection becomes writeable again.
-
exceptionCaught
protected void exceptionCaught(Throwable cause)
Override this to handle exceptions that occurred during asynchronous processing on theChannel.
-
removeHandlerIfPresent
protected boolean removeHandlerIfPresent(ChannelPipeline pipeline, String handlerName)
Removes the handler with the given name if it is present in the pipeline.- Parameters:
pipeline- the pipeline from which to remove the handler.handlerName- the name of the handler to remove.- Returns:
- true if the handler was found and removed; false otherwise.
-
disconnect
Future<Void> disconnect()
Disconnects. This will wait for pending writes to be flushed before disconnecting.- Returns:
Future<Void>for when we're done disconnecting. If we weren't connected, this returns null.
-
isSaturated
protected boolean isSaturated()
Indicates whether or not this connection is saturated (i.e. not writeable).
-
is
protected boolean is(ConnectionState state)
Utility for checking current state.
-
isConnecting
protected boolean isConnecting()
If this connection is currently in the process of going through aConnectionFlow, this will return true.
-
become
protected void become(ConnectionState state)
Updates the current state to the given value.
-
getCurrentState
protected ConnectionState getCurrentState()
-
isTunneling
public boolean isTunneling()
-
getSslEngine
public SSLEngine getSslEngine()
-
stopReading
protected void stopReading()
Call this to stop reading.
-
resumeReading
protected void resumeReading()
Call this to resume reading.
-
getHttpFiltersFromProxyServer
protected HttpFilters getHttpFiltersFromProxyServer(HttpRequest httpRequest)
Request the ProxyServer for Filters. By default, no-op filters are returned by DefaultHttpProxyServer. Subclasses of ProxyConnection can change this behaviour.- Parameters:
httpRequest- Filter attached to the give HttpRequest (if any)
-
getLOG
ProxyConnectionLogger getLOG()
-
channelRead0
protected final void channelRead0(ChannelHandlerContext ctx, Object msg)
- Specified by:
channelRead0in classSimpleChannelInboundHandler<Object>
-
channelRegistered
public void channelRegistered(ChannelHandlerContext ctx) throws Exception
- Specified by:
channelRegisteredin interfaceChannelInboundHandler- Overrides:
channelRegisteredin classChannelInboundHandlerAdapter- Throws:
Exception
-
channelUnregistered
public void channelUnregistered(ChannelHandlerContext ctx) throws Exception
- Specified by:
channelUnregisteredin interfaceChannelInboundHandler- Overrides:
channelUnregisteredin classChannelInboundHandlerAdapter- Throws:
Exception
-
channelActive
public final void channelActive(ChannelHandlerContext ctx) throws Exception
Only once the Netty Channel is active to we recognize the ProxyConnection as connected.- Specified by:
channelActivein interfaceChannelInboundHandler- Overrides:
channelActivein classChannelInboundHandlerAdapter- Throws:
Exception
-
channelInactive
public void channelInactive(ChannelHandlerContext ctx) throws Exception
As soon as the Netty Channel is inactive, we recognize the ProxyConnection as disconnected.- Specified by:
channelInactivein interfaceChannelInboundHandler- Overrides:
channelInactivein classChannelInboundHandlerAdapter- Throws:
Exception
-
channelWritabilityChanged
public final void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exception
- Specified by:
channelWritabilityChangedin interfaceChannelInboundHandler- Overrides:
channelWritabilityChangedin classChannelInboundHandlerAdapter- Throws:
Exception
-
exceptionCaught
public final void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
- Specified by:
exceptionCaughtin interfaceChannelHandler- Specified by:
exceptionCaughtin interfaceChannelInboundHandler- Overrides:
exceptionCaughtin classChannelInboundHandlerAdapter
-
userEventTriggered
public final void userEventTriggered(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.
- Specified by:
userEventTriggeredin interfaceChannelInboundHandler- Overrides:
userEventTriggeredin classChannelInboundHandlerAdapter- Throws:
Exception
-
-