Package org.mitre.dsmiley.httpproxy
Class ProxyServlet
- java.lang.Object
-
- javax.servlet.GenericServlet
-
- javax.servlet.http.HttpServlet
-
- org.mitre.dsmiley.httpproxy.ProxyServlet
-
- All Implemented Interfaces:
Serializable,javax.servlet.Servlet,javax.servlet.ServletConfig
- Direct Known Subclasses:
URITemplateProxyServlet
public class ProxyServlet extends javax.servlet.http.HttpServletAn 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
- Author:
- David Smiley dsmiley@apache.org
- See Also:
- Serialized Form
-
-
Field Summary
Fields Modifier and Type Field Description protected static BitSetasciiQueryCharsprotected static StringATTR_TARGET_HOSTprotected static StringATTR_TARGET_URIprotected intconnectionRequestTimeoutprotected intconnectTimeoutprotected booleandoForwardIPprotected booleandoHandleCompressionprotected booleandoHandleRedirectsprotected booleandoLogprotected booleandoPreserveCookiesprotected booleandoPreserveHostprotected booleandoSendUrlFragmentUser agents shouldn't send the url fragment but what if it does?protected static org.apache.http.message.HeaderGrouphopByHopHeadersThese are the "hop-by-hop" headers that should not be copied.protected intmaxConnectionsstatic StringP_CONNECTIONREQUESTTIMEOUTAn integer parameter name to set the connection request timeout (millis)static StringP_CONNECTTIMEOUTAn integer parameter name to set the socket connection timeout (millis)static StringP_FORWARDEDFORA boolean parameter name to enable forwarding of the client IPstatic StringP_HANDLECOMPRESSIONA boolean parameter to enable handling of compression in the servlet.static StringP_HANDLEREDIRECTSA boolean parameter name to have auto-handle redirectsstatic StringP_LOGA boolean parameter name to enable logging of input and target URLs to the servlet log.static StringP_MAXCONNECTIONSAn integer parameter name to set max connection numberstatic StringP_PRESERVECOOKIESA boolean parameter name to keep COOKIES as-isstatic StringP_PRESERVEHOSTA boolean parameter name to keep HOST parameter as-isstatic StringP_READTIMEOUTAn integer parameter name to set the socket read timeout (millis)static StringP_TARGET_URIThe parameter name for the target (destination) URI to proxy to.static StringP_USESYSTEMPROPERTIESA boolean parameter whether to use JVM-defined system properties to configure various networking aspects.protected intreadTimeoutprotected org.apache.http.HttpHosttargetHostprotected StringtargetUriFrom the configured parameter "targetUri".protected URItargetUriObjprotected booleanuseSystemProperties
-
Constructor Summary
Constructors Constructor Description ProxyServlet()
-
Method Summary
All Methods Instance Methods Concrete Methods Modifier and Type Method Description protected org.apache.http.client.HttpClientbuildHttpClient(org.apache.http.impl.client.HttpClientBuilder clientBuilder)Creates a HttpClient from the given builder.protected StringbuildProxyCookiePath(javax.servlet.http.HttpServletRequest servletRequest)Create path for proxy cookie.protected org.apache.http.client.config.RequestConfigbuildRequestConfig()Sub-classes can override specific behaviour ofRequestConfig.protected org.apache.http.config.SocketConfigbuildSocketConfig()Sub-classes can override specific behaviour ofSocketConfig.protected voidcloseQuietly(Closeable closeable)protected voidcopyProxyCookie(javax.servlet.http.HttpServletRequest servletRequest, javax.servlet.http.HttpServletResponse servletResponse, String headerValue)Copy cookie from the proxy to the servlet client.protected voidcopyRequestHeader(javax.servlet.http.HttpServletRequest servletRequest, org.apache.http.HttpRequest proxyRequest, String headerName)Copy a request header from the servlet client to the proxy request.protected voidcopyRequestHeaders(javax.servlet.http.HttpServletRequest servletRequest, org.apache.http.HttpRequest proxyRequest)Copy request headers from the servlet client to the proxy request.protected voidcopyResponseEntity(org.apache.http.HttpResponse proxyResponse, javax.servlet.http.HttpServletResponse servletResponse, org.apache.http.HttpRequest proxyRequest, javax.servlet.http.HttpServletRequest servletRequest)Copy response body data (the entity) from the proxy to the servlet client.protected voidcopyResponseHeader(javax.servlet.http.HttpServletRequest servletRequest, javax.servlet.http.HttpServletResponse servletResponse, org.apache.http.Header header)Copy a proxied response header back to the servlet client.protected voidcopyResponseHeaders(org.apache.http.HttpResponse proxyResponse, javax.servlet.http.HttpServletRequest servletRequest, javax.servlet.http.HttpServletResponse servletResponse)Copy proxied response headers back to the servlet client.protected org.apache.http.client.HttpClientcreateHttpClient()Called fromGenericServlet.init(javax.servlet.ServletConfig).protected javax.servlet.http.CookiecreateProxyCookie(javax.servlet.http.HttpServletRequest servletRequest, HttpCookie cookie)Creates a proxy cookie from the original cookie.voiddestroy()protected org.apache.http.HttpResponsedoExecute(javax.servlet.http.HttpServletRequest servletRequest, javax.servlet.http.HttpServletResponse servletResponse, org.apache.http.HttpRequest proxyRequest)protected CharSequenceencodeUriQuery(CharSequence in, boolean encodePercent)Encodes characters in the query or fragment part of the URI.protected StringgetConfigParam(String key)Reads a configuration parameter.protected StringgetCookieNamePrefix(String name)The string prefixing rewritten cookies.protected org.apache.http.impl.client.HttpClientBuildergetHttpClientBuilder()Creates aHttpClientBuilder.protected org.apache.http.client.HttpClientgetProxyClient()The http client used.protected StringgetProxyCookieName(HttpCookie cookie)Set cookie name prefixed with a proxy value so it won't collide with other cookies.protected StringgetRealCookie(String cookieValue)Take any client cookies that were originally from the proxy and prepare them to send to the proxy.StringgetServletInfo()protected org.apache.http.HttpHostgetTargetHost(javax.servlet.http.HttpServletRequest servletRequest)StringgetTargetUri()The target URI as configured.protected StringgetTargetUri(javax.servlet.http.HttpServletRequest servletRequest)protected voidhandleRequestException(org.apache.http.HttpRequest proxyRequest, org.apache.http.HttpResponse proxyResonse, Exception e)voidinit()protected voidinitTarget()protected org.apache.http.HttpRequestnewProxyRequestWithEntity(String method, String proxyRequestUri, javax.servlet.http.HttpServletRequest servletRequest)protected StringrewritePathInfoFromRequest(javax.servlet.http.HttpServletRequest servletRequest)Allow overrides ofHttpServletRequest.getPathInfo().protected StringrewriteQueryStringFromRequest(javax.servlet.http.HttpServletRequest servletRequest, String queryString)protected StringrewriteUrlFromRequest(javax.servlet.http.HttpServletRequest servletRequest)Reads the request URI fromservletRequestand rewrites it, considering targetUri.protected StringrewriteUrlFromResponse(javax.servlet.http.HttpServletRequest servletRequest, String theUrl)For a redirect response from the target server, this translatestheUrlto redirect to and translates it to one the original client can use.protected voidservice(javax.servlet.http.HttpServletRequest servletRequest, javax.servlet.http.HttpServletResponse servletResponse)-
Methods inherited from class javax.servlet.http.HttpServlet
doDelete, doGet, doHead, doOptions, doPost, doPut, doTrace, getLastModified, service
-
-
-
-
Field Detail
-
P_LOG
public static final String P_LOG
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
-
P_PRESERVEHOST
public static final String P_PRESERVEHOST
A boolean parameter name to keep HOST parameter as-is- See Also:
- Constant Field Values
-
P_PRESERVECOOKIES
public static final String P_PRESERVECOOKIES
A boolean parameter name to keep COOKIES as-is- See Also:
- Constant Field Values
-
P_HANDLEREDIRECTS
public static final String P_HANDLEREDIRECTS
A boolean parameter name to have auto-handle redirects- See Also:
- Constant Field Values
-
P_CONNECTTIMEOUT
public static final String P_CONNECTTIMEOUT
An integer parameter name to set the socket connection timeout (millis)- See Also:
- Constant Field Values
-
P_READTIMEOUT
public static final String P_READTIMEOUT
An integer parameter name to set the socket read timeout (millis)- See Also:
- Constant Field Values
-
P_CONNECTIONREQUESTTIMEOUT
public static final String P_CONNECTIONREQUESTTIMEOUT
An integer parameter name to set the connection request timeout (millis)- See Also:
- Constant Field Values
-
P_MAXCONNECTIONS
public static final String P_MAXCONNECTIONS
An integer parameter name to set max connection number- See Also:
- Constant Field Values
-
P_USESYSTEMPROPERTIES
public static final String P_USESYSTEMPROPERTIES
A boolean parameter whether to use JVM-defined system properties to configure various networking aspects.- See Also:
- Constant Field Values
-
P_HANDLECOMPRESSION
public static final String P_HANDLECOMPRESSION
A boolean parameter to enable handling of compression in the servlet. If it is false, compressed streams are passed through unmodified.- See Also:
- Constant Field Values
-
P_TARGET_URI
public static final String P_TARGET_URI
The parameter name for the target (destination) URI to proxy to.- See Also:
- Constant Field Values
-
ATTR_TARGET_URI
protected static final String ATTR_TARGET_URI
-
ATTR_TARGET_HOST
protected static final String ATTR_TARGET_HOST
-
doLog
protected boolean doLog
-
doForwardIP
protected boolean doForwardIP
-
doSendUrlFragment
protected boolean doSendUrlFragment
User agents shouldn't send the url fragment but what if it does?
-
doPreserveHost
protected boolean doPreserveHost
-
doPreserveCookies
protected boolean doPreserveCookies
-
doHandleRedirects
protected boolean doHandleRedirects
-
useSystemProperties
protected boolean useSystemProperties
-
doHandleCompression
protected boolean doHandleCompression
-
connectTimeout
protected int connectTimeout
-
readTimeout
protected int readTimeout
-
connectionRequestTimeout
protected int connectionRequestTimeout
-
maxConnections
protected int maxConnections
-
targetUri
protected String targetUri
From the configured parameter "targetUri".
-
targetUriObj
protected URI targetUriObj
-
targetHost
protected org.apache.http.HttpHost targetHost
-
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<String> because this approach does case insensitive lookup faster.
-
asciiQueryChars
protected static final BitSet asciiQueryChars
-
-
Method Detail
-
getServletInfo
public String getServletInfo()
- Specified by:
getServletInfoin interfacejavax.servlet.Servlet- Overrides:
getServletInfoin classjavax.servlet.GenericServlet
-
getTargetUri
protected String getTargetUri(javax.servlet.http.HttpServletRequest servletRequest)
-
getTargetHost
protected org.apache.http.HttpHost getTargetHost(javax.servlet.http.HttpServletRequest servletRequest)
-
getConfigParam
protected String getConfigParam(String key)
Reads a configuration parameter. By default it reads servlet init parameters but it can be overridden.
-
init
public void init() throws javax.servlet.ServletException- Overrides:
initin classjavax.servlet.GenericServlet- Throws:
javax.servlet.ServletException
-
buildRequestConfig
protected org.apache.http.client.config.RequestConfig buildRequestConfig()
Sub-classes can override specific behaviour ofRequestConfig.
-
buildSocketConfig
protected org.apache.http.config.SocketConfig buildSocketConfig()
Sub-classes can override specific behaviour ofSocketConfig.
-
initTarget
protected void initTarget() throws javax.servlet.ServletException- Throws:
javax.servlet.ServletException
-
createHttpClient
protected org.apache.http.client.HttpClient createHttpClient()
Called fromGenericServlet.init(javax.servlet.ServletConfig). HttpClient offers many opportunities for customization. In any case, it should be thread-safe.
-
buildHttpClient
protected org.apache.http.client.HttpClient buildHttpClient(org.apache.http.impl.client.HttpClientBuilder clientBuilder)
Creates a HttpClient from the given builder. Meant as postprocessor to possibly adapt the client builder prior to creating the HttpClient.- Parameters:
clientBuilder- pre-configured client builder- Returns:
- HttpClient
-
getHttpClientBuilder
protected org.apache.http.impl.client.HttpClientBuilder getHttpClientBuilder()
Creates aHttpClientBuilder. Meant as preprocessor to possibly adapt the client builder prior to any configuration got applied.- Returns:
- HttpClient builder
-
getProxyClient
protected org.apache.http.client.HttpClient getProxyClient()
The http client used.- See Also:
createHttpClient()
-
destroy
public void destroy()
- Specified by:
destroyin interfacejavax.servlet.Servlet- Overrides:
destroyin classjavax.servlet.GenericServlet
-
service
protected void service(javax.servlet.http.HttpServletRequest servletRequest, javax.servlet.http.HttpServletResponse servletResponse) throws javax.servlet.ServletException, IOException- Overrides:
servicein classjavax.servlet.http.HttpServlet- Throws:
javax.servlet.ServletExceptionIOException
-
handleRequestException
protected void handleRequestException(org.apache.http.HttpRequest proxyRequest, org.apache.http.HttpResponse proxyResonse, Exception e) throws javax.servlet.ServletException, IOException- Throws:
javax.servlet.ServletExceptionIOException
-
doExecute
protected org.apache.http.HttpResponse doExecute(javax.servlet.http.HttpServletRequest servletRequest, javax.servlet.http.HttpServletResponse servletResponse, org.apache.http.HttpRequest proxyRequest) throws IOException- Throws:
IOException
-
newProxyRequestWithEntity
protected org.apache.http.HttpRequest newProxyRequestWithEntity(String method, String proxyRequestUri, javax.servlet.http.HttpServletRequest servletRequest) throws IOException
- Throws:
IOException
-
closeQuietly
protected void closeQuietly(Closeable closeable)
-
copyRequestHeaders
protected void copyRequestHeaders(javax.servlet.http.HttpServletRequest servletRequest, org.apache.http.HttpRequest proxyRequest)Copy request headers from the servlet client to the proxy request. This is easily overridden to add your own.
-
copyRequestHeader
protected void copyRequestHeader(javax.servlet.http.HttpServletRequest servletRequest, org.apache.http.HttpRequest proxyRequest, String headerName)Copy a request header from the servlet client to the proxy request. This is easily overridden to filter out certain headers if desired.
-
copyResponseHeaders
protected void copyResponseHeaders(org.apache.http.HttpResponse proxyResponse, javax.servlet.http.HttpServletRequest servletRequest, javax.servlet.http.HttpServletResponse servletResponse)Copy proxied response headers back to the servlet client.
-
copyResponseHeader
protected void copyResponseHeader(javax.servlet.http.HttpServletRequest servletRequest, javax.servlet.http.HttpServletResponse servletResponse, org.apache.http.Header header)Copy a proxied response header back to the servlet client. This is easily overwritten to filter out certain headers if desired.
-
copyProxyCookie
protected void copyProxyCookie(javax.servlet.http.HttpServletRequest servletRequest, javax.servlet.http.HttpServletResponse servletResponse, String headerValue)Copy cookie from the proxy to the servlet client. Replaces cookie path to local path and renames cookie to avoid collisions.
-
createProxyCookie
protected javax.servlet.http.Cookie createProxyCookie(javax.servlet.http.HttpServletRequest servletRequest, HttpCookie cookie)Creates a proxy cookie from the original cookie.- Parameters:
servletRequest- original requestcookie- original cookie- Returns:
- proxy cookie
-
getProxyCookieName
protected String getProxyCookieName(HttpCookie cookie)
Set cookie name prefixed with a proxy value so it won't collide with other cookies.- Parameters:
cookie- cookie to get proxy cookie name for- Returns:
- non-conflicting proxy cookie name
-
buildProxyCookiePath
protected String buildProxyCookiePath(javax.servlet.http.HttpServletRequest servletRequest)
Create path for proxy cookie.- Parameters:
servletRequest- original request- Returns:
- proxy cookie path
-
getRealCookie
protected String getRealCookie(String cookieValue)
Take any client cookies that were originally from the proxy and prepare them to send to the proxy. This relies on cookie headers being set correctly according to RFC 6265 Sec 5.4. This also blocks any local cookies from being sent to the proxy.
-
getCookieNamePrefix
protected String getCookieNamePrefix(String name)
The string prefixing rewritten cookies.
-
copyResponseEntity
protected void copyResponseEntity(org.apache.http.HttpResponse proxyResponse, javax.servlet.http.HttpServletResponse servletResponse, org.apache.http.HttpRequest proxyRequest, javax.servlet.http.HttpServletRequest servletRequest) throws IOExceptionCopy response body data (the entity) from the proxy to the servlet client.- Throws:
IOException
-
rewriteUrlFromRequest
protected String rewriteUrlFromRequest(javax.servlet.http.HttpServletRequest servletRequest)
Reads the request URI fromservletRequestand rewrites it, considering targetUri. It's used to make the new request.
-
rewriteQueryStringFromRequest
protected String rewriteQueryStringFromRequest(javax.servlet.http.HttpServletRequest servletRequest, String queryString)
-
rewritePathInfoFromRequest
protected String rewritePathInfoFromRequest(javax.servlet.http.HttpServletRequest servletRequest)
Allow overrides ofHttpServletRequest.getPathInfo(). Useful when url-pattern of servlet-mapping (web.xml) requires manipulation.
-
rewriteUrlFromResponse
protected String rewriteUrlFromResponse(javax.servlet.http.HttpServletRequest servletRequest, String theUrl)
For a redirect response from the target server, this translatestheUrlto redirect to and translates it to one the original client can use.
-
getTargetUri
public String getTargetUri()
The target URI as configured. Not null.
-
encodeUriQuery
protected CharSequence encodeUriQuery(CharSequence in, boolean encodePercent)
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#fragmentencodePercent- determine whether percent characters need to be encoded
-
-