Class ProxyToServerConnection
- All Implemented Interfaces:
ChannelHandler,ChannelInboundHandler
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().
-
Nested Class Summary
Nested ClassesModifier and TypeClassDescriptionprivate classResponses to HEAD requests aren't supposed to have content, but Netty doesn't know that any given response is to a HEAD request, so it needs to be told that there's no content so that it doesn't hang waiting for it.Nested classes/interfaces inherited from class org.littleshoot.proxy.impl.ProxyConnection
ProxyConnection.BytesReadMonitor, ProxyConnection.BytesWrittenMonitor, ProxyConnection.RequestReadMonitor, ProxyConnection.RequestWrittenMonitor, ProxyConnection.ResponseReadMonitor, ProxyConnection.ResponseWrittenMonitorNested classes/interfaces inherited from interface io.netty.channel.ChannelHandler
ChannelHandler.Sharable -
Field Summary
FieldsModifier and TypeFieldDescriptionprivate final Queue<ChainedProxy>private final ProxyConnection<HttpResponse>.BytesReadMonitorprivate final ProxyConnection<HttpResponse>.BytesWrittenMonitorprivate ChainedProxyprivate ChainedProxyTypeprivate final ClientToProxyConnectionprivate final ConnectionFlowStepOpens the socket connection.private ConnectionFlowEncapsulates the flow for establishing a connection, which can vary depending on how things are configured.private final ObjectWhile we're in the process of connecting, it's possible that we'll receive a new message to write.private HttpFiltersThe filters to apply to response/chunks received from server.private HttpRequestKeeps track of HttpRequests that have been issued so that we can associate them with responses that we get backprivate HttpResponseWhile we're doing a chunked transfer, this keeps track of the initial HttpResponse object for our transfer (which is useful for its headers).private booleanDisables SNI when initializing connection flow ininitializeConnectionFlow().private static final Stringprivate static final Stringprivate static final Stringprivate static final Stringprivate static final Stringprivate final ConnectionFlowStepWrites the HTTP CONNECT to the server and waits for a 200 response.private HttpRequestThis is the initial request received prior to connecting.private InetSocketAddressprivate static final Stringprivate static final intMinimum size of the adaptive recv buffer when throttling is enabled.private final ConnectionFlowStepEncrypts the client channel based on our serverSSLSession.private Stringprivate InetSocketAddressprivate io.netty.resolver.AddressResolverGroup<?>private final ProxyConnection.RequestWrittenMonitorprivate final ProxyConnection<HttpResponse>.ResponseReadMonitorprivate final ProxyToServerConnectionprivate final Stringprivate static final Stringprivate static final Stringprivate final ConnectionFlowStepEstablishes a SOCKS4 connection.private final ConnectionFlowStepEstablishes a SOCKS5 connection afterSOCKS5InitialRequestand (optionally)SOCKS5SendPasswordCredentialshave completed.private final ConnectionFlowStepInitiates a SOCKS5 connection.private final ConnectionFlowStepSends SOCKS5 password credentials afterSOCKS5InitialRequesthas completed.private final GlobalTrafficShapingHandlerLimits bandwidth when throttling is enabled.private TransportProtocolprivate StringFields inherited from class org.littleshoot.proxy.impl.ProxyConnection
channel, ctx, lastReadTime, LOG, proxyServer, runsAsSslClient, sslEngine, StartTunneling, tunneling -
Constructor Summary
ConstructorsModifierConstructorDescriptionprivateProxyToServerConnection(DefaultHttpProxyServer proxyServer, ClientToProxyConnection clientConnection, String serverHostAndPort, ChainedProxy chainedProxy, Queue<ChainedProxy> availableChainedProxies, HttpFilters initialFilters, GlobalTrafficShapingHandler globalTrafficShapingHandler) -
Method Summary
Modifier and TypeMethodDescriptionprivate voidaddFirstOrReplaceHandler(String name, ChannelHandler handler) static InetSocketAddressaddressFor(String hostAndPort, DefaultHttpProxyServer proxyServer) Build anInetSocketAddressfor the given hostAndPort.protected voidCallback that's invoked if this connection becomes saturated.protected voidCallback that's invoked when this connection becomes writeable again.protected voidbecome(ConnectionState newState) Updates the current state to the given value.private voidconnectAndWrite(HttpRequest initialRequest) Configures the connection to the upstream server and begins theConnectionFlow.protected booleanconnectionFailed(Throwable cause) Called when the connection to the server or upstream chained proxy fails.(package private) voidconnectionSucceeded(boolean shouldForwardInitialRequest) Do all the stuff that needs to be done after ourConnectionFlowhas succeeded.(package private) static ProxyToServerConnectioncreate(DefaultHttpProxyServer proxyServer, ClientToProxyConnection clientConnection, String serverHostAndPort, HttpFilters initialFilters, HttpRequest initialHttpRequest, GlobalTrafficShapingHandler globalTrafficShapingHandler) Create a new ProxyToServerConnection.protected voidThis method is called as soon as the underlyingChannelbecomes disconnected.protected voidexceptionCaught(Throwable cause) Override this to handle exceptions that occurred during asynchronous processing on theChannel.protected HttpFiltersgetHttpFiltersFromProxyServer(HttpRequest httpRequest) Request the ProxyServer for Filters.booleanprivate voidinitChannelPipeline(ChannelPipeline pipeline, HttpRequest httpRequest) Initialize ourChannelPipelineto connect the upstream server.private voidThis method initializes ourConnectionFlowbased on however this connection has been configured.protected voidRead is invoked automatically by Netty as messages arrive on the socket.protected voidRead anHAProxyMessageprotected voidreadHTTPChunk(HttpContent chunk) Implement this to handle reading a chunk in a chunked transfer.protected ConnectionStatereadHTTPInitial(HttpResponse httpResponse) Implement this to handle reading the initial object (e.g.protected voidImplement this to handle reading a raw buffer as they are used in HTTP tunneling.private voidrememberCurrentResponse(HttpResponse response) Keeps track of the current HttpResponse so that we can associate its headers with future related chunks for this same transfer.private voidremoveHandlerIfPresent(String name) private voidConvenience method to prepare to retry this connection.private voidprivate voidrespondWith(HttpObject httpObject) Respond to the client with the givenHttpObject.private voidSet up our connection parameters based on server address and chained proxies.(package private) voidprotected voidtimedOut()This method is called when the underlyingChanneltimes out due to an idle timeout.private static InetSocketAddressunresolvedAddressFor(String hostAndPort) Similar toaddressFor(String, DefaultHttpProxyServer)except that it does not resolve the address.(package private) ChannelFutureThis method is called by users of the ProxyConnection to send stuff out over the socket.(package private) voidwrite(Object msg, HttpFilters filters) Likewrite(Object)and also sets the current filters to the given value.protected ChannelFuturewriteHttp(HttpObject httpObject) Writes HttpObjects to the connection asynchronously.Methods inherited from class org.littleshoot.proxy.impl.ProxyConnection
aggregateContentForFiltering, channelActive, channelInactive, channelRead0, channelRegistered, channelUnregistered, channelWritabilityChanged, connected, disconnect, doWrite, encrypt, encrypt, EncryptChannel, exceptionCaught, getCurrentState, getLOG, getSslEngine, is, isConnecting, isSaturated, isTunneling, removeHandlerIfPresent, resumeReading, stopReading, userEventTriggered, writeRaw, writeToChannelMethods inherited from class io.netty.channel.SimpleChannelInboundHandler
acceptInboundMessage, channelReadMethods inherited from class io.netty.channel.ChannelInboundHandlerAdapter
channelReadCompleteMethods inherited from class io.netty.channel.ChannelHandlerAdapter
ensureNotSharable, handlerAdded, handlerRemoved, isSharableMethods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, waitMethods inherited from interface io.netty.channel.ChannelHandler
handlerAdded, handlerRemoved
-
Field Details
-
HTTP_ENCODER_NAME
- See Also:
-
HTTP_DECODER_NAME
- See Also:
-
HTTP_PROXY_ENCODER_NAME
- See Also:
-
HTTP_REQUEST_WRITTEN_MONITOR_NAME
- See Also:
-
HTTP_RESPONSE_READ_MONITOR_NAME
- See Also:
-
SOCKS_ENCODER_NAME
- See Also:
-
SOCKS_DECODER_NAME
- See Also:
-
MAIN_HANDLER_NAME
- See Also:
-
clientConnection
-
serverConnection
-
transportProtocol
-
chainedProxyType
-
remoteAddress
-
localAddress
-
remoteAddressResolver
private volatile io.netty.resolver.AddressResolverGroup<?> remoteAddressResolver -
username
-
password
-
serverHostAndPort
-
chainedProxy
-
availableChainedProxies
-
currentFilters
The filters to apply to response/chunks received from server. -
connectionFlow
Encapsulates the flow for establishing a connection, which can vary depending on how things are configured. -
disableSni
private volatile boolean disableSniDisables SNI when initializing connection flow ininitializeConnectionFlow(). This value is set to true when retrying a connection without SNI to work around Java's SNI handling issue (seeconnectionFailed(Throwable)). -
connectLock
While we're in the process of connecting, it's possible that we'll receive a new message to write. This lock helps us synchronize and wait for the connection to be established before writing the next message. -
initialRequest
This is the initial request received prior to connecting. We keep track of it so that we can process it after connection finishes. -
currentHttpRequest
Keeps track of HttpRequests that have been issued so that we can associate them with responses that we get back -
currentHttpResponse
While we're doing a chunked transfer, this keeps track of the initial HttpResponse object for our transfer (which is useful for its headers). -
trafficHandler
Limits bandwidth when throttling is enabled. -
MINIMUM_RECV_BUFFER_SIZE_BYTES
private static final int MINIMUM_RECV_BUFFER_SIZE_BYTESMinimum size of the adaptive recv buffer when throttling is enabled.- See Also:
-
ConnectChannel
Opens the socket connection. -
HTTPCONNECTWithChainedProxy
Writes the HTTP CONNECT to the server and waits for a 200 response. -
SOCKS4CONNECTWithChainedProxy
Establishes a SOCKS4 connection. -
SOCKS5InitialRequest
Initiates a SOCKS5 connection. -
SOCKS5SendPasswordCredentials
Sends SOCKS5 password credentials afterSOCKS5InitialRequesthas completed. -
SOCKS5CONNECTRequestWithChainedProxy
Establishes a SOCKS5 connection afterSOCKS5InitialRequestand (optionally)SOCKS5SendPasswordCredentialshave completed. -
MitmEncryptClientChannel
Encrypts the client channel based on our server
SSLSession.This does not wait for the handshake to finish so that we can go on and respond to the CONNECT request.
-
bytesReadMonitor
-
responseReadMonitor
-
bytesWrittenMonitor
-
requestWrittenMonitor
-
-
Constructor Details
-
ProxyToServerConnection
private ProxyToServerConnection(DefaultHttpProxyServer proxyServer, ClientToProxyConnection clientConnection, String serverHostAndPort, ChainedProxy chainedProxy, Queue<ChainedProxy> availableChainedProxies, HttpFilters initialFilters, GlobalTrafficShapingHandler globalTrafficShapingHandler) throws UnknownHostException - Throws:
UnknownHostException
-
-
Method Details
-
create
static ProxyToServerConnection create(DefaultHttpProxyServer proxyServer, ClientToProxyConnection clientConnection, String serverHostAndPort, HttpFilters initialFilters, HttpRequest initialHttpRequest, GlobalTrafficShapingHandler globalTrafficShapingHandler) throws UnknownHostException Create a new ProxyToServerConnection.- Throws:
UnknownHostException
-
read
Description copied from class:ProxyConnectionRead is invoked automatically by Netty as messages arrive on the socket.- Overrides:
readin classProxyConnection<HttpResponse>
-
readHAProxyMessage
Description copied from class:ProxyConnectionRead anHAProxyMessage- Specified by:
readHAProxyMessagein classProxyConnection<HttpResponse>- Parameters:
msg-HAProxyMessage
-
readHTTPInitial
Description copied from class:ProxyConnectionImplement this to handle reading the initial object (e.g.HttpRequestorHttpResponse).- Specified by:
readHTTPInitialin classProxyConnection<HttpResponse>
-
readHTTPChunk
Description copied from class:ProxyConnectionImplement this to handle reading a chunk in a chunked transfer.- Specified by:
readHTTPChunkin classProxyConnection<HttpResponse>
-
readRaw
Description copied from class:ProxyConnectionImplement this to handle reading a raw buffer as they are used in HTTP tunneling.- Specified by:
readRawin classProxyConnection<HttpResponse>
-
write
Likewrite(Object)and also sets the current filters to the given value. -
write
Description copied from class:ProxyConnectionThis method is called by users of the ProxyConnection to send stuff out over the socket.- Overrides:
writein classProxyConnection<HttpResponse>
-
writeHttp
Description copied from class:ProxyConnectionWrites HttpObjects to the connection asynchronously.- Overrides:
writeHttpin classProxyConnection<HttpResponse>
-
become
Description copied from class:ProxyConnectionUpdates the current state to the given value.- Overrides:
becomein classProxyConnection<HttpResponse>
-
becameSaturated
protected void becameSaturated()Description copied from class:ProxyConnectionCallback that's invoked if this connection becomes saturated.- Overrides:
becameSaturatedin classProxyConnection<HttpResponse>
-
becameWritable
protected void becameWritable()Description copied from class:ProxyConnectionCallback that's invoked when this connection becomes writeable again.- Overrides:
becameWritablein classProxyConnection<HttpResponse>
-
timedOut
protected void timedOut()Description copied from class:ProxyConnectionThis method is called when the underlyingChanneltimes out due to an idle timeout.- Overrides:
timedOutin classProxyConnection<HttpResponse>
-
disconnected
protected void disconnected()Description copied from class:ProxyConnectionThis method is called as soon as the underlyingChannelbecomes disconnected.- Overrides:
disconnectedin classProxyConnection<HttpResponse>
-
exceptionCaught
Description copied from class:ProxyConnectionOverride this to handle exceptions that occurred during asynchronous processing on theChannel.- Overrides:
exceptionCaughtin classProxyConnection<HttpResponse>
-
getTransportProtocol
-
getChainedProxyType
-
getRemoteAddress
-
getServerHostAndPort
-
hasUpstreamChainedProxy
public boolean hasUpstreamChainedProxy() -
getChainedProxyAddress
-
getChainedProxy
-
getInitialRequest
-
getHttpFiltersFromProxyServer
Description copied from class:ProxyConnectionRequest the ProxyServer for Filters. By default, no-op filters are returned by DefaultHttpProxyServer. Subclasses of ProxyConnection can change this behaviour.- Overrides:
getHttpFiltersFromProxyServerin classProxyConnection<HttpResponse>- Parameters:
httpRequest- Filter attached to the give HttpRequest (if any)
-
rememberCurrentResponse
Keeps track of the current HttpResponse so that we can associate its headers with future related chunks for this same transfer. -
respondWith
Respond to the client with the givenHttpObject. -
connectAndWrite
Configures the connection to the upstream server and begins theConnectionFlow.- Parameters:
initialRequest- the current HTTP request being handled
-
initializeConnectionFlow
private void initializeConnectionFlow()This method initializes ourConnectionFlowbased on however this connection has been configured. If thedisableSnivalue is true, this method will not pass peer information to the MitmManager when handling CONNECTs. -
addFirstOrReplaceHandler
-
removeHandlerIfPresent
-
connectionFailed
Called when the connection to the server or upstream chained proxy fails. This method may return true to indicate that the connection should be retried. If returning true, this method must set up the connection itself.- Parameters:
cause- the reason that our attempt to connect failed (can be null)- Returns:
- true if we are trying to fall back to another connection
- Throws:
UnknownHostException
-
resetConnectionForRetry
Convenience method to prepare to retry this connection. Closes the connection's channel and sets up the connection again usingsetupConnectionParameters().- Throws:
UnknownHostException- whensetupConnectionParameters()is unable to resolve the hostname
-
setupConnectionParameters
Set up our connection parameters based on server address and chained proxies.- Throws:
UnknownHostException- when unable to resolve the hostname to an IP address
-
initChannelPipeline
Initialize ourChannelPipelineto connect the upstream server. LittleProxy acts as a client here. AChannelPipelineinvokes the read (Inbound) handlers in ascending ordering of the list and then the write (Outbound) handlers in descending ordering. Regarding the Javadoc ofHttpObjectAggregatorit's needed to have theHttpResponseEncoderorHttpRequestEncoderbefore theHttpObjectAggregatorin theChannelPipeline. -
connectionSucceeded
void connectionSucceeded(boolean shouldForwardInitialRequest) Do all the stuff that needs to be done after our
ConnectionFlowhas succeeded.- Parameters:
shouldForwardInitialRequest- whether or not we should forward the initial HttpRequest to the server after the connection has been established.
-
resetInitialRequest
private void resetInitialRequest() -
addressFor
public static InetSocketAddress addressFor(String hostAndPort, DefaultHttpProxyServer proxyServer) throws UnknownHostException Build anInetSocketAddressfor the given hostAndPort.- Parameters:
hostAndPort- String representation of the host and portproxyServer- the currentDefaultHttpProxyServer- Returns:
- a resolved InetSocketAddress for the specified hostAndPort
- Throws:
UnknownHostException- if hostAndPort could not be resolved, or if the input string could not be parsed into a host and port.
-
unresolvedAddressFor
Similar toaddressFor(String, DefaultHttpProxyServer)except that it does not resolve the address.- Parameters:
hostAndPort- the host and port to parse.- Returns:
- an unresolved
InetSocketAddress.
-
switchToWebSocketProtocol
void switchToWebSocketProtocol()
-