在使用smiley-http-proxy-servlet实现反向代理时,发现在进行转发时原始request中的cookie信息丢失了。翻看了其源代码后发现在ProxyServlet进行http转发时是有copy原始request中的header(包括cookie)的操作的,如下:
/** Copy request headers from the servlet client to the proxy request. */
protected void copyRequestHeaders(HttpServletRequest servletRequest, HttpRequest proxyRequest) {
// Get an Enumeration of all of the header names sent by the client
Enumeration enumerationOfHeaderNames = servletRequest.getHeaderNames();
while (enumerationOfHeaderNames.hasMoreElements()) {
String headerName = (String) enumerationOfHeaderNames.nextElement();
//Instead the content-length is effectively set via InputStreamEntity
if (headerName.equalsIgnoreCase(HttpHeaders.CONTENT_LENGTH))
continue;
if (hopByHopHeaders.containsHeader(headerName))
continue;
Enumeration headers = servletRequest.getHeaders(headerName);
while (headers.hasMoreElements()) {//sometimes more than one value
String headerValue = (String) headers.nextElement();
// In case the proxy host is running multiple virtual servers,
// rewrite the Host header to ensure that we get content from
// the correct virtual server
if (headerName.equalsIgnoreCase(HttpHeaders.HOST)) {
HttpHost host = getTargetHost(servletRequest);
headerValue = host.getHostName();
if (host.getPort() != -1)
headerValue += ":"+host.getPort();
// 就是下面这句copy了cookie
} else if (headerName.equalsIgnoreCase(org.apache.http.cookie.SM.COOKIE)) {
headerValue = getRealCookie(headerValue);
}
proxyRequest.addHeader(headerName, headerValue);
}
}
}
但是在进行copy时做了限定——只copy name为特定前缀的cookie,该方法代码如下:
/** The string prefixing rewritten cookies. */
protected String getCookieNamePrefix() {
return "!Proxy!" + getServletConfig().getServletName();
}
而原始的cookie均不是该前缀,因此出现了cookie丢失的问题。找到问题原因之后,要修改就容易了很多。要么将原始cookie name追加相应的前缀,要么实现一个URITemplateProxyServlet的子类,覆写getCookieNamePrefix方法即可。