blob: 30f03be2eb14dfe2435a87d22587bb2e2f5b0f9c [file] [log] [blame]
/*******************************************************************************
* 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é <raymond.auge@liferay.com> - 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> dispatchTargets = new Stack<DispatchTargets>();
private final HttpServletRequest request;
private Map<String, Part> 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<String, String[]> getParameterMap() {
return dispatchTargets.peek().getParameterMap();
}
public Enumeration<String> 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<String, Object> 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<ServletRequestAttributeListener> 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<ServletRequestAttributeListener> 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<Part> getParts() throws IOException, ServletException {
return new ArrayList<Part>(getParts0().values());
}
private Map<String, Part> 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;
}
}