// ========================================================================
// $Id: ServletHttpRequest.java,v 1.65 2005/08/13 00:01:27 gregwilkins Exp $
// Copyright 200-2004 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
// http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
// ========================================================================
package net.lightbody.bmp.proxy.jetty.jetty.servlet;
import net.lightbody.bmp.proxy.jetty.http.*;
import net.lightbody.bmp.proxy.jetty.log.LogFactory;
import net.lightbody.bmp.proxy.jetty.util.*;
import org.apache.commons.logging.Log;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletInputStream;
import javax.servlet.ServletRequest;
import javax.servlet.ServletRequestWrapper;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;
import java.io.BufferedReader;
import java.io.File;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.security.Principal;
import java.util.*;
/* ------------------------------------------------------------ */
/** Servlet Request Wrapper.
* This class wraps a Jetty HTTP request as a 2.2 Servlet
* request.
* <P>
* Note that this wrapper is not synchronized and if a request is to
* be operated on by multiple threads, then higher level
* synchronizations may be required.
*
* @version $Id: ServletHttpRequest.java,v 1.65 2005/08/13 00:01:27 gregwilkins Exp $
* @author Greg Wilkins (gregw)
*/
public class ServletHttpRequest
implements HttpServletRequest
{
private static Log log = LogFactory.getLog(ServletHttpRequest.class);
/* -------------------------------------------------------------- */
public static final String
__SESSIONID_NOT_CHECKED = "not checked",
__SESSIONID_URL = "url",
__SESSIONID_COOKIE = "cookie",
__SESSIONID_NONE = "none";
private static final Enumeration __emptyEnum =
Collections.enumeration(Collections.EMPTY_LIST);
private static final Collection __defaultLocale =
Collections.singleton(Locale.getDefault());
private ServletHandler _servletHandler;
private HttpRequest _httpRequest;
private ServletHttpResponse _servletHttpResponse;
private String _contextPath=null;
private String _servletPath=null;
private String _pathInfo=null;
private String _query=null;
private String _pathTranslated=null;
private String _requestedSessionId=null;
private HttpSession _session=null;
private String _sessionIdState=__SESSIONID_NOT_CHECKED;
private ServletIn _in =null;
private BufferedReader _reader=null;
private int _inputState=0;
private ServletHolder _servletHolder;
private String _pathInContext;
/* ------------------------------------------------------------ */
/** Constructor.
*/
public ServletHttpRequest(ServletHandler servletHandler,
String pathInContext,
HttpRequest request)
{
_servletHandler=servletHandler;
_pathInContext=pathInContext;
_contextPath=_servletHandler.getHttpContext().getContextPath();
if (_contextPath.length()<=1)
_contextPath="";
_httpRequest=request;
}
/* ------------------------------------------------------------ */
void recycle(ServletHandler servletHandler,String pathInContext)
{
_servletHandler=servletHandler;
_pathInContext=pathInContext;
_servletPath=null;
_pathInfo=null;
_query=null;
_pathTranslated=null;
_requestedSessionId=null;
_session=null;
_sessionIdState=__SESSIONID_NOT_CHECKED;
_in=null;
_reader=null;
_inputState=0;
_servletHolder=null;
if (servletHandler!=null)
_contextPath=_servletHandler.getHttpContext().getContextPath();
if (_contextPath!=null&&_contextPath.length()<=1)
_contextPath="";
}
/* ------------------------------------------------------------ */
ServletHandler getServletHandler()
{
return _servletHandler;
}
/* ------------------------------------------------------------ */
void setServletHandler(ServletHandler servletHandler)
{
_servletHandler=servletHandler;
}
/* ------------------------------------------------------------ */
/** Set servletpath and pathInfo.
* Called by the Handler before passing a request to a particular
* holder to split the context path into a servlet path and path info.
* @param servletPath
* @param pathInfo
*/
void setServletPaths(String servletPath,
String pathInfo,
ServletHolder holder)
{
_servletPath=servletPath;
_pathInfo=pathInfo;
_servletHolder=holder;
}
/* ------------------------------------------------------------ */
ServletHolder getServletHolder()
{
return _servletHolder;
}
/* ------------------------------------------------------------ */
String getPathInContext()
{
return _pathInContext;
}
/* ------------------------------------------------------------ */
HttpRequest getHttpRequest()
{
return _httpRequest;
}
/* ------------------------------------------------------------ */
public ServletHttpResponse getServletHttpResponse()
{
return _servletHttpResponse;
}
/* ------------------------------------------------------------ */
void setServletHttpResponse(ServletHttpResponse response)
{
_servletHttpResponse = response;
}
/* ------------------------------------------------------------ */
public Locale getLocale()
{
Enumeration enm = _httpRequest.getFieldValues(HttpFields.__AcceptLanguage,
HttpFields.__separators);
// handle no locale
if (enm == null || !enm.hasMoreElements())
return Locale.getDefault();
// sort the list in quality order
List acceptLanguage = HttpFields.qualityList(enm);
if (acceptLanguage.size()==0)
return Locale.getDefault();
int size=acceptLanguage.size();
// convert to locals
for (int i=0; i<size; i++)
{
String language = (String)acceptLanguage.get(i);
language=HttpFields.valueParameters(language,null);
String country = "";
int dash = language.indexOf('-');
if (dash > -1)
{
country = language.substring(dash + 1).trim();
language = language.substring(0,dash).trim();
}
return new Locale(language,country);
}
return Locale.getDefault();
}
/* ------------------------------------------------------------ */
public Enumeration getLocales()
{
Enumeration enm = _httpRequest.getFieldValues(HttpFields.__AcceptLanguage,
HttpFields.__separators);
// handle no locale
if (enm == null || !enm.hasMoreElements())
return Collections.enumeration(__defaultLocale);
// sort the list in quality order
List acceptLanguage = HttpFields.qualityList(enm);
if (acceptLanguage.size()==0)
return
Collections.enumeration(__defaultLocale);
Object langs = null;
int size=acceptLanguage.size();
// convert to locals
for (int i=0; i<size; i++)
{
String language = (String)acceptLanguage.get(i);
language=HttpFields.valueParameters(language,null);
String country = "";
int dash = language.indexOf('-');
if (dash > -1)
{
country = language.substring(dash + 1).trim();
language = language.substring(0,dash).trim();
}
langs=LazyList.ensureSize(langs,size);
langs=LazyList.add(langs,new Locale(language,country));
}
if (LazyList.size(langs)==0)
return Collections.enumeration(__defaultLocale);
return Collections.enumeration(LazyList.getList(langs));
}
/* ------------------------------------------------------------ */
public boolean isSecure()
{
return _httpRequest.isConfidential();
}
/* ------------------------------------------------------------ */
public Cookie[] getCookies()
{
Cookie[] cookies = _httpRequest.getCookies();
if (cookies.length==0)
return null;
return cookies;
}
/* ------------------------------------------------------------ */
public long getDateHeader(String name)
{
return _httpRequest.getDateField(name);
}
/* ------------------------------------------------------------ */
public Enumeration getHeaderNames()
{
return _httpRequest.getFieldNames();
}
/* ------------------------------------------------------------ */
public String getHeader(String name)
{
return _httpRequest.getField(name);
}
/* ------------------------------------------------------------ */
public Enumeration getHeaders(String s)
{
Enumeration enm=_httpRequest.getFieldValues(s);
if (enm==null)
return __emptyEnum;
return enm;
}
/* ------------------------------------------------------------ */
public int getIntHeader(String name)
throws NumberFormatException
{
return _httpRequest.getIntField(name);
}
/* ------------------------------------------------------------ */
public String getMethod()
{
return _httpRequest.getMethod();
}
/* ------------------------------------------------------------ */
public String getContextPath()
{
return _contextPath;
}
/* ------------------------------------------------------------ */
public String getPathInfo()
{
if (_servletPath==null)
return null;
return _pathInfo;
}
/* ------------------------------------------------------------ */
public String getPathTranslated()
{
if (_pathInfo==null || _pathInfo.length()==0)
return null;
if (_pathTranslated==null)
{
Resource resource =
_servletHandler.getHttpContext().getBaseResource();
if (resource==null)
return null;
try
{
resource=resource.addPath(_pathInfo);
File file = resource.getFile();
if (file==null)
return null;
_pathTranslated=file.getAbsolutePath();
}
catch(Exception e)
{
log.debug(LogSupport.EXCEPTION,e);
}
}
return _pathTranslated;
}
/* ------------------------------------------------------------ */
public String getQueryString()
{
if (_query==null)
_query =_httpRequest.getQuery();
return _query;
}
/* ------------------------------------------------------------ */
public String getAuthType()
{
String at= _httpRequest.getAuthType();
if (at==SecurityConstraint.__BASIC_AUTH)
return HttpServletRequest.BASIC_AUTH;
if (at==SecurityConstraint.__FORM_AUTH)
return HttpServletRequest.FORM_AUTH;
if (at==SecurityConstraint.__DIGEST_AUTH)
return HttpServletRequest.DIGEST_AUTH;
if (at==SecurityConstraint.__CERT_AUTH)
return HttpServletRequest.CLIENT_CERT_AUTH;
if (at==SecurityConstraint.__CERT_AUTH2)
return HttpServletRequest.CLIENT_CERT_AUTH;
return at;
}
/* ------------------------------------------------------------ */
public String getRemoteUser()
{
return _httpRequest.getAuthUser();
}
/* ------------------------------------------------------------ */
public boolean isUserInRole(String role)
{
if (_servletHolder!=null)
role=_servletHolder.getUserRoleLink(role);
return _httpRequest.isUserInRole(role);
}
/* ------------------------------------------------------------ */
public Principal getUserPrincipal()
{
return _httpRequest.getUserPrincipal();
}
/* ------------------------------------------------------------ */
void setRequestedSessionId(String pathParams)
{
_requestedSessionId=null;
// try cookies first
if (_servletHandler.isUsingCookies())
{
Cookie[] cookies=_httpRequest.getCookies();
if (cookies!=null && cookies.length>0)
{
for (int i=0;i<cookies.length;i++)
{
if (SessionManager.__SessionCookie.equalsIgnoreCase(cookies[i].getName()))
{
if (_requestedSessionId!=null)
{
// Multiple jsessionid cookies. Probably due to
// multiple paths and/or domains. Pick the first
// known session or the last defined cookie.
SessionManager manager = _servletHandler.getSessionManager();
if (manager!=null && manager.getHttpSession(_requestedSessionId)!=null)
break;
log.debug("multiple session cookies");
}
_requestedSessionId=cookies[i].getValue();
_sessionIdState = __SESSIONID_COOKIE;
if(log.isDebugEnabled())log.debug("Got Session "+_requestedSessionId+" from cookie");
}
}
}
}
// check if there is a url encoded session param.
if (pathParams!=null && pathParams.startsWith(SessionManager.__SessionURL))
{
String id =
pathParams.substring(SessionManager.__SessionURL.length()+1);
if(log.isDebugEnabled())log.debug("Got Session "+id+" from URL");
if (_requestedSessionId==null)
{
_requestedSessionId=id;
_sessionIdState = __SESSIONID_URL;
}
else if (!id.equals(_requestedSessionId))
log.debug("Mismatched session IDs");
}
if (_requestedSessionId == null)
_sessionIdState = __SESSIONID_NONE;
}
/* ------------------------------------------------------------ */
public String getRequestedSessionId()
{
return _requestedSessionId;
}
/* ------------------------------------------------------------ */
public String getRequestURI()
{
return _httpRequest.getEncodedPath();
}
/* ------------------------------------------------------------ */
public StringBuffer getRequestURL()
{
StringBuffer buf = _httpRequest.getRootURL();
buf.append(getRequestURI());
return buf;
}
/* ------------------------------------------------------------ */
public String getServletPath()
{
if (_servletPath==null)
return _pathInContext;
return _servletPath;
}
/* ------------------------------------------------------------ */
public HttpSession getSession(boolean create)
{
if (_session != null && ((SessionManager.Session)_session).isValid())
return _session;
_session=null;
String id = getRequestedSessionId();
if (id != null)
{
_session=_servletHandler.getHttpSession(id);
if (_session == null && !create)
return null;
}
if (_session == null && create)
{
_session=newSession();
}
return _session;
}
/* ------------------------------------------------------------ */
/* Create a new HttpSession.
* If cookies are being used a set cookie is added to the response.
*/
HttpSession newSession()
{
HttpSession session=_servletHandler.newHttpSession(this);
Cookie cookie=_servletHandler.getSessionManager().getSessionCookie(session,isSecure());
if (cookie!=null)
_servletHttpResponse.getHttpResponse().addSetCookie(cookie);
return session;
}
/* ------------------------------------------------------------ */
public HttpSession getSession()
{
HttpSession session = getSession(true);
return session;
}
/* ------------------------------------------------------------ */
public boolean isRequestedSessionIdValid()
{
return _requestedSessionId != null && getSession(false) != null;
}
/* -------------------------------------------------------------- */
public boolean isRequestedSessionIdFromCookie()
{
return _sessionIdState == __SESSIONID_COOKIE;
}
/* -------------------------------------------------------------- */
public boolean isRequestedSessionIdFromURL()
{
return _sessionIdState == __SESSIONID_URL;
}
/* -------------------------------------------------------------- */
/**
* @deprecated
*/
public boolean isRequestedSessionIdFromUrl()
{
return isRequestedSessionIdFromURL();
}
/* -------------------------------------------------------------- */
public Enumeration getAttributeNames()
{
return _httpRequest.getAttributeNames();
}
/* -------------------------------------------------------------- */
public Object getAttribute(String name)
{
return _httpRequest.getAttribute(name);
}
/* -------------------------------------------------------------- */
public void setAttribute(String name, Object value)
{
_httpRequest.setAttribute(name,value);
}
/* -------------------------------------------------------------- */
public void removeAttribute(String name)
{
_httpRequest.removeAttribute(name);
}
/* -------------------------------------------------------------- */
public void setCharacterEncoding(String encoding)
throws UnsupportedEncodingException
{
if (_inputState!=0)
throw new IllegalStateException("getReader() or getInputStream() called");
"".getBytes(encoding);
_httpRequest.setCharacterEncoding(encoding,false);
}
/* -------------------------------------------------------------- */
public String getCharacterEncoding()
{
return _httpRequest.getCharacterEncoding();
}
/* -------------------------------------------------------------- */
public int getContentLength()
{
return _httpRequest.getContentLength();
}
/* -------------------------------------------------------------- */
public String getContentType()
{
return _httpRequest.getContentType();
}
/* -------------------------------------------------------------- */
public ServletInputStream getInputStream()
{
if (_inputState!=0 && _inputState!=1)
throw new IllegalStateException();
if (_in==null)
_in = new ServletIn((HttpInputStream)_httpRequest.getInputStream());
_inputState=1;
_reader=null;
return _in;
}
/* -------------------------------------------------------------- */
/**
* This method is not recommended as it forces the generation of a
* non-optimal data structure.
*/
public Map getParameterMap()
{
return Collections.unmodifiableMap(_httpRequest.getParameterStringArrayMap());
}
/* -------------------------------------------------------------- */
public String getParameter(String name)
{
return _httpRequest.getParameter(name);
}
/* -------------------------------------------------------------- */
public Enumeration getParameterNames()
{
return Collections.enumeration(_httpRequest.getParameterNames());
}
/* -------------------------------------------------------------- */
public String[] getParameterValues(String name)
{
List v=_httpRequest.getParameterValues(name);
if (v==null)
return null;
String[]a=new String[v.size()];
return (String[])v.toArray(a);
}
/* -------------------------------------------------------------- */
public String getProtocol()
{
return _httpRequest.getVersion();
}
/* -------------------------------------------------------------- */
public String getScheme()
{
return _httpRequest.getScheme();
}
/* -------------------------------------------------------------- */
public String getServerName()
{
return _httpRequest.getHost();
}
/* -------------------------------------------------------------- */
public int getServerPort()
{
int port = _httpRequest.getPort();
if (port==0)
{
if (getScheme().equalsIgnoreCase("https"))
return 443;
return 80;
}
return port;
}
/* -------------------------------------------------------------- */
public int getRemotePort()
{
HttpConnection connection= _httpRequest.getHttpConnection();
if (connection!=null)
return connection.getRemotePort();
return 0;
}
/* -------------------------------------------------------------- */
public String getLocalName()
{
HttpConnection connection= _httpRequest.getHttpConnection();
if (connection!=null)
return connection.getServerName();
return null;
}
/* -------------------------------------------------------------- */
public String getLocalAddr()
{
HttpConnection connection= _httpRequest.getHttpConnection();
if (connection!=null)
return connection.getServerAddr();
return null;
}
/* -------------------------------------------------------------- */
public int getLocalPort()
{
HttpConnection connection= _httpRequest.getHttpConnection();
if (connection!=null)
return connection.getServerPort();
return 0;
}
/* -------------------------------------------------------------- */
public BufferedReader getReader()
throws UnsupportedEncodingException
{
if (_inputState!=0 && _inputState!=2)
throw new IllegalStateException();
if (_reader==null)
{
String encoding=getCharacterEncoding();
if (encoding==null)
encoding=StringUtil.__ISO_8859_1;
_reader=new BufferedReader(new InputStreamReader(getInputStream(),encoding));
}
_inputState=2;
return _reader;
}
/* -------------------------------------------------------------- */
public String getRemoteAddr()
{
return _httpRequest.getRemoteAddr();
}
/* -------------------------------------------------------------- */
public String getRemoteHost()
{
if (_httpRequest.getHttpConnection()==null)
return null;
return _httpRequest.getRemoteHost();
}
/* -------------------------------------------------------------- */
/**
* @deprecated As of Version 2.1 of the Java Servlet API,
* use {@link javax.servlet.ServletContext#getRealPath} instead.
*/
public String getRealPath(String path)
{
return _servletHandler.getServletContext().getRealPath(path);
}
/* ------------------------------------------------------------ */
public RequestDispatcher getRequestDispatcher(String url)
{
if (url == null)
return null;
if (!url.startsWith("/"))
{
String relTo=URI.addPaths(_servletPath,_pathInfo);
int slash=relTo.lastIndexOf("/");
if (slash>1)
relTo=relTo.substring(0,slash+1);
else
relTo="/";
url=URI.addPaths(relTo,url);
}
return _servletHandler.getServletContext().getRequestDispatcher(url);
}
/* ------------------------------------------------------------ */
public String toString()
{
return
getContextPath()+"+"+getServletPath()+"+"+getPathInfo()+"\n"+
_httpRequest.toString();
}
/* ------------------------------------------------------------ */
/** Unwrap a ServletRequest.
*
* @see javax.servlet.ServletRequestWrapper
* @see javax.servlet.http.HttpServletRequestWrapper
* @param request
* @return The core ServletHttpRequest which must be the
* underlying request object
*/
public static ServletHttpRequest unwrap(ServletRequest request)
{
while (!(request instanceof ServletHttpRequest))
{
if (request instanceof ServletRequestWrapper)
{
ServletRequestWrapper wrapper =
(ServletRequestWrapper)request;
request=wrapper.getRequest();
}
else
throw new IllegalArgumentException("Does not wrap ServletHttpRequest");
}
return (ServletHttpRequest)request;
}
}