Class ProxyServlet

  • All Implemented Interfaces:
    Serializable, javax.servlet.Servlet, javax.servlet.ServletConfig
    Direct Known Subclasses:
    PodServlet, ServiceServlet

    public class ProxyServlet
    extends javax.servlet.http.HttpServlet
    An HTTP reverse proxy/gateway servlet. It is designed to be extended for customization if desired. Most of the work is handled by Apache HttpClient.

    There are alternatives to a servlet based proxy such as Apache mod_proxy if that is available to you. However this servlet is easily customizable by Java, secure-able by your web application's security (e.g. spring-security), portable across servlet engines, and is embeddable into another web application.

    Inspiration: http://httpd.apache.org/docs/2.0/mod/mod_proxy.html

    Original implementation at https://github.com/mitre/HTTP-Proxy-Servlet, released under ASL 2.0.

    Author:
    David Smiley dsmiley@mitre.org
    See Also:
    Serialized Form
    • Field Detail

      • P_LOG

        @Deprecated
        public static final String P_LOG
        Deprecated.
        Use SLF4J Logger
        A boolean parameter name to enable logging of input and target URLs to the servlet log.
        See Also:
        Constant Field Values
      • P_FORWARDEDFOR

        public static final String P_FORWARDEDFOR
        A boolean parameter name to enable forwarding of the client IP
        See Also:
        Constant Field Values
      • enabled

        protected boolean enabled
      • doLog

        protected boolean doLog
      • doForwardIP

        protected boolean doForwardIP
      • acceptSelfSignedCerts

        protected boolean acceptSelfSignedCerts
      • proxyClient

        protected org.apache.http.impl.client.CloseableHttpClient proxyClient
      • hopByHopHeaders

        protected static final org.apache.http.message.HeaderGroup hopByHopHeaders
        These are the "hop-by-hop" headers that should not be copied. http://www.w3.org/Protocols/rfc2616/rfc2616-sec13.html I use an HttpClient HeaderGroup class instead of Set because this approach does case insensitive lookup faster.
      • asciiQueryChars

        protected static final BitSet asciiQueryChars
    • Constructor Detail

      • ProxyServlet

        public ProxyServlet()
    • Method Detail

      • getServletInfo

        public String getServletInfo()
        Specified by:
        getServletInfo in interface javax.servlet.Servlet
        Overrides:
        getServletInfo in class javax.servlet.GenericServlet
      • init

        public void init​(javax.servlet.ServletConfig servletConfig)
                  throws javax.servlet.ServletException
        Specified by:
        init in interface javax.servlet.Servlet
        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
      • service

        protected void service​(javax.servlet.http.HttpServletRequest servletRequest,
                               javax.servlet.http.HttpServletResponse servletResponse)
                        throws javax.servlet.ServletException,
                               IOException
        Overrides:
        service in class javax.servlet.http.HttpServlet
        Throws:
        javax.servlet.ServletException
        IOException
      • parseProxyAddress

        protected ProxyAddress parseProxyAddress​(javax.servlet.http.HttpServletRequest servletRequest)
      • doResponseRedirectOrNotModifiedLogic

        protected boolean doResponseRedirectOrNotModifiedLogic​(javax.servlet.http.HttpServletRequest servletRequest,
                                                               javax.servlet.http.HttpServletResponse servletResponse,
                                                               org.apache.http.HttpResponse proxyResponse,
                                                               int statusCode,
                                                               URI targetUriObj)
                                                        throws javax.servlet.ServletException,
                                                               IOException
        Throws:
        javax.servlet.ServletException
        IOException
      • copyRequestHeaders

        protected void copyRequestHeaders​(javax.servlet.http.HttpServletRequest servletRequest,
                                          org.apache.http.HttpRequest proxyRequest,
                                          URI targetUriObj)
        Copy request headers from the servlet client to the proxy request.
      • copyResponseHeaders

        protected void copyResponseHeaders​(org.apache.http.HttpResponse proxyResponse,
                                           javax.servlet.http.HttpServletResponse servletResponse)
        Copy proxied response headers back to the servlet client.
      • copyResponseEntity

        protected void copyResponseEntity​(org.apache.http.HttpResponse proxyResponse,
                                          javax.servlet.http.HttpServletResponse servletResponse)
                                   throws IOException
        Copy response body data (the entity) from the proxy to the servlet client.
        Throws:
        IOException
      • rewriteUrlFromResponse

        protected String rewriteUrlFromResponse​(javax.servlet.http.HttpServletRequest servletRequest,
                                                String theUrl,
                                                String targetUri)
        For a redirect response from the target server, this translates theUrl to redirect to and translates it to one the original client can use.
      • encodeUriQuery

        protected static CharSequence encodeUriQuery​(CharSequence in)
        Encodes characters in the query or fragment part of the URI.

        Unfortunately, an incoming URI sometimes has characters disallowed by the spec. HttpClient insists that the outgoing proxied request has a valid URI because it uses Java's URI. To be more forgiving, we must escape the problematic characters. See the URI class for the spec.

        Parameters:
        in - example: name=value&foo=bar#fragment