I
- the type of "initial" message. This will be either
HttpResponse
or HttpRequest
.abstract class ProxyConnection<I extends io.netty.handler.codec.http.HttpObject> extends io.netty.channel.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 into
ConnectionState.AWAITING_INITIAL
. The Channel is recorded at this
time for later referencing.disconnected()
- When the underlying channel goes inactive, the
ProxyConnection moves into ConnectionState.DISCONNECTED
becameWritable()
- 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 using stopReading()
and resumeReading()
.
Modifier and Type | Class and Description |
---|---|
protected class |
ProxyConnection.BytesReadMonitor
Utility handler for monitoring bytes read on this connection.
|
protected class |
ProxyConnection.BytesWrittenMonitor
Utility handler for monitoring bytes written on this connection.
|
protected class |
ProxyConnection.RequestReadMonitor
Utility handler for monitoring requests read on this connection.
|
protected class |
ProxyConnection.RequestWrittenMonitor
Utility handler for monitoring requests written on this connection.
|
protected class |
ProxyConnection.ResponseReadMonitor
Utility handler for monitoring responses read on this connection.
|
protected class |
ProxyConnection.ResponseWrittenMonitor
Utility handler for monitoring responses written on this connection.
|
Modifier and Type | Field and Description |
---|---|
protected io.netty.channel.Channel |
channel |
protected io.netty.channel.ChannelHandlerContext |
ctx |
private ConnectionState |
currentState |
protected long |
lastReadTime |
protected ProxyConnectionLogger |
LOG |
protected DefaultHttpProxyServer |
proxyServer |
protected boolean |
runsAsSslClient |
protected SSLEngine |
sslEngine
If using encryption, this holds our
SSLEngine . |
protected ConnectionFlowStep |
StartTunneling
Enables tunneling on this connection by dropping the HTTP related
encoders and decoders, as well as idle timers.
|
private boolean |
tunneling |
Modifier | Constructor and Description |
---|---|
protected |
ProxyConnection(ConnectionState initialState,
DefaultHttpProxyServer proxyServer,
boolean runsAsSslClient)
Construct a new ProxyConnection.
|
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()
Callback that's invoked if this connection becomes saturated.
|
protected void |
becameWritable()
Callback that's invoked when this connection becomes writeable again.
|
protected void |
become(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) |
private void |
closeChannel(io.netty.util.concurrent.Promise<Void> promise) |
protected void |
connected()
This method is called as soon as the underlying
Channel is
connected. |
(package private) io.netty.util.concurrent.Future<Void> |
disconnect()
Disconnects.
|
protected void |
disconnected()
This method is called as soon as the underlying
Channel becomes
disconnected. |
(package private) void |
doWrite(Object msg) |
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 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 . |
protected ConnectionState |
getCurrentState() |
protected HttpFilters |
getHttpFiltersFromProxyServer(io.netty.handler.codec.http.HttpRequest httpRequest)
Request the ProxyServer for Filters.
|
(package private) ProxyConnectionLogger |
getLOG() |
SSLEngine |
getSslEngine() |
protected boolean |
is(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)
Read is invoked automatically by Netty as messages arrive on the socket.
|
private void |
readHTTP(io.netty.handler.codec.http.HttpObject httpObject)
Handles reading
HttpObject s. |
protected abstract void |
readHTTPChunk(io.netty.handler.codec.http.HttpContent chunk)
Implement this to handle reading a chunk in a chunked transfer.
|
protected abstract ConnectionState |
readHTTPInitial(I httpObject)
Implement this to handle reading the initial object (e.g.
|
protected abstract 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
IdleStateEvent s to see if we need to
disconnect. |
(package private) void |
write(Object msg)
This method is called by users of the ProxyConnection to send stuff out
over the socket.
|
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, channelRead
channelReadComplete, channelUnregistered
ensureNotSharable, handlerAdded, handlerRemoved, isSharable
protected final ProxyConnectionLogger LOG
protected final DefaultHttpProxyServer proxyServer
protected final boolean runsAsSslClient
protected volatile io.netty.channel.ChannelHandlerContext ctx
protected volatile io.netty.channel.Channel channel
private volatile ConnectionState currentState
private volatile boolean tunneling
protected volatile long lastReadTime
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
because ChannelPipeline.remove(String)
can deadlock if called
directly.
protected ProxyConnection(ConnectionState initialState, DefaultHttpProxyServer proxyServer, boolean runsAsSslClient)
initialState
- the state in which this connection starts outproxyServer
- the DefaultHttpProxyServer
in which we're runningrunsAsSslClient
- determines whether this connection acts as an SSL client or
server (determines who does the handshake)protected void read(Object msg)
msg
- private void readHTTP(io.netty.handler.codec.http.HttpObject httpObject)
HttpObject
s.httpObject
- protected abstract ConnectionState readHTTPInitial(I httpObject)
HttpRequest
or HttpResponse
).httpObject
- protected abstract void readHTTPChunk(io.netty.handler.codec.http.HttpContent chunk)
chunk
- protected abstract void readRaw(io.netty.buffer.ByteBuf buf)
buf
- void write(Object msg)
msg
- void doWrite(Object 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 void connected()
Channel
is
connected. Note that for proxies with complex ConnectionFlow
s
that include SSL handshaking and other such things, just because the
Channel
is connected doesn't mean that our connection is fully
established.protected void disconnected()
Channel
becomes
disconnected.protected void timedOut()
Channel
times out due
to an idle timeout.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 ConnectionFlowStep EncryptChannel(SSLEngine sslEngine)
SSLEngine
.sslEngine
- the SSLEngine
for doing the encryptionprotected void aggregateContentForFiltering(io.netty.channel.ChannelPipeline pipeline, int numberOfBytesToBuffer)
pipeline
- numberOfBytesToBuffer
- protected void becameSaturated()
protected void becameWritable()
protected void exceptionCaught(Throwable cause)
Channel
.cause
- io.netty.util.concurrent.Future<Void> disconnect()
private void closeChannel(io.netty.util.concurrent.Promise<Void> promise)
protected boolean isSaturated()
protected boolean is(ConnectionState state)
state
- protected boolean isConnecting()
ConnectionFlow
, this will return true.protected void become(ConnectionState state)
state
- protected ConnectionState getCurrentState()
public boolean isTunneling()
public SSLEngine getSslEngine()
protected void stopReading()
protected void resumeReading()
protected HttpFilters getHttpFiltersFromProxyServer(io.netty.handler.codec.http.HttpRequest httpRequest)
httpRequest
- Filter attached to the give HttpRequest (if any)ProxyConnectionLogger getLOG()
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.ChannelInboundHandler
channelRegistered
in class io.netty.channel.ChannelInboundHandlerAdapter
Exception
public final void channelActive(io.netty.channel.ChannelHandlerContext ctx) throws Exception
channelActive
in interface io.netty.channel.ChannelInboundHandler
channelActive
in class io.netty.channel.ChannelInboundHandlerAdapter
Exception
public void channelInactive(io.netty.channel.ChannelHandlerContext ctx) throws Exception
channelInactive
in interface io.netty.channel.ChannelInboundHandler
channelInactive
in class io.netty.channel.ChannelInboundHandlerAdapter
Exception
public final void channelWritabilityChanged(io.netty.channel.ChannelHandlerContext ctx) throws Exception
channelWritabilityChanged
in interface io.netty.channel.ChannelInboundHandler
channelWritabilityChanged
in class io.netty.channel.ChannelInboundHandlerAdapter
Exception
public final void exceptionCaught(io.netty.channel.ChannelHandlerContext ctx, Throwable cause) throws Exception
exceptionCaught
in interface io.netty.channel.ChannelHandler
exceptionCaught
in interface io.netty.channel.ChannelInboundHandler
exceptionCaught
in class io.netty.channel.ChannelInboundHandlerAdapter
Exception
public final void userEventTriggered(io.netty.channel.ChannelHandlerContext ctx, Object evt) throws Exception
We're looking for IdleStateEvent
s 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.ChannelInboundHandler
userEventTriggered
in class io.netty.channel.ChannelInboundHandlerAdapter
Exception
Copyright © 2009–2019 LittleShoot. All rights reserved.