/******************************************************************************* * Copyright (c) 2005, 2016 Cognos Incorporated, IBM Corporation and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * Cognos Incorporated - initial API and implementation * IBM Corporation - bug fixes and enhancements * Raymond Augé - Bug 436698 *******************************************************************************/ package org.eclipse.equinox.http.servlet.internal.servlet; import java.io.IOException; import java.util.*; import java.util.concurrent.locks.Lock; import java.util.concurrent.locks.ReentrantLock; import javax.servlet.*; import javax.servlet.http.*; import org.eclipse.equinox.http.servlet.internal.context.ContextController; import org.eclipse.equinox.http.servlet.internal.context.DispatchTargets; import org.eclipse.equinox.http.servlet.internal.registration.EndpointRegistration; import org.eclipse.equinox.http.servlet.internal.util.Const; import org.eclipse.equinox.http.servlet.internal.util.EventListeners; import org.osgi.service.http.HttpContext; public class HttpServletRequestWrapperImpl extends HttpServletRequestWrapper { private final Stack dispatchTargets = new Stack(); private final HttpServletRequest request; private Map parts; private final Lock lock = new ReentrantLock(); private static final String[] dispatcherAttributes = new String[] { RequestDispatcher.ERROR_EXCEPTION, RequestDispatcher.ERROR_EXCEPTION_TYPE, RequestDispatcher.ERROR_MESSAGE, RequestDispatcher.ERROR_REQUEST_URI, RequestDispatcher.ERROR_SERVLET_NAME, RequestDispatcher.ERROR_STATUS_CODE, RequestDispatcher.FORWARD_CONTEXT_PATH, RequestDispatcher.FORWARD_PATH_INFO, RequestDispatcher.FORWARD_QUERY_STRING, RequestDispatcher.FORWARD_REQUEST_URI, RequestDispatcher.FORWARD_SERVLET_PATH, RequestDispatcher.INCLUDE_CONTEXT_PATH, RequestDispatcher.INCLUDE_PATH_INFO, RequestDispatcher.INCLUDE_QUERY_STRING, RequestDispatcher.INCLUDE_REQUEST_URI, RequestDispatcher.INCLUDE_SERVLET_PATH }; public static HttpServletRequestWrapperImpl findHttpRuntimeRequest( HttpServletRequest request) { while (request instanceof HttpServletRequestWrapper) { if (request instanceof HttpServletRequestWrapperImpl) { return (HttpServletRequestWrapperImpl)request; } request = (HttpServletRequest)((HttpServletRequestWrapper)request).getRequest(); } return null; } public HttpServletRequestWrapperImpl(HttpServletRequest request) { super(request); this.request = request; } public String getAuthType() { String authType = (String) this.getAttribute(HttpContext.AUTHENTICATION_TYPE); if (authType != null) return authType; return request.getAuthType(); } public String getRemoteUser() { String remoteUser = (String) this.getAttribute(HttpContext.REMOTE_USER); if (remoteUser != null) return remoteUser; return request.getRemoteUser(); } public String getPathInfo() { if ((dispatchTargets.peek().getServletName() != null) || (dispatchTargets.peek().getDispatcherType() == DispatcherType.INCLUDE)) { return this.dispatchTargets.get(0).getPathInfo(); } return this.dispatchTargets.peek().getPathInfo(); } public DispatcherType getDispatcherType() { return dispatchTargets.peek().getDispatcherType(); } public String getParameter(String name) { String[] values = getParameterValues(name); if ((values == null) || (values.length == 0)) { return null; } return values[0]; } public Map getParameterMap() { return dispatchTargets.peek().getParameterMap(); } public Enumeration getParameterNames() { return Collections.enumeration(getParameterMap().keySet()); } public String[] getParameterValues(String name) { return getParameterMap().get(name); } @Override public String getQueryString() { if ((dispatchTargets.peek().getServletName() != null) || (dispatchTargets.peek().getDispatcherType() == DispatcherType.INCLUDE)) { return request.getQueryString(); } return this.dispatchTargets.peek().getQueryString(); } @Override public String getRequestURI() { if ((dispatchTargets.peek().getServletName() != null) || (dispatchTargets.peek().getDispatcherType() == DispatcherType.INCLUDE)) { return request.getRequestURI(); } return this.dispatchTargets.peek().getRequestURI(); } public ServletContext getServletContext() { return dispatchTargets.peek().getServletRegistration().getServletContext(); } public String getServletPath() { if ((dispatchTargets.peek().getServletName() != null) || (dispatchTargets.peek().getDispatcherType() == DispatcherType.INCLUDE)) { return this.dispatchTargets.get(0).getServletPath(); } if (dispatchTargets.peek().getServletPath().equals(Const.SLASH)) { return Const.BLANK; } return this.dispatchTargets.peek().getServletPath(); } public String getContextPath() { return dispatchTargets.peek().getContextController().getFullContextPath(); } public Object getAttribute(String attributeName) { DispatchTargets current = dispatchTargets.peek(); Map specialOverides = current.getSpecialOverides(); if (current.getDispatcherType() == DispatcherType.ERROR) { if ((Arrays.binarySearch(dispatcherAttributes, attributeName) > -1) && !attributeName.startsWith("javax.servlet.error.")) { //$NON-NLS-1$ return null; } } else if (current.getDispatcherType() == DispatcherType.INCLUDE) { if (attributeName.equals(RequestDispatcher.INCLUDE_CONTEXT_PATH)) { if (current.getServletName() != null) { return null; } if (specialOverides.containsKey(RequestDispatcher.INCLUDE_CONTEXT_PATH)) { return specialOverides.get(RequestDispatcher.INCLUDE_CONTEXT_PATH); } return current.getContextController().getContextPath(); } else if (attributeName.equals(RequestDispatcher.INCLUDE_PATH_INFO)) { if (current.getServletName() != null) { return null; } if (specialOverides.containsKey(RequestDispatcher.INCLUDE_PATH_INFO)) { return specialOverides.get(RequestDispatcher.INCLUDE_PATH_INFO); } return current.getPathInfo(); } else if (attributeName.equals(RequestDispatcher.INCLUDE_QUERY_STRING)) { if (current.getServletName() != null) { return null; } if (specialOverides.containsKey(RequestDispatcher.INCLUDE_QUERY_STRING)) { return specialOverides.get(RequestDispatcher.INCLUDE_QUERY_STRING); } return current.getQueryString(); } else if (attributeName.equals(RequestDispatcher.INCLUDE_REQUEST_URI)) { if (current.getServletName() != null) { return null; } if (specialOverides.containsKey(RequestDispatcher.INCLUDE_REQUEST_URI)) { return specialOverides.get(RequestDispatcher.INCLUDE_REQUEST_URI); } return current.getRequestURI(); } else if (attributeName.equals(RequestDispatcher.INCLUDE_SERVLET_PATH)) { if (current.getServletName() != null) { return null; } if (specialOverides.containsKey(RequestDispatcher.INCLUDE_SERVLET_PATH)) { return specialOverides.get(RequestDispatcher.INCLUDE_SERVLET_PATH); } return current.getServletPath(); } if (Arrays.binarySearch(dispatcherAttributes, attributeName) > -1) { return null; } } else if (current.getDispatcherType() == DispatcherType.FORWARD) { DispatchTargets original = dispatchTargets.get(0); if (attributeName.equals(RequestDispatcher.FORWARD_CONTEXT_PATH)) { if (current.getServletName() != null) { return null; } if (specialOverides.containsKey(RequestDispatcher.FORWARD_CONTEXT_PATH)) { return specialOverides.get(RequestDispatcher.FORWARD_CONTEXT_PATH); } return original.getContextController().getContextPath(); } else if (attributeName.equals(RequestDispatcher.FORWARD_PATH_INFO)) { if (current.getServletName() != null) { return null; } if (specialOverides.containsKey(RequestDispatcher.FORWARD_PATH_INFO)) { return specialOverides.get(RequestDispatcher.FORWARD_PATH_INFO); } return original.getPathInfo(); } else if (attributeName.equals(RequestDispatcher.FORWARD_QUERY_STRING)) { if (current.getServletName() != null) { return null; } if (specialOverides.containsKey(RequestDispatcher.FORWARD_QUERY_STRING)) { return specialOverides.get(RequestDispatcher.FORWARD_QUERY_STRING); } return original.getQueryString(); } else if (attributeName.equals(RequestDispatcher.FORWARD_REQUEST_URI)) { if (current.getServletName() != null) { return null; } if (specialOverides.containsKey(RequestDispatcher.FORWARD_REQUEST_URI)) { return specialOverides.get(RequestDispatcher.FORWARD_REQUEST_URI); } return original.getRequestURI(); } else if (attributeName.equals(RequestDispatcher.FORWARD_SERVLET_PATH)) { if (current.getServletName() != null) { return null; } if (specialOverides.containsKey(RequestDispatcher.FORWARD_SERVLET_PATH)) { return specialOverides.get(RequestDispatcher.FORWARD_SERVLET_PATH); } return original.getServletPath(); } if (Arrays.binarySearch(dispatcherAttributes, attributeName) > -1) { return null; } } return request.getAttribute(attributeName); } public RequestDispatcher getRequestDispatcher(String path) { ContextController contextController = this.dispatchTargets.peek().getContextController(); // support relative paths if (!path.startsWith(Const.SLASH)) { path = this.dispatchTargets.peek().getServletPath() + Const.SLASH + path; } // if the path starts with the full context path strip it else if (path.startsWith(contextController.getFullContextPath())) { path = path.substring(contextController.getFullContextPath().length()); } DispatchTargets requestedDispatchTargets = contextController.getDispatchTargets(path, null); if (requestedDispatchTargets == null) { return null; } return new RequestDispatcherAdaptor(requestedDispatchTargets, path); } public static String getDispatchPathInfo(HttpServletRequest req) { if (req.getDispatcherType() == DispatcherType.INCLUDE) return (String) req.getAttribute(RequestDispatcher.INCLUDE_PATH_INFO); return req.getPathInfo(); } public HttpSession getSession() { HttpSession session = request.getSession(); if (session != null) { return dispatchTargets.peek().getContextController().getSessionAdaptor( session, dispatchTargets.peek().getServletRegistration().getT().getServletConfig().getServletContext()); } return null; } public HttpSession getSession(boolean create) { HttpSession session = request.getSession(create); if (session != null) { return dispatchTargets.peek().getContextController().getSessionAdaptor( session, dispatchTargets.peek().getServletRegistration().getT().getServletConfig().getServletContext()); } return null; } public synchronized void pop() { if (dispatchTargets.size() > 1) { this.dispatchTargets.pop(); } } public synchronized void push(DispatchTargets toPush) { toPush.addRequestParameters(request); this.dispatchTargets.push(toPush); } public void removeAttribute(String name) { if (Arrays.binarySearch(dispatcherAttributes, name) > -1) { DispatchTargets current = dispatchTargets.peek(); current.getSpecialOverides().remove(name); } else { request.removeAttribute(name); } EventListeners eventListeners = dispatchTargets.peek().getContextController().getEventListeners(); List listeners = eventListeners.get( ServletRequestAttributeListener.class); if (listeners.isEmpty()) { return; } ServletRequestAttributeEvent servletRequestAttributeEvent = new ServletRequestAttributeEvent( dispatchTargets.peek().getServletRegistration().getServletContext(), this, name, null); for (ServletRequestAttributeListener servletRequestAttributeListener : listeners) { servletRequestAttributeListener.attributeRemoved( servletRequestAttributeEvent); } } public void setAttribute(String name, Object value) { boolean added = (request.getAttribute(name) == null); if (Arrays.binarySearch(dispatcherAttributes, name) > -1) { DispatchTargets current = dispatchTargets.peek(); if (value == null) { current.getSpecialOverides().remove(name); } else { current.getSpecialOverides().put(name, value); } } else { request.setAttribute(name, value); } EventListeners eventListeners = dispatchTargets.peek().getContextController().getEventListeners(); List listeners = eventListeners.get( ServletRequestAttributeListener.class); if (listeners.isEmpty()) { return; } ServletRequestAttributeEvent servletRequestAttributeEvent = new ServletRequestAttributeEvent( dispatchTargets.peek().getServletRegistration().getServletContext(), this, name, value); for (ServletRequestAttributeListener servletRequestAttributeListener : listeners) { if (added) { servletRequestAttributeListener.attributeAdded( servletRequestAttributeEvent); } else { servletRequestAttributeListener.attributeReplaced( servletRequestAttributeEvent); } } } @Override public Part getPart(String name) throws IOException, ServletException { return getParts0().get(name); } @Override public Collection getParts() throws IOException, ServletException { return new ArrayList(getParts0().values()); } private Map getParts0() throws IOException, ServletException { org.eclipse.equinox.http.servlet.internal.registration.ServletRegistration servletRegistration = getServletRegistration(); if (servletRegistration == null) { throw new ServletException("Not a servlet request!"); //$NON-NLS-1$ } lock.lock(); try { if (parts != null) { return parts; } return parts = servletRegistration.parseRequest(this); } finally { lock.unlock(); } } private org.eclipse.equinox.http.servlet.internal.registration.ServletRegistration getServletRegistration() { EndpointRegistration servletRegistration = dispatchTargets.peek().getServletRegistration(); if (servletRegistration instanceof org.eclipse.equinox.http.servlet.internal.registration.ServletRegistration) { return (org.eclipse.equinox.http.servlet.internal.registration.ServletRegistration)servletRegistration; } return null; } }