public class ClientToProxyConnection extends HttpProxyConnection<HttpRequestWrapper>
Represents a connection from a client to our proxy. Each ClientToProxyConnection can have multiple
ProxyToServerConnections, at most one per outbound host:port.
Once a ProxyToServerConnection has been created for a given server, it is continually reused. The
ProxyToServerConnection goes through its own lifecycle of connects and disconnects, with different underlying
Channels, but only a single ProxyToServerConnection object is used per server. The one exception to this is
CONNECT tunneling - if a connection has been used for CONNECT tunneling, that connection will never be reused.
As the ProxyToServerConnections receive responses from their servers, they feed these back to the client by calling
respond(ProxyToServerConnection, HttpFilters, HttpRequest, HttpResponse, HttpObject) .
HttpProxyConnection.RequestReadMonitor, HttpProxyConnection.RequestWrittenMonitor, HttpProxyConnection.ResponseReadMonitor, HttpProxyConnection.ResponseWrittenMonitorChannelHandler.Sharable| 限定符和类型 | 字段和说明 |
|---|---|
private SSLSession |
clientSslSession |
private HttpFilters |
currentFilters |
private ProxyToServerConnection |
currentServerConnection |
private io.netty.handler.traffic.GlobalTrafficShapingHandler |
globalTrafficShapingHandler |
private HttpProxyConfigOptions |
httpProxyConfigOptions |
private static String |
LOWERCASE_TRANSFER_ENCODING_HEADER |
private AtomicInteger |
numberOfCurrentlyConnectingServers |
private ProxyConfigOptions |
proxyConfigOptions |
private HttpProxyConnection.RequestReadMonitor |
requestReadMonitor
Activity Tracking/Statistics
We track statistics on bytes, requests and responses by adding handlers at the appropriate parts of the pipeline
(see initChannelPipeline()).
|
private HttpProxyConnection.ResponseWrittenMonitor |
responseWrittenMonitor |
private Map<InetSocketAddress,ProxyToServerConnection> |
serverConnectionsMap |
log, proxyManagerchannel, ctx, lastReadTime, logger, sslEngine| 构造器和说明 |
|---|
ClientToProxyConnection(ProxyConfigOptions proxyConfigOptions,
HttpProxyConfigOptions httpProxyConfigOptions,
HttpProxyManager httpProxyManager,
String applicationName,
SslEngineSource sslEngineSource,
ChannelPipeline pipeline,
io.netty.handler.traffic.GlobalTrafficShapingHandler globalTrafficShapingHandler) |
| 限定符和类型 | 方法和说明 |
|---|---|
private InetSocketAddress |
addressFor(ProxyRuleOption proxy,
HttpProxyManager proxyServer)
Build an
InetSocketAddress for the given hostAndPort. |
protected void |
becameSaturated()
When the ClientToProxyConnection becomes saturated, stop reading on all associated ProxyToServerConnections.
|
protected void |
becameWritable()
When the ClientToProxyConnection becomes writable, resume reading on all associated ProxyToServerConnections.
|
private void |
closeConnectionsAfterWriteIfNecessary(ProxyToServerConnection serverConnection,
io.netty.handler.codec.http.HttpRequest currentHttpRequest,
io.netty.handler.codec.http.HttpResponse currentHttpResponse,
io.netty.handler.codec.http.HttpObject httpObject)
This method takes care of closing client to proxy and/or proxy to server connections after finishing a write.
|
protected void |
connected()
On connect of the client, start waiting for an initial
HttpRequest. |
private void |
connectionFailedUnrecoverably(HttpRequestWrapper initialRequest,
ProxyToServerConnection serverConnection) |
private void |
createCorsHandler(ChannelPipeline pipeline) |
protected void |
disconnected()
On disconnect of the client, disconnect all server connections.
|
private ConnectionState |
doReadHTTPInitial(HttpRequestWrapper httpRequest)
Reads an
HttpRequest. |
protected void |
exceptionCaught(Throwable cause)
Override this to handle exceptions that occurred during asynchronous processing on the
Channel. |
private void |
fixHttpVersionHeaderIfNecessary(io.netty.handler.codec.http.HttpResponse httpResponse)
Chunked encoding is an HTTP 1.1 feature, but sometimes we get a chunked response that reports its HTTP version as
1.0.
|
private FlowContext |
flowContext() |
private void |
forceDisconnect(ProxyToServerConnection serverConnection) |
InetSocketAddress |
getClientAddress() |
protected HttpProxyConfigOptions |
getHttpConfigOptions() |
protected ProxyConfigOptions |
getProxyConfigOptions() |
protected void |
initChannelPipeline(ChannelPipeline pipeline)
Initialize the
ChannelPipeline for the client to proxy channel. |
private void |
modifyRequestHeadersToReflectProxying(io.netty.handler.codec.http.HttpRequest httpRequest)
If and only if our proxy is not running in transparent mode, modify the request headers to reflect that it was
proxied.
|
private void |
modifyResponseHeadersToReflectProxying(io.netty.handler.codec.http.HttpResponse httpResponse)
If and only if our proxy is not running in transparent mode, modify the response headers to reflect that it was
proxied.
|
protected void |
readHTTPChunk(io.netty.handler.codec.http.HttpContent chunk)
Implement this to handle reading a chunk in a chunked transfer.
|
protected ConnectionState |
readHTTPInitial(HttpRequestWrapper httpRequest)
Reading
|
private void |
recordClientConnected() |
private void |
recordClientDisconnected() |
private void |
recordClientSSLHandshakeSucceeded() |
(专用程序包) void |
respond(ProxyToServerConnection serverConnection,
HttpFilters filters,
io.netty.handler.codec.http.HttpRequest currentHttpRequest,
io.netty.handler.codec.http.HttpResponse currentHttpResponse,
io.netty.handler.codec.http.HttpObject httpObject)
Send a response to the client.
|
private boolean |
respondWithShortCircuitResponse(io.netty.handler.codec.http.HttpResponse httpResponse)
Responds to the client with the specified "short-circuit" response.
|
private void |
resumeReadingIfNecessary() |
protected void |
serverBecameSaturated(ProxyToServerConnection serverConnection)
When a server becomes saturated, we stop reading from the client.
|
protected void |
serverBecameWriteable(ProxyToServerConnection serverConnection)
When a server becomes writeable, we check to see if all servers are writeable and if they are, we resume reading.
|
protected boolean |
serverConnectionFailed(ProxyToServerConnection serverConnection,
ConnectionState lastStateBeforeFailure,
Throwable cause)
If the
ProxyToServerConnection fails to complete its connection lifecycle successfully, this method is
called to let us know about it. |
protected void |
serverConnectionFlowStarted(ProxyToServerConnection serverConnection)
Called when
ProxyToServerConnection starts its connection flow. |
protected void |
serverConnectionSucceeded(ProxyToServerConnection serverConnection,
boolean shouldForwardInitialRequest)
If the
ProxyToServerConnection completes its connection lifecycle successfully, this method is called to
let us know about it. |
protected void |
serverDisconnected(ProxyToServerConnection serverConnection)
On disconnect of the server, track that we have one fewer connected servers and then disconnect the client if
necessary.
|
private boolean |
shouldCloseClientConnection(io.netty.handler.codec.http.HttpRequest req,
io.netty.handler.codec.http.HttpResponse res,
io.netty.handler.codec.http.HttpObject httpObject)
Determine whether or not the client connection should be closed.
|
private boolean |
shouldCloseServerConnection(io.netty.handler.codec.http.HttpRequest req,
io.netty.handler.codec.http.HttpResponse res,
io.netty.handler.codec.http.HttpObject msg)
Determines if the remote connection should be closed based on the request and response pair.
|
private void |
stripConnectionTokens(io.netty.handler.codec.http.HttpHeaders headers)
RFC2616 Section 14.10
HTTP/1.1 proxies MUST parse the Connection header field before a message is forwarded and, for each
connection-token in this field, remove any header field(s) from the message with the same name as the
connection-token.
|
private void |
stripHopByHopHeaders(io.netty.handler.codec.http.HttpHeaders headers)
Removes all headers that should not be forwarded.
|
private void |
switchProxyConnectionHeader(io.netty.handler.codec.http.HttpHeaders headers)
Switch the de-facto standard "Proxy-Connection" header to "Connection" when we pass it along to the remote host.
|
protected void |
timedOut()
This method is called when the underlying
Channel times out due to an idle timeout. |
(专用程序包) void |
timedOut(ProxyToServerConnection serverConnection) |
private boolean |
writeBadGateway(HttpRequestWrapper httpRequest)
Tells the client that something went wrong trying to proxy its request.
|
private void |
writeEmptyBuffer()
Write an empty buffer at the end of a chunked transfer.
|
private boolean |
writeGatewayTimeout()
Tells the client that the connection to the server, or possibly to some intermediary service (such as DNS), timed
out.
|
disconnect, doWrite, encrypt, encrypt, getHttpFiltersFromProxyServer, getLOG, getSslEngine, isSaturated, readProxyIncoming, resumeReading, stopReading, write, writeHttp, writeRaw, writeToChannel, writeToChannelNoFlushbecome, channelActive, channelInactive, channelRead0, channelRegistered, channelRegistered0, channelWritabilityChanged, exceptionCaught, getApplicationName, getChannel, getCurrentState, is, isConnecting, readIncoming, userEventTriggeredacceptInboundMessage, channelReadchannelReadComplete, channelUnregisteredensureNotSharable, handlerAdded, handlerRemoved, isSharableclone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, waithandlerAdded, handlerRemovedprivate static final String LOWERCASE_TRANSFER_ENCODING_HEADER
private volatile Map<InetSocketAddress,ProxyToServerConnection> serverConnectionsMap
private final AtomicInteger numberOfCurrentlyConnectingServers
private volatile ProxyToServerConnection currentServerConnection
private volatile HttpFilters currentFilters
private volatile SSLSession clientSslSession
private final io.netty.handler.traffic.GlobalTrafficShapingHandler globalTrafficShapingHandler
private final ProxyConfigOptions proxyConfigOptions
private final HttpProxyConfigOptions httpProxyConfigOptions
private HttpProxyConnection.RequestReadMonitor requestReadMonitor
private HttpProxyConnection.ResponseWrittenMonitor responseWrittenMonitor
public ClientToProxyConnection(ProxyConfigOptions proxyConfigOptions, HttpProxyConfigOptions httpProxyConfigOptions, HttpProxyManager httpProxyManager, String applicationName, SslEngineSource sslEngineSource, ChannelPipeline pipeline, io.netty.handler.traffic.GlobalTrafficShapingHandler globalTrafficShapingHandler)
protected ConnectionState readHTTPInitial(HttpRequestWrapper httpRequest)
readHTTPInitial 在类中 HttpProxyConnection<HttpRequestWrapper>httpRequest - http objectprivate ConnectionState doReadHTTPInitial(HttpRequestWrapper httpRequest)
Reads an HttpRequest.
If we don't yet have a ProxyToServerConnection for the desired server, this takes care of creating it.
Note - the "server" could be a chained proxy, not the final endpoint for the request.
httpRequest - requestprotected void readHTTPChunk(io.netty.handler.codec.http.HttpContent chunk)
HttpProxyConnectionreadHTTPChunk 在类中 HttpProxyConnection<HttpRequestWrapper>chunk - http contentvoid respond(ProxyToServerConnection serverConnection, HttpFilters filters, io.netty.handler.codec.http.HttpRequest currentHttpRequest, io.netty.handler.codec.http.HttpResponse currentHttpResponse, io.netty.handler.codec.http.HttpObject httpObject)
serverConnection - the ProxyToServerConnection that's respondingfilters - the filters to apply to the responsecurrentHttpRequest - the HttpRequest that prompted this responsecurrentHttpResponse - the HttpResponse corresponding to this data (when doing chunked transfers, this is the initial HttpResponse object that came in before the other chunks)httpObject - the data with which to respondprotected void connected()
HttpRequest.void timedOut(ProxyToServerConnection serverConnection)
protected void timedOut()
HttpProxyConnectionChannel times out due to an idle timeout.protected void disconnected()
protected void serverConnectionFlowStarted(ProxyToServerConnection serverConnection)
ProxyToServerConnection starts its connection flow.serverConnection - connectionprotected void serverConnectionSucceeded(ProxyToServerConnection serverConnection, boolean shouldForwardInitialRequest)
ProxyToServerConnection completes its connection lifecycle successfully, this method is called to
let us know about it.serverConnection - connectionshouldForwardInitialRequest - should forward requestprotected boolean serverConnectionFailed(ProxyToServerConnection serverConnection, ConnectionState lastStateBeforeFailure, Throwable cause)
ProxyToServerConnection fails to complete its connection lifecycle successfully, this method is
called to let us know about it.
After failing to connect to the server, one of two things can happen:
serverConnection - connectionlastStateBeforeFailure - failure statecause - what caused the failureprivate void connectionFailedUnrecoverably(HttpRequestWrapper initialRequest, ProxyToServerConnection serverConnection)
private void resumeReadingIfNecessary()
protected void serverDisconnected(ProxyToServerConnection serverConnection)
serverConnection - connectionprotected void becameSaturated()
protected void becameWritable()
protected void serverBecameSaturated(ProxyToServerConnection serverConnection)
serverConnection - connectionprotected void serverBecameWriteable(ProxyToServerConnection serverConnection)
serverConnection - connectionprotected void exceptionCaught(Throwable cause)
HttpProxyConnectionChannel.exceptionCaught 在类中 HttpProxyConnection<HttpRequestWrapper>cause - raised errorprotected void initChannelPipeline(ChannelPipeline pipeline)
ChannelPipeline for the client to proxy channel. Proxy acts like a server 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.pipeline - channel pipelineprotected final ProxyConfigOptions getProxyConfigOptions()
protected final HttpProxyConfigOptions getHttpConfigOptions()
private void createCorsHandler(ChannelPipeline pipeline)
private void closeConnectionsAfterWriteIfNecessary(ProxyToServerConnection serverConnection, io.netty.handler.codec.http.HttpRequest currentHttpRequest, io.netty.handler.codec.http.HttpResponse currentHttpResponse, io.netty.handler.codec.http.HttpObject httpObject)
serverConnection - connectioncurrentHttpRequest - current requestcurrentHttpResponse - current responsehttpObject - htp objectprivate void forceDisconnect(ProxyToServerConnection serverConnection)
private boolean shouldCloseClientConnection(io.netty.handler.codec.http.HttpRequest req,
io.netty.handler.codec.http.HttpResponse res,
io.netty.handler.codec.http.HttpObject httpObject)
req - http requestres - http responsehttpObject - http objectprivate boolean shouldCloseServerConnection(io.netty.handler.codec.http.HttpRequest req,
io.netty.handler.codec.http.HttpResponse res,
io.netty.handler.codec.http.HttpObject msg)
req - The request.res - The response.msg - The message.private void fixHttpVersionHeaderIfNecessary(io.netty.handler.codec.http.HttpResponse httpResponse)
httpResponse - http responseprivate void modifyRequestHeadersToReflectProxying(io.netty.handler.codec.http.HttpRequest httpRequest)
httpRequest - http requestprivate void modifyResponseHeadersToReflectProxying(io.netty.handler.codec.http.HttpResponse httpResponse)
httpResponse - http responseprivate void switchProxyConnectionHeader(io.netty.handler.codec.http.HttpHeaders headers)
headers - The headers to modifyprivate void stripConnectionTokens(io.netty.handler.codec.http.HttpHeaders headers)
headers - The headers to modifyprivate void stripHopByHopHeaders(io.netty.handler.codec.http.HttpHeaders headers)
headers - The headers to modifyprivate boolean writeBadGateway(HttpRequestWrapper httpRequest)
httpRequest - the HttpRequest that is resulting in the Bad Gateway responseprivate boolean writeGatewayTimeout()
private boolean respondWithShortCircuitResponse(io.netty.handler.codec.http.HttpResponse httpResponse)
HttpFilters.proxyToClientResponse(HttpObject) filter method before writing it to the client. The client
will not be disconnected, unless the response includes a "Connection: close" header, or the filter returns a null
HttpResponse (in which case no response will be written to the client and the connection will be disconnected
immediately). If the response is not a Bad Gateway or Gateway Timeout response, the response's headers will be
modified to reflect proxying, including adding a Via header, Date header, etc.httpResponse - the response to return to the clientprivate void writeEmptyBuffer()
private void recordClientConnected()
private void recordClientSSLHandshakeSucceeded()
private void recordClientDisconnected()
public InetSocketAddress getClientAddress()
private FlowContext flowContext()
private InetSocketAddress addressFor(ProxyRuleOption proxy, HttpProxyManager proxyServer) throws UnknownHostException
InetSocketAddress for the given hostAndPort.proxy - rule optionproxyServer - proxu serverUnknownHostException - if hostAndPort could not be resolved, or if the input string could not be parsed into a host and port.Copyright © 2022 Zodiac. All rights reserved.