@ChannelHandler.Sharable public class ProxyToServerConnection extends ProxyConnection<HttpResponse>
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().
| Modifier and Type | Class and Description |
|---|---|
private class |
ProxyToServerConnection.HeadAwareHttpResponseDecoder
Responses 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.
|
ProxyConnection.BytesReadMonitor, ProxyConnection.BytesWrittenMonitor, ProxyConnection.RequestReadMonitor, ProxyConnection.RequestWrittenMonitor, ProxyConnection.ResponseReadMonitor, ProxyConnection.ResponseWrittenMonitorChannelHandler.Sharable| Modifier and Type | Field and Description |
|---|---|
private Queue<ChainedProxy> |
availableChainedProxies |
private ProxyConnection.BytesReadMonitor |
bytesReadMonitor |
private ProxyConnection.BytesWrittenMonitor |
bytesWrittenMonitor |
private ChainedProxy |
chainedProxy |
private ChainedProxyType |
chainedProxyType |
private ClientToProxyConnection |
clientConnection |
private ConnectionFlowStep |
ConnectChannel
Opens the socket connection.
|
private ConnectionFlow |
connectionFlow
Encapsulates the flow for establishing a connection, which can vary
depending on how things are configured.
|
private Object |
connectLock
While we're in the process of connecting, it's possible that we'll
receive a new message to write.
|
private HttpFilters |
currentFilters
The filters to apply to response/chunks received from server.
|
private HttpRequest |
currentHttpRequest
Keeps track of HttpRequests that have been issued so that we can
associate them with responses that we get back
|
private HttpResponse |
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).
|
private boolean |
disableSni
Disables SNI when initializing connection flow in
initializeConnectionFlow(). |
private static String |
HTTP_DECODER_NAME |
private static String |
HTTP_ENCODER_NAME |
private static String |
HTTP_PROXY_ENCODER_NAME |
private static String |
HTTP_REQUEST_WRITTEN_MONITOR_NAME |
private static String |
HTTP_RESPONSE_READ_MONITOR_NAME |
private ConnectionFlowStep |
HTTPCONNECTWithChainedProxy
Writes the HTTP CONNECT to the server and waits for a 200 response.
|
private HttpRequest |
initialRequest
This is the initial request received prior to connecting.
|
private InetSocketAddress |
localAddress |
private static String |
MAIN_HANDLER_NAME |
private static int |
MINIMUM_RECV_BUFFER_SIZE_BYTES
Minimum size of the adaptive recv buffer when throttling is enabled.
|
private ConnectionFlowStep |
MitmEncryptClientChannel
Encrypts the client channel based on our server
SSLSession. |
private String |
password |
private InetSocketAddress |
remoteAddress |
private io.netty.resolver.AddressResolverGroup<?> |
remoteAddressResolver |
private ProxyConnection.RequestWrittenMonitor |
requestWrittenMonitor |
private ProxyConnection.ResponseReadMonitor |
responseReadMonitor |
private ProxyToServerConnection |
serverConnection |
private String |
serverHostAndPort |
private static String |
SOCKS_DECODER_NAME |
private static String |
SOCKS_ENCODER_NAME |
private ConnectionFlowStep |
SOCKS4CONNECTWithChainedProxy
Establishes a SOCKS4 connection.
|
private ConnectionFlowStep |
SOCKS5CONNECTRequestWithChainedProxy
Establishes a SOCKS5 connection after
SOCKS5InitialRequest and
(optionally) SOCKS5SendPasswordCredentials have completed. |
private ConnectionFlowStep |
SOCKS5InitialRequest
Initiates a SOCKS5 connection.
|
private ConnectionFlowStep |
SOCKS5SendPasswordCredentials
Sends SOCKS5 password credentials after
SOCKS5InitialRequest has completed. |
private GlobalTrafficShapingHandler |
trafficHandler
Limits bandwidth when throttling is enabled.
|
private TransportProtocol |
transportProtocol |
private String |
username |
channel, ctx, lastReadTime, LOG, proxyServer, runsAsSslClient, sslEngine, StartTunneling| Modifier | Constructor and Description |
|---|---|
private |
ProxyToServerConnection(DefaultHttpProxyServer proxyServer,
ClientToProxyConnection clientConnection,
String serverHostAndPort,
ChainedProxy chainedProxy,
Queue<ChainedProxy> availableChainedProxies,
HttpFilters initialFilters,
GlobalTrafficShapingHandler globalTrafficShapingHandler) |
| Modifier and Type | Method and Description |
|---|---|
private void |
addFirstOrReplaceHandler(String name,
ChannelHandler handler) |
static InetSocketAddress |
addressFor(String hostAndPort,
DefaultHttpProxyServer proxyServer)
Build an
InetSocketAddress for the given hostAndPort. |
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 newState)
Updates the current state to the given value.
|
private void |
connectAndWrite(HttpRequest initialRequest)
Configures the connection to the upstream server and begins the
ConnectionFlow. |
protected boolean |
connectionFailed(Throwable cause)
Called when the connection to the server or upstream chained proxy fails.
|
(package private) void |
connectionSucceeded(boolean shouldForwardInitialRequest)
Do all the stuff that needs to be done after our
ConnectionFlow
has succeeded. |
(package private) static ProxyToServerConnection |
create(DefaultHttpProxyServer proxyServer,
ClientToProxyConnection clientConnection,
String serverHostAndPort,
HttpFilters initialFilters,
HttpRequest initialHttpRequest,
GlobalTrafficShapingHandler globalTrafficShapingHandler)
Create a new ProxyToServerConnection.
|
protected void |
disconnected()
This method is called as soon as the underlying
Channel becomes
disconnected. |
protected void |
exceptionCaught(Throwable cause)
Override this to handle exceptions that occurred during asynchronous
processing on the
Channel. |
ChainedProxy |
getChainedProxy() |
InetSocketAddress |
getChainedProxyAddress() |
ChainedProxyType |
getChainedProxyType() |
protected HttpFilters |
getHttpFiltersFromProxyServer(HttpRequest httpRequest)
Request the ProxyServer for Filters.
|
HttpRequest |
getInitialRequest() |
InetSocketAddress |
getRemoteAddress() |
String |
getServerHostAndPort() |
TransportProtocol |
getTransportProtocol() |
boolean |
hasUpstreamChainedProxy() |
private void |
initChannelPipeline(ChannelPipeline pipeline,
HttpRequest httpRequest)
Initialize our
ChannelPipeline to connect the upstream server. |
private void |
initializeConnectionFlow()
This method initializes our
ConnectionFlow based on however this connection has been configured. |
protected void |
read(Object msg)
Read is invoked automatically by Netty as messages arrive on the socket.
|
protected void |
readHAProxyMessage(HAProxyMessage msg)
Read an
HAProxyMessage |
protected void |
readHTTPChunk(HttpContent chunk)
Implement this to handle reading a chunk in a chunked transfer.
|
protected ConnectionState |
readHTTPInitial(HttpResponse httpResponse)
Implement this to handle reading the initial object (e.g.
|
protected void |
readRaw(ByteBuf buf)
Implement this to handle reading a raw buffer as they are used in HTTP
tunneling.
|
private void |
rememberCurrentResponse(HttpResponse response)
Keeps track of the current HttpResponse so that we can associate its
headers with future related chunks for this same transfer.
|
private void |
removeHandlerIfPresent(String name) |
private void |
resetConnectionForRetry()
Convenience method to prepare to retry this connection.
|
private void |
respondWith(HttpObject httpObject)
Respond to the client with the given
HttpObject. |
private void |
setupConnectionParameters()
Set up our connection parameters based on server address and chained
proxies.
|
(package private) void |
switchToWebSocketProtocol() |
protected void |
timedOut()
This method is called when the underlying
Channel times out due
to an idle timeout. |
private static InetSocketAddress |
unresolvedAddressFor(String hostAndPort)
Similar to
addressFor(String, DefaultHttpProxyServer) except that it does
not resolve the address. |
(package private) void |
write(Object msg)
This method is called by users of the ProxyConnection to send stuff out
over the socket.
|
(package private) void |
write(Object msg,
HttpFilters filters)
Like
write(Object) and also sets the current filters to the
given value. |
protected void |
writeHttp(HttpObject httpObject)
Writes HttpObjects to the connection asynchronously.
|
aggregateContentForFiltering, channelActive, channelInactive, channelRead0, channelRegistered, channelWritabilityChanged, connected, disconnect, doWrite, encrypt, encrypt, EncryptChannel, exceptionCaught, getCurrentState, getLOG, getSslEngine, is, isConnecting, isSaturated, isTunneling, resumeReading, stopReading, userEventTriggered, writeRaw, writeToChannelacceptInboundMessage, channelReadchannelReadComplete, channelUnregisteredensureNotSharable, handlerAdded, handlerRemoved, isSharableclone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, waithandlerAdded, handlerRemovedprivate static final String HTTP_ENCODER_NAME
private static final String HTTP_DECODER_NAME
private static final String HTTP_PROXY_ENCODER_NAME
private static final String HTTP_REQUEST_WRITTEN_MONITOR_NAME
private static final String HTTP_RESPONSE_READ_MONITOR_NAME
private static final String SOCKS_ENCODER_NAME
private static final String SOCKS_DECODER_NAME
private static final String MAIN_HANDLER_NAME
private final ClientToProxyConnection clientConnection
private final ProxyToServerConnection serverConnection
private volatile TransportProtocol transportProtocol
private volatile ChainedProxyType chainedProxyType
private volatile InetSocketAddress remoteAddress
private volatile InetSocketAddress localAddress
private volatile io.netty.resolver.AddressResolverGroup<?> remoteAddressResolver
private volatile String username
private volatile String password
private final String serverHostAndPort
private volatile ChainedProxy chainedProxy
private final Queue<ChainedProxy> availableChainedProxies
private volatile HttpFilters currentFilters
private volatile ConnectionFlow connectionFlow
private volatile boolean disableSni
initializeConnectionFlow(). This value is set to true
when retrying a connection without SNI to work around Java's SNI handling issue (see
connectionFailed(Throwable)).private final Object connectLock
private volatile HttpRequest initialRequest
private volatile HttpRequest currentHttpRequest
private volatile HttpResponse currentHttpResponse
private volatile GlobalTrafficShapingHandler trafficHandler
private static final int MINIMUM_RECV_BUFFER_SIZE_BYTES
private ConnectionFlowStep ConnectChannel
private ConnectionFlowStep HTTPCONNECTWithChainedProxy
private ConnectionFlowStep SOCKS4CONNECTWithChainedProxy
private ConnectionFlowStep SOCKS5InitialRequest
private ConnectionFlowStep SOCKS5SendPasswordCredentials
SOCKS5InitialRequest has completed.private ConnectionFlowStep SOCKS5CONNECTRequestWithChainedProxy
SOCKS5InitialRequest and
(optionally) SOCKS5SendPasswordCredentials have completed.private ConnectionFlowStep 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.
private final ProxyConnection.BytesReadMonitor bytesReadMonitor
private ProxyConnection.ResponseReadMonitor responseReadMonitor
private ProxyConnection.BytesWrittenMonitor bytesWrittenMonitor
private ProxyConnection.RequestWrittenMonitor requestWrittenMonitor
private ProxyToServerConnection(DefaultHttpProxyServer proxyServer, ClientToProxyConnection clientConnection, String serverHostAndPort, ChainedProxy chainedProxy, Queue<ChainedProxy> availableChainedProxies, HttpFilters initialFilters, GlobalTrafficShapingHandler globalTrafficShapingHandler) throws UnknownHostException
UnknownHostExceptionstatic ProxyToServerConnection create(DefaultHttpProxyServer proxyServer, ClientToProxyConnection clientConnection, String serverHostAndPort, HttpFilters initialFilters, HttpRequest initialHttpRequest, GlobalTrafficShapingHandler globalTrafficShapingHandler) throws UnknownHostException
UnknownHostExceptionprotected void read(Object msg)
ProxyConnectionread in class ProxyConnection<HttpResponse>protected void readHAProxyMessage(HAProxyMessage msg)
ProxyConnectionHAProxyMessagereadHAProxyMessage in class ProxyConnection<HttpResponse>msg - HAProxyMessageprotected ConnectionState readHTTPInitial(HttpResponse httpResponse)
ProxyConnectionHttpRequest or HttpResponse).readHTTPInitial in class ProxyConnection<HttpResponse>protected void readHTTPChunk(HttpContent chunk)
ProxyConnectionreadHTTPChunk in class ProxyConnection<HttpResponse>protected void readRaw(ByteBuf buf)
ProxyConnectionreadRaw in class ProxyConnection<HttpResponse>void write(Object msg, HttpFilters filters)
write(Object) and also sets the current filters to the
given value.void write(Object msg)
ProxyConnectionwrite in class ProxyConnection<HttpResponse>protected void writeHttp(HttpObject httpObject)
ProxyConnectionwriteHttp in class ProxyConnection<HttpResponse>protected void become(ConnectionState newState)
ProxyConnectionbecome in class ProxyConnection<HttpResponse>protected void becameSaturated()
ProxyConnectionbecameSaturated in class ProxyConnection<HttpResponse>protected void becameWritable()
ProxyConnectionbecameWritable in class ProxyConnection<HttpResponse>protected void timedOut()
ProxyConnectionChannel times out due
to an idle timeout.timedOut in class ProxyConnection<HttpResponse>protected void disconnected()
ProxyConnectionChannel becomes
disconnected.disconnected in class ProxyConnection<HttpResponse>protected void exceptionCaught(Throwable cause)
ProxyConnectionChannel.exceptionCaught in class ProxyConnection<HttpResponse>public TransportProtocol getTransportProtocol()
public ChainedProxyType getChainedProxyType()
public InetSocketAddress getRemoteAddress()
public String getServerHostAndPort()
public boolean hasUpstreamChainedProxy()
public InetSocketAddress getChainedProxyAddress()
public ChainedProxy getChainedProxy()
public HttpRequest getInitialRequest()
protected HttpFilters getHttpFiltersFromProxyServer(HttpRequest httpRequest)
ProxyConnectiongetHttpFiltersFromProxyServer in class ProxyConnection<HttpResponse>httpRequest - Filter attached to the give HttpRequest (if any)private void rememberCurrentResponse(HttpResponse response)
private void respondWith(HttpObject httpObject)
HttpObject.private void connectAndWrite(HttpRequest initialRequest)
ConnectionFlow.initialRequest - the current HTTP request being handledprivate void initializeConnectionFlow()
ConnectionFlow based on however this connection has been configured. If
the disableSni value is true, this method will not pass peer information to the MitmManager when
handling CONNECTs.private void addFirstOrReplaceHandler(String name, ChannelHandler handler)
private void removeHandlerIfPresent(String name)
protected boolean connectionFailed(Throwable cause) throws UnknownHostException
cause - the reason that our attempt to connect failed (can be null)UnknownHostExceptionprivate void resetConnectionForRetry()
throws UnknownHostException
setupConnectionParameters().UnknownHostException - when setupConnectionParameters() is unable to resolve the hostnameprivate void setupConnectionParameters()
throws UnknownHostException
UnknownHostException - when unable to resolve the hostname to an IP addressprivate void initChannelPipeline(ChannelPipeline pipeline, HttpRequest httpRequest)
ChannelPipeline to connect the upstream server.
LittleProxy acts as a client here.
A ChannelPipeline invokes the read (Inbound) handlers in
ascending ordering of the list and then the write (Outbound) handlers in
descending ordering.
Regarding the Javadoc of HttpObjectAggregator it's needed to have
the HttpResponseEncoder or HttpRequestEncoder before the
HttpObjectAggregator in the ChannelPipeline.void connectionSucceeded(boolean shouldForwardInitialRequest)
Do all the stuff that needs to be done after our ConnectionFlow
has succeeded.
shouldForwardInitialRequest - whether or not we should forward the initial HttpRequest to
the server after the connection has been established.public static InetSocketAddress addressFor(String hostAndPort, DefaultHttpProxyServer proxyServer) throws UnknownHostException
InetSocketAddress for the given hostAndPort.hostAndPort - String representation of the host and portproxyServer - the current DefaultHttpProxyServerUnknownHostException - if hostAndPort could not be resolved, or if the input string could not be parsed into
a host and port.private static InetSocketAddress unresolvedAddressFor(String hostAndPort)
addressFor(String, DefaultHttpProxyServer) except that it does
not resolve the address.hostAndPort - the host and port to parse.InetSocketAddress.void switchToWebSocketProtocol()
Copyright © 2009–2021. All rights reserved.