Class AbstractProxyServlet

java.lang.Object
jakarta.servlet.GenericServlet
jakarta.servlet.http.HttpServlet
org.eclipse.jetty.proxy.AbstractProxyServlet
All Implemented Interfaces:
jakarta.servlet.Servlet, jakarta.servlet.ServletConfig, Serializable
Direct Known Subclasses:
AsyncMiddleManServlet, ProxyServlet

public abstract class AbstractProxyServlet extends jakarta.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:
  • Nested Class Summary

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

    Fields
    Modifier and Type
    Field
    Description
    protected org.slf4j.Logger
     
    protected static final String
     
    protected static final Set<String>
     
  • Constructor Summary

    Constructors
    Constructor
    Description
     
  • Method Summary

    Modifier and Type
    Method
    Description
    protected void
    addProxyHeaders(jakarta.servlet.http.HttpServletRequest clientRequest, org.eclipse.jetty.client.api.Request proxyRequest)
     
    protected void
    addViaHeader(jakarta.servlet.http.HttpServletRequest clientRequest, org.eclipse.jetty.client.api.Request proxyRequest)
    Adds the HTTP Via header to the proxied request, taking into account data present in the client request.
    protected void
    addViaHeader(org.eclipse.jetty.client.api.Request proxyRequest)
    Adds the HTTP Via header to the proxied request.
    protected void
    addXForwardedHeaders(jakarta.servlet.http.HttpServletRequest clientRequest, org.eclipse.jetty.client.api.Request proxyRequest)
     
    protected int
     
    protected void
    copyRequestHeaders(jakarta.servlet.http.HttpServletRequest clientRequest, org.eclipse.jetty.client.api.Request proxyRequest)
     
    protected org.eclipse.jetty.client.HttpClient
    Creates a HttpClient instance, configured with init parameters of this servlet.
    protected org.slf4j.Logger
     
    void
     
    protected boolean
    expects100Continue(jakarta.servlet.http.HttpServletRequest request)
     
    protected String
    filterServerResponseHeader(jakarta.servlet.http.HttpServletRequest clientRequest, org.eclipse.jetty.client.api.Response serverResponse, String headerName, String headerValue)
     
    protected Set<String>
    findConnectionHeaders(jakarta.servlet.http.HttpServletRequest clientRequest)
     
     
     
    protected org.eclipse.jetty.client.HttpClient
     
    protected int
    getRequestId(jakarta.servlet.http.HttpServletRequest clientRequest)
     
    long
     
     
     
    protected boolean
    hasContent(jakarta.servlet.http.HttpServletRequest clientRequest)
     
    void
     
    protected org.eclipse.jetty.io.ClientConnector
     
    protected org.eclipse.jetty.client.HttpClient
    The servlet init parameter 'selectors' can be set for the number of selector threads to be used by the HttpClient.
    protected org.eclipse.jetty.client.HttpClient
    newHttpClient(org.eclipse.jetty.io.ClientConnector clientConnector)
     
    protected org.eclipse.jetty.client.api.Request
    newProxyRequest(jakarta.servlet.http.HttpServletRequest request, String rewrittenTarget)
     
    protected abstract org.eclipse.jetty.client.api.Response.CompleteListener
    newProxyResponseListener(jakarta.servlet.http.HttpServletRequest clientRequest, jakarta.servlet.http.HttpServletResponse proxyResponse)
     
    protected void
    onClientRequestFailure(jakarta.servlet.http.HttpServletRequest clientRequest, org.eclipse.jetty.client.api.Request proxyRequest, jakarta.servlet.http.HttpServletResponse proxyResponse, Throwable failure)
     
    protected void
    onContinue(jakarta.servlet.http.HttpServletRequest clientRequest, org.eclipse.jetty.client.api.Request proxyRequest)
     
    protected void
    onProxyResponseFailure(jakarta.servlet.http.HttpServletRequest clientRequest, jakarta.servlet.http.HttpServletResponse proxyResponse, org.eclipse.jetty.client.api.Response serverResponse, Throwable failure)
     
    protected void
    onProxyResponseSuccess(jakarta.servlet.http.HttpServletRequest clientRequest, jakarta.servlet.http.HttpServletResponse proxyResponse, org.eclipse.jetty.client.api.Response serverResponse)
     
    protected void
    onProxyRewriteFailed(jakarta.servlet.http.HttpServletRequest clientRequest, jakarta.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(jakarta.servlet.http.HttpServletRequest clientRequest, jakarta.servlet.http.HttpServletResponse proxyResponse, org.eclipse.jetty.client.api.Response serverResponse)
     
    protected int
     
    protected String
    rewriteTarget(jakarta.servlet.http.HttpServletRequest clientRequest)
     
    protected void
    sendProxyRequest(jakarta.servlet.http.HttpServletRequest clientRequest, jakarta.servlet.http.HttpServletResponse proxyResponse, org.eclipse.jetty.client.api.Request proxyRequest)
     
    protected void
    sendProxyResponseError(jakarta.servlet.http.HttpServletRequest clientRequest, jakarta.servlet.http.HttpServletResponse proxyResponse, int status)
     
    void
    setTimeout(long timeout)
     
    boolean
    validateDestination(String host, int port)
    Checks the given host and port against whitelist and blacklist.

    Methods inherited from class jakarta.servlet.http.HttpServlet

    doDelete, doGet, doHead, doOptions, doPost, doPut, doTrace, getLastModified, service, service

    Methods inherited from class jakarta.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 Details

    • CLIENT_REQUEST_ATTRIBUTE

      protected static final String CLIENT_REQUEST_ATTRIBUTE
      See Also:
    • HOP_HEADERS

      protected static final Set<String> HOP_HEADERS
    • _log

      protected org.slf4j.Logger _log
  • Constructor Details

    • AbstractProxyServlet

      public AbstractProxyServlet()
  • Method Details

    • init

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

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

      public String getHostHeader()
    • getViaHost

      public String getViaHost()
    • getTimeout

      public long getTimeout()
    • setTimeout

      public void setTimeout(long timeout)
    • getWhiteListHosts

      public Set<String> getWhiteListHosts()
    • getBlackListHosts

      public Set<String> getBlackListHosts()
    • createLogger

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

      protected org.eclipse.jetty.client.HttpClient createHttpClient() throws jakarta.servlet.ServletException

      Creates a HttpClient instance, configured with init parameters of this servlet.

      The init parameters used to configure the HttpClient instance are:

      Init Parameters
      init-param default description
      maxThreads 256 The max number of threads of HttpClient's Executor. If not set, or set to the value of "-", then the Jetty server thread pool will be used.
      maxConnections 32768 The max number of connections per destination, see HttpClient.setMaxConnectionsPerDestination(int)
      idleTimeout 30000 The idle timeout in milliseconds, see HttpClient.setIdleTimeout(long)
      timeout 60000 The total timeout in milliseconds, see Request.timeout(long, java.util.concurrent.TimeUnit)
      requestBufferSize HttpClient's default The request buffer size, see HttpClient.setRequestBufferSize(int)
      responseBufferSize HttpClient's default The response buffer size, see HttpClient.setResponseBufferSize(int)
      selectors cores / 2 The number of NIO selectors used by HttpClient
      Returns:
      a HttpClient configured from the servlet configuration
      Throws:
      jakarta.servlet.ServletException - if the HttpClient cannot be created
      See Also:
    • newHttpClient

      protected org.eclipse.jetty.client.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
    • newHttpClient

      protected org.eclipse.jetty.client.HttpClient newHttpClient(org.eclipse.jetty.io.ClientConnector clientConnector)
    • newClientConnector

      protected org.eclipse.jetty.io.ClientConnector newClientConnector()
    • getHttpClient

      protected org.eclipse.jetty.client.HttpClient getHttpClient()
    • validateDestination

      public boolean validateDestination(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 String rewriteTarget(jakarta.servlet.http.HttpServletRequest clientRequest)
    • onProxyRewriteFailed

      protected void onProxyRewriteFailed(jakarta.servlet.http.HttpServletRequest clientRequest, jakarta.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(jakarta.servlet.http.HttpServletRequest clientRequest)
    • expects100Continue

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

      protected org.eclipse.jetty.client.api.Request newProxyRequest(jakarta.servlet.http.HttpServletRequest request, String rewrittenTarget)
    • copyRequestHeaders

      protected void copyRequestHeaders(jakarta.servlet.http.HttpServletRequest clientRequest, org.eclipse.jetty.client.api.Request proxyRequest)
    • findConnectionHeaders

      protected Set<String> findConnectionHeaders(jakarta.servlet.http.HttpServletRequest clientRequest)
    • addProxyHeaders

      protected void addProxyHeaders(jakarta.servlet.http.HttpServletRequest clientRequest, org.eclipse.jetty.client.api.Request proxyRequest)
    • addViaHeader

      protected void addViaHeader(org.eclipse.jetty.client.api.Request proxyRequest)
      Adds the HTTP Via header to the proxied request.
      Parameters:
      proxyRequest - the request being proxied
      See Also:
    • addViaHeader

      protected void addViaHeader(jakarta.servlet.http.HttpServletRequest clientRequest, org.eclipse.jetty.client.api.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:
    • addXForwardedHeaders

      protected void addXForwardedHeaders(jakarta.servlet.http.HttpServletRequest clientRequest, org.eclipse.jetty.client.api.Request proxyRequest)
    • sendProxyRequest

      protected void sendProxyRequest(jakarta.servlet.http.HttpServletRequest clientRequest, jakarta.servlet.http.HttpServletResponse proxyResponse, org.eclipse.jetty.client.api.Request proxyRequest)
    • newProxyResponseListener

      protected abstract org.eclipse.jetty.client.api.Response.CompleteListener newProxyResponseListener(jakarta.servlet.http.HttpServletRequest clientRequest, jakarta.servlet.http.HttpServletResponse proxyResponse)
    • onClientRequestFailure

      protected void onClientRequestFailure(jakarta.servlet.http.HttpServletRequest clientRequest, org.eclipse.jetty.client.api.Request proxyRequest, jakarta.servlet.http.HttpServletResponse proxyResponse, Throwable failure)
    • clientRequestStatus

      protected int clientRequestStatus(Throwable failure)
    • onServerResponseHeaders

      protected void onServerResponseHeaders(jakarta.servlet.http.HttpServletRequest clientRequest, jakarta.servlet.http.HttpServletResponse proxyResponse, org.eclipse.jetty.client.api.Response serverResponse)
    • filterServerResponseHeader

      protected String filterServerResponseHeader(jakarta.servlet.http.HttpServletRequest clientRequest, org.eclipse.jetty.client.api.Response serverResponse, String headerName, String headerValue)
    • onProxyResponseSuccess

      protected void onProxyResponseSuccess(jakarta.servlet.http.HttpServletRequest clientRequest, jakarta.servlet.http.HttpServletResponse proxyResponse, org.eclipse.jetty.client.api.Response serverResponse)
    • onProxyResponseFailure

      protected void onProxyResponseFailure(jakarta.servlet.http.HttpServletRequest clientRequest, jakarta.servlet.http.HttpServletResponse proxyResponse, org.eclipse.jetty.client.api.Response serverResponse, Throwable failure)
    • proxyResponseStatus

      protected int proxyResponseStatus(Throwable failure)
    • getRequestId

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

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

      protected void onContinue(jakarta.servlet.http.HttpServletRequest clientRequest, org.eclipse.jetty.client.api.Request proxyRequest)