/* * Copyright (c) 1998-2011 Caucho Technology -- all rights reserved * * This file is part of Resin(R) Open Source * * Each copy or derived work must preserve the copyright notice and this * notice unmodified. * * Resin Open Source is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * Resin Open Source is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty * of NON-INFRINGEMENT. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License * along with Resin Open Source; if not, write to the * Free SoftwareFoundation, Inc. * 59 Temple Place, Suite 330 * Boston, MA 02111-1307 USA * * @author Scott Ferguson */ package com.caucho.server.http; import com.caucho.network.listen.SocketLink; import com.caucho.server.session.SessionManager; import com.caucho.server.webapp.WebApp; import com.caucho.util.FreeList; import com.caucho.util.L10N; import com.caucho.vfs.ReadStream; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletRequestWrapper; import javax.servlet.http.Cookie; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import javax.servlet.http.HttpSession; import javax.servlet.http.Part; import java.io.IOException; import java.util.Collection; import java.util.HashMap; /** * Any requests that depends on an underlying request, like * include() requests or adapters for other servlet engines. */ public class RequestAdapter extends RequestWrapper implements CauchoRequest { private static final L10N L = new L10N(RequestAdapter.class); static final int MAX_DEPTH = 64; public static String JSP_EXCEPTION = "javax.servlet.jsp.jspException"; public static String SHUTDOWN = "com.caucho.shutdown"; private static final FreeList<RequestAdapter> _freeList = new FreeList<RequestAdapter>(16); // for real adapters private WebApp _webApp; private HttpServletResponse _response; private HashMap<String,String> _roleMap; protected RequestAdapter() { } protected RequestAdapter(HttpServletRequest request, WebApp app) { super(request); _webApp = app; } /** * Creates a new RequestAdapter. */ public static RequestAdapter create(HttpServletRequest request, WebApp app) { RequestAdapter reqAdapt = _freeList.allocate(); if (reqAdapt == null) return new RequestAdapter(request, app); else { reqAdapt.setRequest(request); reqAdapt._webApp = app; return reqAdapt; } } /** * Creates a new RequestAdapter. */ public static RequestAdapter create() { RequestAdapter reqAdapt = _freeList.allocate(); if (reqAdapt != null) return reqAdapt; else return new RequestAdapter(); } public void init(HttpServletRequest request, HttpServletResponse response, WebApp app) throws ServletException { setRequest(request); _response = response; _webApp = app; if (request == this || (request instanceof CauchoRequest && ((CauchoRequest) request).getRequestDepth(0) > MAX_DEPTH)) { throw new ServletException(L.l("too many servlet includes `{0}'", request.getRequestURI())); } } public boolean isTop() { return false; } public void setWebApp(WebApp app) { _webApp = app; } public AbstractHttpRequest getAbstractHttpRequest() { HttpServletRequest request = getRequest(); if (request instanceof CauchoRequest) return ((CauchoRequest) request).getAbstractHttpRequest(); else return null; } protected HttpServletResponse getResponse() { return _response; } public void setResponse(CauchoResponse response) { _response = response; } /** * Returns the underlying read stream. */ public ReadStream getStream() throws IOException { if (getRequest() instanceof CauchoRequest) return ((CauchoRequest) getRequest()).getStream(); else return null; } /** * Returns the URI for the current page: included or top-level. */ public String getPageURI() { String uri = (String) getAttribute(RequestDispatcher.INCLUDE_REQUEST_URI); if (uri != null) return uri; else return getRequestURI(); } public static String getPageURI(HttpServletRequest request) { String uri = (String) request.getAttribute(RequestDispatcher.INCLUDE_REQUEST_URI); if (uri != null) return uri; else return request.getRequestURI(); } public String getPageContextPath() { String contextPath = (String) getAttribute(RequestDispatcher.INCLUDE_CONTEXT_PATH); if (contextPath != null) return contextPath; else return getContextPath(); } public static String getPageContextPath(HttpServletRequest request) { String contextPath = (String) request.getAttribute(RequestDispatcher.INCLUDE_CONTEXT_PATH); if (contextPath != null) return contextPath; else return request.getContextPath(); } /** * Returns the servlet-path for the current page, i.e. this will return the * url of the include page, not the original request. */ public String getPageServletPath() { String servletPath = (String) getAttribute(RequestDispatcher.INCLUDE_SERVLET_PATH); if (servletPath != null) return servletPath; else return getServletPath(); } /** * Returns the servlet-path for the current page, i.e. this will return the * url of the include page, not the original request. */ public static String getPageServletPath(HttpServletRequest request) { String servletPath = (String) request.getAttribute(RequestDispatcher.INCLUDE_SERVLET_PATH); if (servletPath != null) return servletPath; else return request.getServletPath(); } /** * Returns the path-info for the current page, i.e. this will return the * url of the include page, not the original request. */ public String getPagePathInfo() { String uri = (String) getAttribute(RequestDispatcher.INCLUDE_REQUEST_URI); if (uri != null) return (String) getAttribute(RequestDispatcher.INCLUDE_PATH_INFO); else return getPathInfo(); } /** * Returns the path-info for the current page, i.e. this will return the * url of the include page, not the original request. */ public static String getPagePathInfo(HttpServletRequest request) { String uri = (String) request.getAttribute(RequestDispatcher.INCLUDE_REQUEST_URI); if (uri != null) return (String) request.getAttribute(RequestDispatcher.INCLUDE_PATH_INFO); else return request.getPathInfo(); } /** * Returns the query-string for the current page, i.e. this will return the * url of the include page, not the original request. */ public String getPageQueryString() { String uri = (String) getAttribute(RequestDispatcher.INCLUDE_REQUEST_URI); if (uri != null) return (String) getAttribute(RequestDispatcher.INCLUDE_QUERY_STRING); else return getQueryString(); } /** * Returns the query-string for the current page, i.e. this will return the * url of the include page, not the original request. */ public static String getPageQueryString(HttpServletRequest request) { String uri = (String) request.getAttribute(RequestDispatcher.INCLUDE_REQUEST_URI); if (uri != null) return (String) request.getAttribute(RequestDispatcher.INCLUDE_QUERY_STRING); else return request.getQueryString(); } public int getRequestDepth(int depth) { if (depth > MAX_DEPTH) throw new RuntimeException(L.l("too many request dispatchers")); ServletRequest req = getRequest(); while (req != null) { if (req instanceof CauchoRequest) return ((CauchoRequest) req).getRequestDepth(depth + 1); else if (req instanceof ServletRequestWrapper) { ServletRequestWrapper reqWrap = (ServletRequestWrapper) req; req = reqWrap.getRequest(); } else break; } return depth + 2; } public void setHeader(String key, String value) { } public void setSyntheticCacheHeader(boolean isSynthetic) { } public boolean isSyntheticCacheHeader() { return false; } public WebApp getWebApp() { return _webApp; } public void setVaryCookie(String cookie) { // super.setVaryCookie(cookie); if (getRequest() instanceof CauchoRequest) ((CauchoRequest) getRequest()).setVaryCookie(cookie); } public boolean getVaryCookies() { // super.setVaryCookie(cookie); if (getRequest() instanceof CauchoRequest) return ((CauchoRequest) getRequest()).getVaryCookies(); else return false; } public void setHasCookie() { // super.setHasCookie(); if (getRequest() instanceof CauchoRequest) ((CauchoRequest) getRequest()).setHasCookie(); } public boolean getHasCookie() { // super.setHasCookie(); if (getRequest() instanceof CauchoRequest) return ((CauchoRequest) getRequest()).getHasCookie(); else return false; } public HttpSession getMemorySession() { return getSession(false); } public HttpSession getSession(boolean create) { SessionManager manager = getSessionManager(); setVaryCookie(getCookieName(manager)); HttpSession session = super.getSession(create); if (session != null) setHasCookie(); return session; } public String getRequestedSessionId() { SessionManager manager = getSessionManager(); setVaryCookie(getCookieName(manager)); String id = super.getRequestedSessionId(); if (id != null) setHasCookie(); return id; } public boolean isRequestedSessionIdValid() { SessionManager manager = getSessionManager(); setVaryCookie(getCookieName(manager)); boolean isValid = super.isRequestedSessionIdValid(); if (isValid) setHasCookie(); return isValid; } public boolean isRequestedSessionIdFromCookie() { SessionManager manager = getSessionManager(); setVaryCookie(getCookieName(manager)); boolean isValid = super.isRequestedSessionIdFromCookie(); if (isValid) setHasCookie(); return isValid; } public boolean isRequestedSessionIdFromURL() { SessionManager manager = getSessionManager(); setVaryCookie(getCookieName(manager)); boolean isValid = super.isRequestedSessionIdFromURL(); if (isValid) setHasCookie(); return isValid; } public boolean isSessionIdFromCookie() { CauchoRequest cReq = getCauchoRequest(); if (cReq != null) return cReq.isSessionIdFromCookie(); else return isRequestedSessionIdFromCookie(); } public String getSessionId() { CauchoRequest cReq = getCauchoRequest(); if (cReq != null) return cReq.getSessionId(); else return getRequestedSessionId(); } public void setSessionId(String sessionId) { CauchoRequest cReq = getCauchoRequest(); if (cReq != null) cReq.setSessionId(sessionId); } protected final SessionManager getSessionManager() { WebApp app = getWebApp(); if (app != null) return app.getSessionManager(); else return null; } protected final String getCookieName(SessionManager manager) { if (isSecure()) return manager.getCookieName(); else return manager.getSSLCookieName(); } public Cookie []getCookies() { // page depends on any cookie setVaryCookie(null); Cookie []cookies = super.getCookies(); if (cookies != null && cookies.length > 0) setHasCookie(); return cookies; } public Cookie getCookie(String name) { // page depends on this cookie setVaryCookie(name); if (getRequest() instanceof CauchoRequest) return ((CauchoRequest) getRequest()).getCookie(name); Cookie []cookies = super.getCookies(); for (int i = 0; i < cookies.length; i++) { if (cookies[i].getName().equals(name)) { setHasCookie(); return cookies[i]; } } return null; } public boolean isComet() { return false; } public boolean isDuplex() { return false; } @Override public void killKeepalive(String reason) { } @Override public SocketLink getSocketLink() { if (getRequest() instanceof CauchoRequest) return ((CauchoRequest) getRequest()).getSocketLink(); else return null; } public boolean isConnectionClosed() { return false; } public void clientDisconnect() { } /** * Sets the role map. */ public HashMap<String,String> setRoleMap(HashMap<String,String> map) { HashMap<String,String> oldMap = _roleMap; _roleMap = map; return oldMap; } /** * Checks the isUserInRole. */ public boolean isUserInRole(String role) { if (_roleMap != null) { String newRole = _roleMap.get(role); if (newRole != null) role = newRole; } return super.isUserInRole(role); } @Override public boolean isLoginRequested() { return false; } @Override public void requestLogin() { } @Override public boolean login(boolean isFail) { return true; } public boolean isSuspend() { return false; } public boolean hasRequest() { return false; } /** * @since Servlet 3.0 */ public boolean authenticate(HttpServletResponse response) throws IOException, ServletException { return getRequest().authenticate(response); } /** * @since Servlet 3.0 */ public Part getPart(String name) throws IOException, ServletException { return getRequest().getPart(name); } /** * @since Servlet 3.0 */ public Collection<Part> getParts() throws IOException, ServletException { return getRequest().getParts(); } /** * @since Servlet 3.0 */ public void login(String username, String password) throws ServletException { getRequest().login(username, password); } /** * @since Servlet 3.0 */ public void logout() throws ServletException { getRequest().logout(); } public CauchoRequest getCauchoRequest() { return (CauchoRequest) getRequest(); } /** * Frees the adapter for reuse. */ public static void free(RequestAdapter reqAdapt) { reqAdapt.free(); _freeList.free(reqAdapt); } /** * Clears the adapter. */ protected void free() { super.free(); _webApp = null; _response = null; } @Override public String toString() { return getClass().getSimpleName() + '[' + _request + ']'; } }