Class AbstractProxyServlet

  • All Implemented Interfaces:
    java.io.Serializable, javax.servlet.Servlet, javax.servlet.ServletConfig
    Direct Known Subclasses:
    AsyncMiddleManServlet, ProxyServlet

    public abstract class AbstractProxyServlet
    extends javax.servlet.http.HttpServlet

    Abstract base class for proxy servlets.

    Forwards requests to another server either as a standard web reverse proxy or as a transparent reverse proxy (as defined by RFC 7230).

    To facilitate JMX monitoring, the HttpClient instance is set as ServletContext attribute, prefixed with this servlet's name and exposed by the mechanism provided by ServletContext.setAttribute(String, Object).

    The following init parameters may be used to configure the servlet:

    • preserveHost - the host header specified by the client is forwarded to the server
    • hostHeader - forces the host header to a particular value
    • viaHost - the name to use in the Via header: Via: http/1.1 <viaHost>
    • whiteList - comma-separated list of allowed proxy hosts
    • blackList - comma-separated list of forbidden proxy hosts

    In addition, see createHttpClient() for init parameters used to configure the HttpClient instance.

    NOTE: By default the Host header sent to the server by this proxy servlet is the server's host name. However, this breaks redirects. Set preserveHost to true to make redirects working, although this may break server's virtual host selection.

    The default behavior of not preserving the Host header mimics the default behavior of Apache httpd and Nginx, which both have a way to be configured to preserve the Host header.

    See Also:
    Serialized Form
    • Nested Class Summary

      Nested Classes 
      Modifier and Type Class Description
      protected static class  AbstractProxyServlet.TransparentDelegate
      Utility class that implement transparent proxy functionalities.
    • Method Summary

      All Methods Instance Methods Abstract Methods Concrete Methods 
      Modifier and Type Method Description
      protected void addProxyHeaders​(javax.servlet.http.HttpServletRequest clientRequest, Request proxyRequest)  
      protected void addViaHeader​(javax.servlet.http.HttpServletRequest clientRequest, Request proxyRequest)
      Adds the HTTP Via header to the proxied request, taking into account data present in the client request.
      protected void addViaHeader​(Request proxyRequest)
      Adds the HTTP Via header to the proxied request.
      protected void addXForwardedHeaders​(javax.servlet.http.HttpServletRequest clientRequest, Request proxyRequest)  
      protected int clientRequestStatus​(java.lang.Throwable failure)  
      protected void copyRequestHeaders​(javax.servlet.http.HttpServletRequest clientRequest, Request proxyRequest)  
      protected HttpClient createHttpClient()
      Creates a HttpClient instance, configured with init parameters of this servlet.
      protected Logger createLogger()  
      void destroy()  
      protected boolean expects100Continue​(javax.servlet.http.HttpServletRequest request)  
      protected java.lang.String filterServerResponseHeader​(javax.servlet.http.HttpServletRequest clientRequest, Response serverResponse, java.lang.String headerName, java.lang.String headerValue)  
      protected java.util.Set<java.lang.String> findConnectionHeaders​(javax.servlet.http.HttpServletRequest clientRequest)  
      java.util.Set<java.lang.String> getBlackListHosts()  
      java.lang.String getHostHeader()  
      protected HttpClient getHttpClient()  
      protected int getRequestId​(javax.servlet.http.HttpServletRequest clientRequest)  
      long getTimeout()  
      java.lang.String getViaHost()  
      java.util.Set<java.lang.String> getWhiteListHosts()  
      protected boolean hasContent​(javax.servlet.http.HttpServletRequest clientRequest)  
      void init()  
      protected HttpClient newHttpClient()
      The servlet init parameter 'selectors' can be set for the number of selector threads to be used by the HttpClient.
      protected Request newProxyRequest​(javax.servlet.http.HttpServletRequest request, java.lang.String rewrittenTarget)  
      protected abstract Response.CompleteListener newProxyResponseListener​(javax.servlet.http.HttpServletRequest clientRequest, javax.servlet.http.HttpServletResponse proxyResponse)  
      protected void onClientRequestFailure​(javax.servlet.http.HttpServletRequest clientRequest, Request proxyRequest, javax.servlet.http.HttpServletResponse proxyResponse, java.lang.Throwable failure)  
      protected void onContinue​(javax.servlet.http.HttpServletRequest clientRequest, Request proxyRequest)  
      protected void onProxyResponseFailure​(javax.servlet.http.HttpServletRequest clientRequest, javax.servlet.http.HttpServletResponse proxyResponse, Response serverResponse, java.lang.Throwable failure)  
      protected void onProxyResponseSuccess​(javax.servlet.http.HttpServletRequest clientRequest, javax.servlet.http.HttpServletResponse proxyResponse, Response serverResponse)  
      protected void onProxyRewriteFailed​(javax.servlet.http.HttpServletRequest clientRequest, javax.servlet.http.HttpServletResponse proxyResponse)
      Callback method invoked when the URI rewrite performed in rewriteTarget(HttpServletRequest) returns null indicating that no rewrite can be performed.
      protected void onServerResponseHeaders​(javax.servlet.http.HttpServletRequest clientRequest, javax.servlet.http.HttpServletResponse proxyResponse, Response serverResponse)  
      protected int proxyResponseStatus​(java.lang.Throwable failure)  
      protected java.lang.String rewriteTarget​(javax.servlet.http.HttpServletRequest clientRequest)  
      protected void sendProxyRequest​(javax.servlet.http.HttpServletRequest clientRequest, javax.servlet.http.HttpServletResponse proxyResponse, Request proxyRequest)  
      protected void sendProxyResponseError​(javax.servlet.http.HttpServletRequest clientRequest, javax.servlet.http.HttpServletResponse proxyResponse, int status)  
      void setTimeout​(long timeout)  
      boolean validateDestination​(java.lang.String host, int port)
      Checks the given host and port against whitelist and blacklist.
      • Methods inherited from class javax.servlet.http.HttpServlet

        doDelete, doGet, doHead, doOptions, doPost, doPut, doTrace, getLastModified, service, service
      • Methods inherited from class javax.servlet.GenericServlet

        getInitParameter, getInitParameterNames, getServletConfig, getServletContext, getServletInfo, getServletName, init, log, log
      • Methods inherited from class java.lang.Object

        clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait
    • Field Detail

      • CLIENT_REQUEST_ATTRIBUTE

        protected static final java.lang.String CLIENT_REQUEST_ATTRIBUTE
        See Also:
        Constant Field Values
      • HOP_HEADERS

        protected static final java.util.Set<java.lang.String> HOP_HEADERS
    • Constructor Detail

      • AbstractProxyServlet

        public AbstractProxyServlet()
    • Method Detail

      • init

        public void init()
                  throws javax.servlet.ServletException
        Overrides:
        init in class javax.servlet.GenericServlet
        Throws:
        javax.servlet.ServletException
      • destroy

        public void destroy()
        Specified by:
        destroy in interface javax.servlet.Servlet
        Overrides:
        destroy in class javax.servlet.GenericServlet
      • getHostHeader

        public java.lang.String getHostHeader()
      • getViaHost

        public java.lang.String getViaHost()
      • getTimeout

        public long getTimeout()
      • setTimeout

        public void setTimeout​(long timeout)
      • getWhiteListHosts

        public java.util.Set<java.lang.String> getWhiteListHosts()
      • getBlackListHosts

        public java.util.Set<java.lang.String> getBlackListHosts()
      • createLogger

        protected Logger createLogger()
        Returns:
        a logger instance with a name derived from this servlet's name.
      • newHttpClient

        protected HttpClient newHttpClient()
        The servlet init parameter 'selectors' can be set for the number of selector threads to be used by the HttpClient.
        Returns:
        a new HttpClient instance
      • getHttpClient

        protected HttpClient getHttpClient()
      • validateDestination

        public boolean validateDestination​(java.lang.String host,
                                           int port)
        Checks the given host and port against whitelist and blacklist.
        Parameters:
        host - the host to check
        port - the port to check
        Returns:
        true if it is allowed to be proxy to the given host and port
      • rewriteTarget

        protected java.lang.String rewriteTarget​(javax.servlet.http.HttpServletRequest clientRequest)
      • onProxyRewriteFailed

        protected void onProxyRewriteFailed​(javax.servlet.http.HttpServletRequest clientRequest,
                                            javax.servlet.http.HttpServletResponse proxyResponse)

        Callback method invoked when the URI rewrite performed in rewriteTarget(HttpServletRequest) returns null indicating that no rewrite can be performed.

        It is possible to use blocking API in this method, like HttpServletResponse.sendError(int).

        Parameters:
        clientRequest - the client request
        proxyResponse - the client response
      • hasContent

        protected boolean hasContent​(javax.servlet.http.HttpServletRequest clientRequest)
      • expects100Continue

        protected boolean expects100Continue​(javax.servlet.http.HttpServletRequest request)
      • newProxyRequest

        protected Request newProxyRequest​(javax.servlet.http.HttpServletRequest request,
                                          java.lang.String rewrittenTarget)
      • copyRequestHeaders

        protected void copyRequestHeaders​(javax.servlet.http.HttpServletRequest clientRequest,
                                          Request proxyRequest)
      • findConnectionHeaders

        protected java.util.Set<java.lang.String> findConnectionHeaders​(javax.servlet.http.HttpServletRequest clientRequest)
      • addProxyHeaders

        protected void addProxyHeaders​(javax.servlet.http.HttpServletRequest clientRequest,
                                       Request proxyRequest)
      • addViaHeader

        protected void addViaHeader​(javax.servlet.http.HttpServletRequest clientRequest,
                                    Request proxyRequest)

        Adds the HTTP Via header to the proxied request, taking into account data present in the client request.

        This method considers the protocol of the client request when forming the proxied request. If it is HTTP, then the protocol name will not be included in the Via header that is sent by the proxy, and only the protocol version will be sent. If it is not, the entire protocol (name and version) will be included. If the client request includes a Via header, the result will be appended to that to form a chain.

        Parameters:
        clientRequest - the client request
        proxyRequest - the request being proxied
        See Also:
        RFC 7230 section 5.7.1
      • addXForwardedHeaders

        protected void addXForwardedHeaders​(javax.servlet.http.HttpServletRequest clientRequest,
                                            Request proxyRequest)
      • sendProxyRequest

        protected void sendProxyRequest​(javax.servlet.http.HttpServletRequest clientRequest,
                                        javax.servlet.http.HttpServletResponse proxyResponse,
                                        Request proxyRequest)
      • newProxyResponseListener

        protected abstract Response.CompleteListener newProxyResponseListener​(javax.servlet.http.HttpServletRequest clientRequest,
                                                                              javax.servlet.http.HttpServletResponse proxyResponse)
      • onClientRequestFailure

        protected void onClientRequestFailure​(javax.servlet.http.HttpServletRequest clientRequest,
                                              Request proxyRequest,
                                              javax.servlet.http.HttpServletResponse proxyResponse,
                                              java.lang.Throwable failure)
      • clientRequestStatus

        protected int clientRequestStatus​(java.lang.Throwable failure)
      • onServerResponseHeaders

        protected void onServerResponseHeaders​(javax.servlet.http.HttpServletRequest clientRequest,
                                               javax.servlet.http.HttpServletResponse proxyResponse,
                                               Response serverResponse)
      • filterServerResponseHeader

        protected java.lang.String filterServerResponseHeader​(javax.servlet.http.HttpServletRequest clientRequest,
                                                              Response serverResponse,
                                                              java.lang.String headerName,
                                                              java.lang.String headerValue)
      • onProxyResponseSuccess

        protected void onProxyResponseSuccess​(javax.servlet.http.HttpServletRequest clientRequest,
                                              javax.servlet.http.HttpServletResponse proxyResponse,
                                              Response serverResponse)
      • onProxyResponseFailure

        protected void onProxyResponseFailure​(javax.servlet.http.HttpServletRequest clientRequest,
                                              javax.servlet.http.HttpServletResponse proxyResponse,
                                              Response serverResponse,
                                              java.lang.Throwable failure)
      • proxyResponseStatus

        protected int proxyResponseStatus​(java.lang.Throwable failure)
      • getRequestId

        protected int getRequestId​(javax.servlet.http.HttpServletRequest clientRequest)
      • sendProxyResponseError

        protected void sendProxyResponseError​(javax.servlet.http.HttpServletRequest clientRequest,
                                              javax.servlet.http.HttpServletResponse proxyResponse,
                                              int status)
      • onContinue

        protected void onContinue​(javax.servlet.http.HttpServletRequest clientRequest,
                                  Request proxyRequest)