Class ClientToProxyConnection
- java.lang.Object
-
- io.netty.channel.ChannelHandlerAdapter
-
- io.netty.channel.ChannelInboundHandlerAdapter
-
- io.netty.channel.SimpleChannelInboundHandler<Object>
-
- org.littleshoot.proxy.impl.ProxyConnection<HttpRequest>
-
- org.littleshoot.proxy.impl.ClientToProxyConnection
-
- All Implemented Interfaces:
ChannelHandler,ChannelInboundHandler
public class ClientToProxyConnection extends ProxyConnection<HttpRequest>
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).
-
-
Nested Class Summary
-
Nested classes/interfaces inherited from class org.littleshoot.proxy.impl.ProxyConnection
ProxyConnection.BytesReadMonitor, ProxyConnection.BytesWrittenMonitor, ProxyConnection.RequestReadMonitor, ProxyConnection.RequestWrittenMonitor, ProxyConnection.ResponseReadMonitor, ProxyConnection.ResponseWrittenMonitor
-
Nested classes/interfaces inherited from interface io.netty.channel.ChannelHandler
ChannelHandler.Sharable
-
-
Field Summary
Fields Modifier and Type Field Description private static PatternABSOLUTE_URI_PATTERNUsed for case-insensitive comparisons when checking direct proxy request.private AtomicBooleanauthenticatedprivate ProxyConnection.BytesReadMonitorbytesReadMonitorprivate ProxyConnection.BytesWrittenMonitorbytesWrittenMonitorprivate ClientDetailsclientDetailsprivate SSLSessionclientSslSessionprivate static HttpResponseStatusCONNECTION_ESTABLISHEDprivate HttpFilterscurrentFiltersThe current filters to apply to incoming requests/chunks.private HttpRequestcurrentRequestThe current HTTP request that this connection is currently servicing.private ProxyToServerConnectioncurrentServerConnectionThis is the current server connection that we're using while transferring chunked data.private GlobalTrafficShapingHandlerglobalTrafficShapingHandlerprivate HAProxyMessagehaProxyMessageKeep track of proxy protocol headerprivate static StringHTTP_DECODER_NAMEprivate static StringHTTP_ENCODER_NAMEprivate static StringHTTP_PROXY_DECODER_NAMEprivate static StringHTTP_REQUEST_READ_MONITOR_NAMEprivate static StringHTTP_RESPONSE_WRITTEN_MONITOR_NAMEprivate static StringMAIN_HANDLER_NAMEprivate booleanmitmingTracks whether this ClientToProxyConnection is current doing MITM.private AtomicIntegernumberOfCurrentlyConnectedServersKeep track of how many servers are currently connected.private AtomicIntegernumberOfCurrentlyConnectingServersKeep track of how many servers are currently in the process of connecting.private AtomicIntegernumberOfReusedServerConnectionsKeep track of how many times we were able to reuse a connection.private ProxyConnection.RequestReadMonitorrequestReadMonitor(package private) ConnectionFlowStepRespondCONNECTSuccessfulTells the Client that its HTTP CONNECT request was successful.private ProxyConnection.ResponseWrittenMonitorresponseWrittenMonitorprivate Map<String,ProxyToServerConnection>serverConnectionsByHostAndPortKeep track of all ProxyToServerConnections by host+port.-
Fields inherited from class org.littleshoot.proxy.impl.ProxyConnection
channel, ctx, lastReadTime, LOG, proxyServer, runsAsSslClient, sslEngine, StartTunneling
-
-
Constructor Summary
Constructors Constructor Description ClientToProxyConnection(DefaultHttpProxyServer proxyServer, SslEngineSource sslEngineSource, boolean authenticateClients, ChannelPipeline pipeline, GlobalTrafficShapingHandler globalTrafficShapingHandler)
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description private booleanauthenticationRequired(HttpRequest request)Checks whether the given HttpRequest requires authentication.protected voidbecameSaturated()When the ClientToProxyConnection becomes saturated, stop reading on all associated ProxyToServerConnections.protected voidbecameWritable()When the ClientToProxyConnection becomes writable, resume reading on all associated ProxyToServerConnections.private voidcloseConnectionsAfterWriteIfNecessary(ProxyToServerConnection serverConnection, HttpRequest currentHttpRequest, HttpResponse currentHttpResponse, HttpObject httpObject)This method takes care of closing client to proxy and/or proxy to server connections after finishing a write.protected voidconnected()On connect of the client, start waiting for an initialHttpRequest.private voidconnectionFailedUnrecoverably(HttpRequest initialRequest, ProxyToServerConnection serverConnection)private HttpRequestcopy(HttpRequest original)Copy the givenHttpRequestverbatim.protected voiddisconnected()On disconnect of the client, disconnect all server connections.private ConnectionStatedoReadHTTPInitial(HttpRequest httpRequest)Reads anHttpRequest.protected voidexceptionCaught(Throwable cause)Override this to handle exceptions that occurred during asynchronous processing on theChannel.private voidfixHttpVersionHeaderIfNecessary(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 FlowContextflowContext()private voidforceDisconnect(ProxyToServerConnection serverConnection)InetSocketAddressgetClientAddress()ClientDetailsgetClientDetails()HAProxyMessagegetHaProxyMessage()private StringidentifyHostAndPort(HttpRequest httpRequest)Identify the host and port for a request.private voidinitChannelPipeline(ChannelPipeline pipeline)Initialize theChannelPipelinefor the client to proxy channel.(package private) booleanisAcceptProxyProtocol()Is the proxy server set to accept a proxy protocol headerbooleanisMitming()private booleanisNextHopOriginServer()private booleanisRequestToOriginServer(HttpRequest httpRequest)Returns true if the specified request is a request to an origin server, rather than to a proxy server.(package private) booleanisSendProxyProtocol()Is the proxy server set to send a proxy protocol headerprivate voidmodifyRequestHeadersToReflectProxying(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 voidmodifyResponseHeadersToReflectProxying(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 voidreadHAProxyMessage(HAProxyMessage msg)Read anHAProxyMessageprotected voidreadHTTPChunk(HttpContent chunk)Implement this to handle reading a chunk in a chunked transfer.protected ConnectionStatereadHTTPInitial(HttpRequest httpRequest)Implement this to handle reading the initial object (e.g.protected voidreadRaw(ByteBuf buf)Implement this to handle reading a raw buffer as they are used in HTTP tunneling.private voidrecordClientConnected()private voidrecordClientDisconnected()private voidrecordClientSSLHandshakeSucceeded()private voidremoveHandlerIfPresent(String name)private voidresetCurrentRequest()(package private) voidrespond(ProxyToServerConnection serverConnection, HttpFilters filters, HttpRequest currentHttpRequest, HttpResponse currentHttpResponse, HttpObject httpObject)Send a response to the client.private booleanrespondWithShortCircuitResponse(HttpResponse httpResponse)Responds to the client with the specified "short-circuit" response.private voidresumeReadingIfNecessary()protected voidserverBecameSaturated(ProxyToServerConnection serverConnection)When a server becomes saturated, we stop reading from the client.protected voidserverBecameWriteable(ProxyToServerConnection serverConnection)When a server becomes writeable, we check to see if all servers are writeable and if they are, we resume reading.protected booleanserverConnectionFailed(ProxyToServerConnection serverConnection, ConnectionState lastStateBeforeFailure, Throwable cause)If theProxyToServerConnectionfails to complete its connection lifecycle successfully, this method is called to let us know about it.protected voidserverConnectionFlowStarted(ProxyToServerConnection serverConnection)Called whenProxyToServerConnectionstarts its connection flow.protected voidserverConnectionSucceeded(ProxyToServerConnection serverConnection, boolean shouldForwardInitialRequest)If theProxyToServerConnectioncompletes its connection lifecycle successfully, this method is called to let us know about it.protected voidserverDisconnected(ProxyToServerConnection serverConnection)On disconnect of the server, track that we have one fewer connected servers and then disconnect the client if necessary.protected voidsetMitming(boolean isMitming)private booleanshouldCloseClientConnection(HttpRequest req, HttpResponse res, HttpObject httpObject)Determine whether or not the client connection should be closed.private booleanshouldCloseServerConnection(HttpRequest req, HttpResponse res, HttpObject msg)Determines if the remote connection should be closed based on the request and response pair.private voidstripConnectionTokens(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 voidstripHopByHopHeaders(HttpHeaders headers)Removes all headers that should not be forwarded.private voidswitchProxyConnectionHeader(HttpHeaders headers)Switch the de-facto standard "Proxy-Connection" header to "Connection" when we pass it along to the remote host.private voidswitchToWebSocketProtocol(ProxyToServerConnection serverConnection)protected voidtimedOut()This method is called when the underlyingChanneltimes out due to an idle timeout.(package private) voidtimedOut(ProxyToServerConnection serverConnection)private voidwriteAuthenticationRequired(String realm)private booleanwriteBadGateway(HttpRequest httpRequest)Tells the client that something went wrong trying to proxy its request.private booleanwriteBadRequest(HttpRequest httpRequest)Tells the client that the request was malformed or erroneous.private voidwriteEmptyBuffer()Write an empty buffer at the end of a chunked transfer.private booleanwriteGatewayTimeout(HttpRequest httpRequest)Tells the client that the connection to the server, or possibly to some intermediary service (such as DNS), timed out.-
Methods inherited from class org.littleshoot.proxy.impl.ProxyConnection
aggregateContentForFiltering, become, channelActive, channelInactive, channelRead0, channelRegistered, channelUnregistered, channelWritabilityChanged, disconnect, doWrite, encrypt, encrypt, EncryptChannel, exceptionCaught, getCurrentState, getHttpFiltersFromProxyServer, getLOG, getSslEngine, is, isConnecting, isSaturated, isTunneling, read, removeHandlerIfPresent, resumeReading, stopReading, userEventTriggered, write, writeHttp, writeRaw, writeToChannel
-
Methods inherited from class io.netty.channel.SimpleChannelInboundHandler
acceptInboundMessage, channelRead
-
Methods inherited from class io.netty.channel.ChannelInboundHandlerAdapter
channelReadComplete
-
Methods inherited from class io.netty.channel.ChannelHandlerAdapter
ensureNotSharable, handlerAdded, handlerRemoved, isSharable
-
Methods inherited from class java.lang.Object
clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
-
Methods inherited from interface io.netty.channel.ChannelHandler
handlerAdded, handlerRemoved
-
-
-
-
Field Detail
-
CONNECTION_ESTABLISHED
private static final HttpResponseStatus CONNECTION_ESTABLISHED
-
HTTP_ENCODER_NAME
private static final String HTTP_ENCODER_NAME
- See Also:
- Constant Field Values
-
HTTP_DECODER_NAME
private static final String HTTP_DECODER_NAME
- See Also:
- Constant Field Values
-
HTTP_PROXY_DECODER_NAME
private static final String HTTP_PROXY_DECODER_NAME
- See Also:
- Constant Field Values
-
HTTP_REQUEST_READ_MONITOR_NAME
private static final String HTTP_REQUEST_READ_MONITOR_NAME
- See Also:
- Constant Field Values
-
HTTP_RESPONSE_WRITTEN_MONITOR_NAME
private static final String HTTP_RESPONSE_WRITTEN_MONITOR_NAME
- See Also:
- Constant Field Values
-
MAIN_HANDLER_NAME
private static final String MAIN_HANDLER_NAME
- See Also:
- Constant Field Values
-
ABSOLUTE_URI_PATTERN
private static final Pattern ABSOLUTE_URI_PATTERN
Used for case-insensitive comparisons when checking direct proxy request.
-
serverConnectionsByHostAndPort
private final Map<String,ProxyToServerConnection> serverConnectionsByHostAndPort
Keep track of all ProxyToServerConnections by host+port.
-
numberOfCurrentlyConnectingServers
private final AtomicInteger numberOfCurrentlyConnectingServers
Keep track of how many servers are currently in the process of connecting.
-
haProxyMessage
private HAProxyMessage haProxyMessage
Keep track of proxy protocol header
-
numberOfCurrentlyConnectedServers
private final AtomicInteger numberOfCurrentlyConnectedServers
Keep track of how many servers are currently connected.
-
numberOfReusedServerConnections
private final AtomicInteger numberOfReusedServerConnections
Keep track of how many times we were able to reuse a connection.
-
currentServerConnection
private volatile ProxyToServerConnection currentServerConnection
This is the current server connection that we're using while transferring chunked data.
-
currentFilters
private volatile HttpFilters currentFilters
The current filters to apply to incoming requests/chunks.
-
clientSslSession
private volatile SSLSession clientSslSession
-
mitming
private volatile boolean mitming
Tracks whether this ClientToProxyConnection is current doing MITM.
-
authenticated
private final AtomicBoolean authenticated
-
globalTrafficShapingHandler
private final GlobalTrafficShapingHandler globalTrafficShapingHandler
-
currentRequest
private volatile HttpRequest currentRequest
The current HTTP request that this connection is currently servicing.
-
clientDetails
private final ClientDetails clientDetails
-
RespondCONNECTSuccessful
ConnectionFlowStep RespondCONNECTSuccessful
Tells the Client that its HTTP CONNECT request was successful.
-
bytesReadMonitor
private final ProxyConnection.BytesReadMonitor bytesReadMonitor
-
requestReadMonitor
private final ProxyConnection.RequestReadMonitor requestReadMonitor
-
bytesWrittenMonitor
private final ProxyConnection.BytesWrittenMonitor bytesWrittenMonitor
-
responseWrittenMonitor
private final ProxyConnection.ResponseWrittenMonitor responseWrittenMonitor
-
-
Constructor Detail
-
ClientToProxyConnection
ClientToProxyConnection(DefaultHttpProxyServer proxyServer, SslEngineSource sslEngineSource, boolean authenticateClients, ChannelPipeline pipeline, GlobalTrafficShapingHandler globalTrafficShapingHandler)
-
-
Method Detail
-
readHAProxyMessage
protected void readHAProxyMessage(HAProxyMessage msg)
Description copied from class:ProxyConnectionRead anHAProxyMessage- Specified by:
readHAProxyMessagein classProxyConnection<HttpRequest>- Parameters:
msg-HAProxyMessage
-
readHTTPInitial
protected ConnectionState readHTTPInitial(HttpRequest httpRequest)
Description copied from class:ProxyConnectionImplement this to handle reading the initial object (e.g.HttpRequestorHttpResponse).- Specified by:
readHTTPInitialin classProxyConnection<HttpRequest>
-
doReadHTTPInitial
private ConnectionState doReadHTTPInitial(HttpRequest httpRequest)
Reads an
HttpRequest.If we don't yet have a
ProxyToServerConnectionfor the desired server, this takes care of creating it.Note - the "server" could be a chained proxy, not the final endpoint for the request.
-
isRequestToOriginServer
private boolean isRequestToOriginServer(HttpRequest httpRequest)
Returns true if the specified request is a request to an origin server, rather than to a proxy server. If this request is being MITM'd, this method always returns false. The format of requests to a proxy server are defined in RFC 7230, section 5.3.2 (all other requests are considered requests to an origin server):When making a request to a proxy, other than a CONNECT or server-wide OPTIONS request (as detailed below), a client MUST send the target URI in absolute-form as the request-target. [...] An example absolute-form of request-line would be: GET https://www.example.org/pub/WWW/TheProject.html HTTP/1.1 To allow for transition to the absolute-form for all requests in some future version of HTTP, a server MUST accept the absolute-form in requests, even though HTTP/1.1 clients will only send them in requests to proxies.- Parameters:
httpRequest- the request to evaluate- Returns:
- true if the specified request is a request to an origin server, otherwise false
-
readHTTPChunk
protected void readHTTPChunk(HttpContent chunk)
Description copied from class:ProxyConnectionImplement this to handle reading a chunk in a chunked transfer.- Specified by:
readHTTPChunkin classProxyConnection<HttpRequest>
-
readRaw
protected void readRaw(ByteBuf buf)
Description copied from class:ProxyConnectionImplement this to handle reading a raw buffer as they are used in HTTP tunneling.- Specified by:
readRawin classProxyConnection<HttpRequest>
-
respond
void respond(ProxyToServerConnection serverConnection, HttpFilters filters, HttpRequest currentHttpRequest, HttpResponse currentHttpResponse, HttpObject httpObject)
Send a response to the client.- Parameters:
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 respond
-
resetCurrentRequest
private void resetCurrentRequest()
-
switchToWebSocketProtocol
private void switchToWebSocketProtocol(ProxyToServerConnection serverConnection)
-
connected
protected void connected()
On connect of the client, start waiting for an initialHttpRequest.- Overrides:
connectedin classProxyConnection<HttpRequest>
-
timedOut
void timedOut(ProxyToServerConnection serverConnection)
-
timedOut
protected void timedOut()
Description copied from class:ProxyConnectionThis method is called when the underlyingChanneltimes out due to an idle timeout.- Overrides:
timedOutin classProxyConnection<HttpRequest>
-
disconnected
protected void disconnected()
On disconnect of the client, disconnect all server connections.- Overrides:
disconnectedin classProxyConnection<HttpRequest>
-
serverConnectionFlowStarted
protected void serverConnectionFlowStarted(ProxyToServerConnection serverConnection)
Called whenProxyToServerConnectionstarts its connection flow.
-
serverConnectionSucceeded
protected void serverConnectionSucceeded(ProxyToServerConnection serverConnection, boolean shouldForwardInitialRequest)
If theProxyToServerConnectioncompletes its connection lifecycle successfully, this method is called to let us know about it.
-
serverConnectionFailed
protected boolean serverConnectionFailed(ProxyToServerConnection serverConnection, ConnectionState lastStateBeforeFailure, Throwable cause)
If theProxyToServerConnectionfails 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:
- If the server was a chained proxy, we fall back to connecting to the ultimate endpoint directly.
- If the server was the ultimate endpoint, we return a 502 Bad Gateway to the client.
- Parameters:
serverConnection-lastStateBeforeFailure-cause- what caused the failure- Returns:
- true if we're falling back to a another chained proxy (or direct connection) and trying again
-
connectionFailedUnrecoverably
private void connectionFailedUnrecoverably(HttpRequest initialRequest, ProxyToServerConnection serverConnection)
-
resumeReadingIfNecessary
private void resumeReadingIfNecessary()
-
serverDisconnected
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.
-
becameSaturated
protected void becameSaturated()
When the ClientToProxyConnection becomes saturated, stop reading on all associated ProxyToServerConnections.- Overrides:
becameSaturatedin classProxyConnection<HttpRequest>
-
becameWritable
protected void becameWritable()
When the ClientToProxyConnection becomes writable, resume reading on all associated ProxyToServerConnections.- Overrides:
becameWritablein classProxyConnection<HttpRequest>
-
serverBecameSaturated
protected void serverBecameSaturated(ProxyToServerConnection serverConnection)
When a server becomes saturated, we stop reading from the client.
-
serverBecameWriteable
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.
-
exceptionCaught
protected void exceptionCaught(Throwable cause)
Description copied from class:ProxyConnectionOverride this to handle exceptions that occurred during asynchronous processing on theChannel.- Overrides:
exceptionCaughtin classProxyConnection<HttpRequest>
-
initChannelPipeline
private void initChannelPipeline(ChannelPipeline pipeline)
Initialize theChannelPipelinefor the client to proxy channel. LittleProxy acts like a server 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.
-
removeHandlerIfPresent
private void removeHandlerIfPresent(String name)
-
isAcceptProxyProtocol
boolean isAcceptProxyProtocol()
Is the proxy server set to accept a proxy protocol header- Returns:
- True if the proxy server set to accept a proxy protocol header. False otherwise
-
isSendProxyProtocol
boolean isSendProxyProtocol()
Is the proxy server set to send a proxy protocol header- Returns:
- True if the proxy server set to send a proxy protocol header. False otherwise
-
closeConnectionsAfterWriteIfNecessary
private void closeConnectionsAfterWriteIfNecessary(ProxyToServerConnection serverConnection, HttpRequest currentHttpRequest, HttpResponse currentHttpResponse, HttpObject httpObject)
This method takes care of closing client to proxy and/or proxy to server connections after finishing a write.
-
forceDisconnect
private void forceDisconnect(ProxyToServerConnection serverConnection)
-
shouldCloseClientConnection
private boolean shouldCloseClientConnection(HttpRequest req, HttpResponse res, HttpObject httpObject)
Determine whether or not the client connection should be closed.
-
shouldCloseServerConnection
private boolean shouldCloseServerConnection(HttpRequest req, HttpResponse res, HttpObject msg)
Determines if the remote connection should be closed based on the request and response pair. If the request is HTTP 1.0 with no keep-alive header, for example, the connection should be closed. This in part determines if we should close the connection. Here's the relevant section of RFC 2616: "HTTP/1.1 defines the "close" connection option for the sender to signal that the connection will be closed after completion of the response. For example, Connection: close in either the request or the response header fields indicates that the connection SHOULD NOT be considered `persistent' (section 8.1) after the current request/response is complete."- Parameters:
req- The request.res- The response.msg- The message.- Returns:
- Returns true if the connection should close.
-
authenticationRequired
private boolean authenticationRequired(HttpRequest request)
Checks whether the given HttpRequest requires authentication.
If the request contains credentials, these are checked.
If authentication is still required, either because no credentials were provided or the credentials were wrong, this writes a 407 response to the client.
-
writeAuthenticationRequired
private void writeAuthenticationRequired(String realm)
-
copy
private HttpRequest copy(HttpRequest original)
Copy the givenHttpRequestverbatim.
-
fixHttpVersionHeaderIfNecessary
private void fixHttpVersionHeaderIfNecessary(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. In this case, we change it to 1.1.
-
modifyRequestHeadersToReflectProxying
private void modifyRequestHeadersToReflectProxying(HttpRequest httpRequest)
If and only if our proxy is not running in transparent mode, modify the request headers to reflect that it was proxied.
-
isNextHopOriginServer
private boolean isNextHopOriginServer()
-
modifyResponseHeadersToReflectProxying
private void modifyResponseHeadersToReflectProxying(HttpResponse httpResponse)
If and only if our proxy is not running in transparent mode, modify the response headers to reflect that it was proxied.
-
switchProxyConnectionHeader
private void switchProxyConnectionHeader(HttpHeaders headers)
Switch the de-facto standard "Proxy-Connection" header to "Connection" when we pass it along to the remote host. This is largely undocumented but seems to be what most browsers and servers expect.- Parameters:
headers- The headers to modify
-
stripConnectionTokens
private void stripConnectionTokens(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.- Parameters:
headers- The headers to modify
-
stripHopByHopHeaders
private void stripHopByHopHeaders(HttpHeaders headers)
Removes all headers that should not be forwarded. See RFC 2616 13.5.1 End-to-end and Hop-by-hop Headers.- Parameters:
headers- The headers to modify
-
writeBadGateway
private boolean writeBadGateway(HttpRequest httpRequest)
Tells the client that something went wrong trying to proxy its request. If the Bad Gateway is a response to an HTTP HEAD request, the response will contain no body, but the Content-Length header will be set to the value it would have been if this 502 Bad Gateway were in response to a GET.- Parameters:
httpRequest- the HttpRequest that is resulting in the Bad Gateway response- Returns:
- true if the connection will be kept open, or false if it will be disconnected
-
writeBadRequest
private boolean writeBadRequest(HttpRequest httpRequest)
Tells the client that the request was malformed or erroneous. If the Bad Request is a response to an HTTP HEAD request, the response will contain no body, but the Content-Length header will be set to the value it would have been if this Bad Request were in response to a GET.- Returns:
- true if the connection will be kept open, or false if it will be disconnected
-
writeGatewayTimeout
private boolean writeGatewayTimeout(HttpRequest httpRequest)
Tells the client that the connection to the server, or possibly to some intermediary service (such as DNS), timed out. If the Gateway Timeout is a response to an HTTP HEAD request, the response will contain no body, but the Content-Length header will be set to the value it would have been if this 504 Gateway Timeout were in response to a GET.- Parameters:
httpRequest- the HttpRequest that is resulting in the Gateway Timeout response- Returns:
- true if the connection will be kept open, or false if it will be disconnected
-
respondWithShortCircuitResponse
private boolean respondWithShortCircuitResponse(HttpResponse httpResponse)
Responds to the client with the specified "short-circuit" response. The response will be sent through theHttpFilters.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.- Parameters:
httpResponse- the response to return to the client- Returns:
- true if the connection will be kept open, or false if it will be disconnected.
-
identifyHostAndPort
private String identifyHostAndPort(HttpRequest httpRequest)
Identify the host and port for a request.
-
writeEmptyBuffer
private void writeEmptyBuffer()
Write an empty buffer at the end of a chunked transfer. We need to do this to handle the way Netty creates HttpChunks from responses that aren't in fact chunked from the remote server using Transfer-Encoding: chunked. Netty turns these into pseudo-chunked responses in cases where the response would otherwise fill up too much memory or where the length of the response body is unknown. This is handy because it means we can start streaming response bodies back to the client without reading the entire response. The problem is that in these pseudo-cases the last chunk is encoded to null, and this thwarts normal ChannelFutures from propagating operationComplete events on writes to appropriate channel listeners. We work around this by writing an empty buffer in those cases and using the empty buffer's future instead to handle any operations we need to when responses are fully written back to clients.
-
isMitming
public boolean isMitming()
-
setMitming
protected void setMitming(boolean isMitming)
-
recordClientConnected
private void recordClientConnected()
-
recordClientSSLHandshakeSucceeded
private void recordClientSSLHandshakeSucceeded()
-
recordClientDisconnected
private void recordClientDisconnected()
-
getClientAddress
public InetSocketAddress getClientAddress()
-
flowContext
private FlowContext flowContext()
-
getHaProxyMessage
public HAProxyMessage getHaProxyMessage()
-
getClientDetails
public ClientDetails getClientDetails()
-
-