Class ProxyConnection<I extends HttpObject>

Type Parameters:
I - the type of "initial" message. This will be either HttpResponse or HttpRequest.
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:

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().

  • Field Details

  • Constructor Details

    • ProxyConnection

      protected ProxyConnection(ConnectionState initialState, DefaultHttpProxyServer proxyServer, boolean runsAsSslClient)
      Construct a new ProxyConnection.
      Parameters:
      initialState - the state in which this connection starts out
      proxyServer - the DefaultHttpProxyServer in which we're running
      runsAsSslClient - determines whether this connection acts as an SSL client or server (determines who does the handshake)
  • Method Details

    • 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)
      Parameters:
      msg - HAProxyMessage
    • readHTTP

      private void readHTTP(HttpObject httpObject)
      Handles reading HttpObjects.
    • readHTTPInitial

      protected abstract ConnectionState readHTTPInitial(I httpObject)
      Implement this to handle reading the initial object (e.g. HttpRequest or HttpResponse).
    • 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 underlying 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.
    • disconnected

      protected void disconnected()
      This method is called as soon as the underlying Channel becomes disconnected.
    • timedOut

      protected void timedOut()
      This method is called when the underlying Channel times 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 - the SSLEngine for doing the encryption
      authenticateClients - 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 encryption
      sslEngine - the SSLEngine for doing the encryption
      authenticateClients - 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 provided SSLEngine.
      Parameters:
      sslEngine - the SSLEngine for 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 the Channel.
    • 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.
    • closeChannel

      private void closeChannel(Promise<Void> promise)
    • 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 a ConnectionFlow, 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

    • channelRead0

      protected final void channelRead0(ChannelHandlerContext ctx, Object msg)
      Specified by:
      channelRead0 in class SimpleChannelInboundHandler<Object>
    • channelRegistered

      public void channelRegistered(ChannelHandlerContext ctx) throws Exception
      Specified by:
      channelRegistered in interface ChannelInboundHandler
      Overrides:
      channelRegistered in class ChannelInboundHandlerAdapter
      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:
      channelActive in interface ChannelInboundHandler
      Overrides:
      channelActive in class ChannelInboundHandlerAdapter
      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:
      channelInactive in interface ChannelInboundHandler
      Overrides:
      channelInactive in class ChannelInboundHandlerAdapter
      Throws:
      Exception
    • channelWritabilityChanged

      public final void channelWritabilityChanged(ChannelHandlerContext ctx) throws Exception
      Specified by:
      channelWritabilityChanged in interface ChannelInboundHandler
      Overrides:
      channelWritabilityChanged in class ChannelInboundHandlerAdapter
      Throws:
      Exception
    • exceptionCaught

      public final void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
      Specified by:
      exceptionCaught in interface ChannelHandler
      Specified by:
      exceptionCaught in interface ChannelInboundHandler
      Overrides:
      exceptionCaught in class ChannelInboundHandlerAdapter
    • 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:
      userEventTriggered in interface ChannelInboundHandler
      Overrides:
      userEventTriggered in class ChannelInboundHandlerAdapter
      Throws:
      Exception