You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by ja...@apache.org on 2014/07/04 15:25:21 UTC
svn commit: r1607850 [1/2] - in /felix/sandbox/http-rfc189:
api/src/main/java/org/apache/felix/http/api/
base/src/main/java/org/apache/felix/http/base/internal/dispatch/
base/src/main/java/org/apache/felix/http/base/internal/handler/
base/src/main/java...
Author: jawi
Date: Fri Jul 4 13:25:21 2014
New Revision: 1607850
URL: http://svn.apache.org/r1607850
Log:
RFC-189 / FELIX-2137 / FELIX-1651 / FELIX-4541:
- add support for multiple patterns (and regex's in case of Filters), which also includes
adding support for wildcards in patterns (FELIX-1651 & FELIX-4541);
- add support for named servlets/filters, and added tests for named request dispatchers;
- simplified the dispatching stage by determining the applicable servlet/filters as soon
as possible (allows us to simplify the Servlet/FilterHandler);
- unify the various used ServletRequestWrappers into one, again to simplify the dispatch
logic;
- added integration tests for filters & servlets with some of the new functionality we
now have implemented.
Added:
felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/dispatch/HttpSessionWrapper.java
- copied, changed from r1607310, felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/handler/HttpSessionWrapper.java
felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/dispatch/ServletContextWrapper.java
- copied, changed from r1607310, felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/handler/ServletContextWrapper.java
felix/sandbox/http-rfc189/itest/src/test/java/org/apache/felix/http/itest/FilterTest.java (with props)
felix/sandbox/http-rfc189/itest/src/test/java/org/apache/felix/http/itest/ServletTest.java (with props)
Removed:
felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/dispatch/FilterPipeline.java
felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/dispatch/ServletPipeline.java
felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/handler/HttpSessionWrapper.java
felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/handler/ServletContextWrapper.java
felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/handler/ServletHandlerRequest.java
felix/sandbox/http-rfc189/base/src/test/java/org/apache/felix/http/base/internal/handler/ServletHandlerRequestTest.java
Modified:
felix/sandbox/http-rfc189/api/src/main/java/org/apache/felix/http/api/FilterInfo.java
felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/dispatch/Dispatcher.java
felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/dispatch/HttpFilterChain.java
felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/dispatch/InvocationFilterChain.java
felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/dispatch/NotFoundFilterChain.java
felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/handler/AbstractHandler.java
felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/handler/FilterHandler.java
felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/handler/HandlerMapping.java
felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/handler/HandlerRegistry.java
felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/handler/HttpServicePlugin.java
felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/handler/ServletHandler.java
felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/service/HttpServiceImpl.java
felix/sandbox/http-rfc189/base/src/test/java/org/apache/felix/http/base/internal/handler/FilterHandlerTest.java
felix/sandbox/http-rfc189/base/src/test/java/org/apache/felix/http/base/internal/handler/HandlerMappingTest.java
felix/sandbox/http-rfc189/base/src/test/java/org/apache/felix/http/base/internal/handler/ServletHandlerTest.java
felix/sandbox/http-rfc189/itest/src/test/java/org/apache/felix/http/itest/AsyncTest.java
felix/sandbox/http-rfc189/itest/src/test/java/org/apache/felix/http/itest/BaseIntegrationTest.java
felix/sandbox/http-rfc189/itest/src/test/java/org/apache/felix/http/itest/HttpJettyTest.java
felix/sandbox/http-rfc189/itest/src/test/java/org/apache/felix/http/itest/RequestDispatchTest.java
felix/sandbox/http-rfc189/whiteboard/src/main/java/org/apache/felix/http/whiteboard/internal/manager/ExtenderManager.java
Modified: felix/sandbox/http-rfc189/api/src/main/java/org/apache/felix/http/api/FilterInfo.java
URL: http://svn.apache.org/viewvc/felix/sandbox/http-rfc189/api/src/main/java/org/apache/felix/http/api/FilterInfo.java?rev=1607850&r1=1607849&r2=1607850&view=diff
==============================================================================
--- felix/sandbox/http-rfc189/api/src/main/java/org/apache/felix/http/api/FilterInfo.java (original)
+++ felix/sandbox/http-rfc189/api/src/main/java/org/apache/felix/http/api/FilterInfo.java Fri Jul 4 13:25:21 2014
@@ -88,7 +88,7 @@ public final class FilterInfo
* See {@link DispatcherType} and Servlet 3.0 specification, section 6.2.5.
* </p>
*/
- public String[] dispatcher = { "REQUEST" };
+ public DispatcherType[] dispatcher = { DispatcherType.REQUEST };
/**
* The filter initialization parameters as provided during registration of the filter.
Modified: felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/dispatch/Dispatcher.java
URL: http://svn.apache.org/viewvc/felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/dispatch/Dispatcher.java?rev=1607850&r1=1607849&r2=1607850&view=diff
==============================================================================
--- felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/dispatch/Dispatcher.java (original)
+++ felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/dispatch/Dispatcher.java Fri Jul 4 13:25:21 2014
@@ -16,19 +16,372 @@
*/
package org.apache.felix.http.base.internal.dispatch;
+import static javax.servlet.RequestDispatcher.FORWARD_CONTEXT_PATH;
+import static javax.servlet.RequestDispatcher.FORWARD_PATH_INFO;
+import static javax.servlet.RequestDispatcher.FORWARD_QUERY_STRING;
+import static javax.servlet.RequestDispatcher.FORWARD_REQUEST_URI;
+import static javax.servlet.RequestDispatcher.FORWARD_SERVLET_PATH;
+import static javax.servlet.RequestDispatcher.INCLUDE_CONTEXT_PATH;
+import static javax.servlet.RequestDispatcher.INCLUDE_PATH_INFO;
+import static javax.servlet.RequestDispatcher.INCLUDE_QUERY_STRING;
+import static javax.servlet.RequestDispatcher.INCLUDE_REQUEST_URI;
+import static javax.servlet.RequestDispatcher.INCLUDE_SERVLET_PATH;
+import static org.apache.felix.http.base.internal.util.UriUtils.compactPath;
+import static org.apache.felix.http.base.internal.util.UriUtils.concat;
+import static org.apache.felix.http.base.internal.util.UriUtils.decodePath;
+import static org.apache.felix.http.base.internal.util.UriUtils.relativePath;
+import static org.apache.felix.http.base.internal.util.UriUtils.removeDotSegments;
+
import java.io.IOException;
+import javax.servlet.DispatcherType;
import javax.servlet.FilterChain;
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletContext;
import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpSession;
+import org.apache.felix.http.base.internal.context.ExtServletContext;
+import org.apache.felix.http.base.internal.handler.FilterHandler;
import org.apache.felix.http.base.internal.handler.HandlerRegistry;
+import org.apache.felix.http.base.internal.handler.ServletHandler;
+import org.apache.felix.http.base.internal.util.UriUtils;
+import org.osgi.service.http.HttpContext;
+import org.osgi.service.useradmin.Authorization;
-public final class Dispatcher
+public final class Dispatcher implements RequestDispatcherProvider
{
+ /**
+ * Wrapper implementation for {@link RequestDispatcher}.
+ */
+ final class RequestDispatcherImpl implements RequestDispatcher
+ {
+ private final RequestInfo requestInfo;
+ private final ServletHandler handler;
+
+ public RequestDispatcherImpl(ServletHandler handler, RequestInfo requestInfo)
+ {
+ this.handler = handler;
+ this.requestInfo = requestInfo;
+ }
+
+ public void forward(ServletRequest request, ServletResponse response) throws ServletException, IOException
+ {
+ if (response.isCommitted())
+ {
+ throw new ServletException("Response has been committed");
+ }
+ else
+ {
+ // See section 9.4 of Servlet 3.0 spec
+ response.resetBuffer();
+ }
+
+ try
+ {
+ ServletRequestWrapper req = new ServletRequestWrapper((HttpServletRequest) request, this.handler.getContext(), this.requestInfo, DispatcherType.FORWARD);
+ Dispatcher.this.forward(this.handler, req, (HttpServletResponse) response);
+ }
+ finally
+ {
+ // After a forward has taken place, the results should be committed,
+ // see section 9.4 of Servlet 3.0 spec...
+ if (!request.isAsyncStarted())
+ {
+ response.flushBuffer();
+ response.getWriter().close();
+ }
+ }
+ }
+
+ public void include(ServletRequest request, ServletResponse response) throws ServletException, IOException
+ {
+ ServletRequestWrapper req = new ServletRequestWrapper((HttpServletRequest) request, this.handler.getContext(), this.requestInfo, DispatcherType.INCLUDE);
+ Dispatcher.this.include(this.handler, req, (HttpServletResponse) response);
+ }
+ }
+
+ final class ServletRequestWrapper extends HttpServletRequestWrapper
+ {
+ private final DispatcherType type;
+ private final RequestInfo requestInfo;
+ private final ExtServletContext servletContext;
+
+ public ServletRequestWrapper(HttpServletRequest req, ExtServletContext servletContext, RequestInfo requestInfo)
+ {
+ this(req, servletContext, requestInfo, null /* type */);
+ }
+
+ public ServletRequestWrapper(HttpServletRequest req, ExtServletContext servletContext, RequestInfo requestInfo, DispatcherType type)
+ {
+ super(req);
+
+ this.servletContext = servletContext;
+ this.requestInfo = requestInfo;
+ this.type = type;
+ }
+
+ @Override
+ public Object getAttribute(String name)
+ {
+ HttpServletRequest request = (HttpServletRequest) getRequest();
+ if (isInclusionDispatcher())
+ {
+ // The javax.servlet.include.* attributes refer to the information of the *included* request,
+ // meaning that the request information comes from the *original* request...
+ if (INCLUDE_REQUEST_URI.equals(name))
+ {
+ return concat(request.getContextPath(), this.requestInfo.requestURI);
+ }
+ else if (INCLUDE_CONTEXT_PATH.equals(name))
+ {
+ return request.getContextPath();
+ }
+ else if (INCLUDE_SERVLET_PATH.equals(name))
+ {
+ return this.requestInfo.servletPath;
+ }
+ else if (INCLUDE_PATH_INFO.equals(name))
+ {
+ return this.requestInfo.pathInfo;
+ }
+ else if (INCLUDE_QUERY_STRING.equals(name))
+ {
+ return this.requestInfo.queryString;
+ }
+ }
+ else if (isForwardingDispatcher())
+ {
+ // The javax.servlet.forward.* attributes refer to the information of the *original* request,
+ // meaning that the request information comes from the *forwarded* request...
+ if (FORWARD_REQUEST_URI.equals(name))
+ {
+ return super.getRequestURI();
+ }
+ else if (FORWARD_CONTEXT_PATH.equals(name))
+ {
+ return request.getContextPath();
+ }
+ else if (FORWARD_SERVLET_PATH.equals(name))
+ {
+ return super.getServletPath();
+ }
+ else if (FORWARD_PATH_INFO.equals(name))
+ {
+ return super.getPathInfo();
+ }
+ else if (FORWARD_QUERY_STRING.equals(name))
+ {
+ return super.getQueryString();
+ }
+ }
+ return super.getAttribute(name);
+ }
+
+ @Override
+ public String getAuthType()
+ {
+ String authType = (String) getAttribute(HttpContext.AUTHENTICATION_TYPE);
+ if (authType == null)
+ {
+ authType = super.getAuthType();
+ }
+ return authType;
+ }
+
+ @Override
+ public String getContextPath()
+ {
+ /*
+ * FELIX-2030 Calculate the context path for the Http Service
+ * registered servlets from the container context and servlet paths
+ */
+ // if (contextPath == null)
+ // {
+ // final String context = super.getContextPath();
+ // final String servlet = super.getServletPath();
+ // if (context == null || context.length() == 0)
+ // {
+ // contextPath = servlet;
+ // }
+ // else if (servlet == null || servlet.length() == 0)
+ // {
+ // contextPath = context;
+ // }
+ // else
+ // {
+ // contextPath = context + servlet;
+ // }
+ // }
+
+ return super.getContextPath();
+ }
+
+ @Override
+ public DispatcherType getDispatcherType()
+ {
+ return (this.type == null) ? super.getDispatcherType() : this.type;
+ }
+
+ @Override
+ public String getPathInfo()
+ {
+ String pathInfo = super.getPathInfo();
+ if (isForwardingDispatcher() || !isWrapperFor(ServletRequestWrapper.class))
+ {
+ pathInfo = this.requestInfo.pathInfo;
+ }
+ return pathInfo;
+ }
+
+ @Override
+ @SuppressWarnings("deprecation")
+ public String getPathTranslated()
+ {
+ final String info = getPathInfo();
+ return (null == info) ? null : getRealPath(info);
+ }
+
+ @Override
+ public String getRemoteUser()
+ {
+ String remoteUser = (String) getAttribute(HttpContext.REMOTE_USER);
+ if (remoteUser != null)
+ {
+ return remoteUser;
+ }
+
+ return super.getRemoteUser();
+ }
+
+ @Override
+ public RequestDispatcher getRequestDispatcher(String path)
+ {
+ // See section 9.1 of Servlet 3.0 specification...
+ if (path == null)
+ {
+ return null;
+ }
+ // Handle relative paths, see Servlet 3.0 spec, section 9.1 last paragraph.
+ boolean relPath = !path.startsWith("/") && !"".equals(path);
+ if (relPath)
+ {
+ path = concat(getServletPath(), path);
+ }
+ return Dispatcher.this.getRequestDispatcher(path);
+ }
+
+ @Override
+ public String getRequestURI()
+ {
+ String requestURI = super.getRequestURI();
+ if (isForwardingDispatcher() || !isWrapperFor(ServletRequestWrapper.class))
+ {
+ requestURI = concat(getContextPath(), this.requestInfo.requestURI);
+ }
+ return requestURI;
+ }
+
+ @Override
+ public ServletContext getServletContext()
+ {
+ return new ServletContextWrapper(this.servletContext, Dispatcher.this);
+ }
+
+ @Override
+ public String getServletPath()
+ {
+ String servletPath = super.getServletPath();
+ if (isForwardingDispatcher() || !isWrapperFor(ServletRequestWrapper.class))
+ {
+ servletPath = this.requestInfo.servletPath;
+ }
+ if ("/".equals(servletPath))
+ {
+ return ""; // XXX still necessary?
+ }
+ return servletPath;
+ }
+
+ @Override
+ public HttpSession getSession(boolean create)
+ {
+ // FELIX-2797: wrap the original HttpSession to provide access to the correct ServletContext...
+ HttpSession session = super.getSession(create);
+ if (session == null)
+ {
+ return null;
+ }
+ return new HttpSessionWrapper(session, this.servletContext);
+ }
+
+ @Override
+ public boolean isUserInRole(String role)
+ {
+ Authorization authorization = (Authorization) getAttribute(HttpContext.AUTHORIZATION);
+ if (authorization != null)
+ {
+ return authorization.hasRole(role);
+ }
+
+ return super.isUserInRole(role);
+ }
+
+ @Override
+ public String toString()
+ {
+ return getClass().getSimpleName() + "->" + super.getRequest();
+ }
+
+ private boolean isForwardingDispatcher()
+ {
+ return (DispatcherType.FORWARD == this.type) && (this.requestInfo != null);
+ }
+
+ private boolean isInclusionDispatcher()
+ {
+ return (DispatcherType.INCLUDE == this.type) && (this.requestInfo != null);
+ }
+ }
+
+ private static class RequestInfo
+ {
+ final String servletPath;
+ final String pathInfo;
+ final String queryString;
+ final String requestURI;
+
+ public RequestInfo(String servletPath, String pathInfo, String queryString)
+ {
+ this.servletPath = servletPath;
+ this.pathInfo = pathInfo;
+ this.queryString = queryString;
+ this.requestURI = compactPath(concat(servletPath, pathInfo));
+ }
+
+ @Override
+ public String toString()
+ {
+ StringBuilder sb = new StringBuilder("RequestInfo[servletPath =");
+ sb.append(this.servletPath).append(", pathInfo = ").append(this.pathInfo);
+ sb.append(", queryString = ").append(this.queryString).append("]");
+ return sb.toString();
+ }
+ }
+
+ /**
+ * Request attribute that provides access to the request dispatcher provider.
+ */
public static final String REQUEST_DISPATCHER_PROVIDER = "org.apache.felix.http.requestDispatcherProvider";
+ /**
+ * Catch-all filter chain that simple finishes all requests with a "404 Not Found" error.
+ */
private static final FilterChain DEFAULT_CHAIN = new NotFoundFilterChain();
private final HandlerRegistry handlerRegistry;
@@ -40,18 +393,103 @@ public final class Dispatcher
public void dispatch(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException
{
- ServletPipeline servletPipeline = new ServletPipeline(this.handlerRegistry.getServletMapping());
+ String requestURI = getRequestURI(req);
+
+ // Determine which servlets we should forward the request to...
+ ServletHandler servletHandler = this.handlerRegistry.getServletHander(requestURI);
+ FilterHandler[] filterHandlers = this.handlerRegistry.getFilterHandlers(servletHandler, req.getDispatcherType(), requestURI);
+
// Provides access to the correct request dispatcher...
- req.setAttribute(REQUEST_DISPATCHER_PROVIDER, servletPipeline);
+ req.setAttribute(REQUEST_DISPATCHER_PROVIDER, this);
+
+ String servletPath = (servletHandler != null) ? servletHandler.determineServletPath(requestURI) : "";
+ String pathInfo = compactPath(relativePath(servletPath, requestURI));
+ String queryString = null; // XXX
+
+ ExtServletContext servletContext = (servletHandler != null) ? servletHandler.getContext() : null;
+ RequestInfo requestInfo = new RequestInfo(servletPath, pathInfo, queryString);
- FilterPipeline filterPipeline = new FilterPipeline(this.handlerRegistry.getFilterMapping(), servletPipeline);
try
{
- filterPipeline.dispatch(req, res, DEFAULT_CHAIN);
+ invokeChain(filterHandlers, servletHandler, new ServletRequestWrapper(req, servletContext, requestInfo), res);
}
finally
{
req.removeAttribute(REQUEST_DISPATCHER_PROVIDER);
}
}
+
+ public RequestDispatcher getNamedDispatcher(String name)
+ {
+ ServletHandler handler = this.handlerRegistry.getServletHandlerByName(name);
+ return handler != null ? new RequestDispatcherImpl(handler, null) : null;
+ }
+
+ public RequestDispatcher getRequestDispatcher(String path)
+ {
+ // See section 9.1 of Servlet 3.x specification...
+ if (path == null || (!path.startsWith("/") && !"".equals(path)))
+ {
+ return null;
+ }
+
+ String query = null;
+ int q = 0;
+ if ((q = path.indexOf('?')) > 0)
+ {
+ query = path.substring(q + 1);
+ path = path.substring(0, q);
+ }
+ // TODO remove path parameters...
+ String requestURI = decodePath(removeDotSegments(path));
+
+ ServletHandler handler = this.handlerRegistry.getServletHander(requestURI);
+ if (handler == null)
+ {
+ return null;
+ }
+
+ String servletPath = handler.determineServletPath(requestURI);
+ String pathInfo = relativePath(servletPath, path);
+
+ RequestInfo requestInfo = new RequestInfo(servletPath, pathInfo, query);
+ return new RequestDispatcherImpl(handler, requestInfo);
+ }
+
+ /**
+ * @param servletHandler the servlet that should handle the forward request;
+ * @param request the {@link HttpServletRequest};
+ * @param response the {@link HttpServletResponse};
+ */
+ void forward(ServletHandler servletHandler, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+ {
+ String requestURI = getRequestURI(request);
+ FilterHandler[] filterHandlers = this.handlerRegistry.getFilterHandlers(servletHandler, DispatcherType.FORWARD, requestURI);
+
+ invokeChain(filterHandlers, servletHandler, request, response);
+ }
+
+ /**
+ * @param servletHandler the servlet that should handle the include request;
+ * @param request the {@link HttpServletRequest};
+ * @param response the {@link HttpServletResponse};
+ */
+ void include(ServletHandler servletHandler, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
+ {
+ String requestURI = getRequestURI(request);
+ FilterHandler[] filterHandlers = this.handlerRegistry.getFilterHandlers(servletHandler, DispatcherType.INCLUDE, requestURI);
+
+ invokeChain(filterHandlers, servletHandler, request, response);
+ }
+
+ private String getRequestURI(HttpServletRequest req)
+ {
+ return UriUtils.relativePath(req.getContextPath(), req.getRequestURI());
+ }
+
+ private void invokeChain(FilterHandler[] filterHandlers, ServletHandler servletHandler, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
+ {
+ FilterChain filterChain = new InvocationFilterChain(servletHandler, filterHandlers, DEFAULT_CHAIN);
+ filterChain.doFilter(request, response);
+ }
}
Modified: felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/dispatch/HttpFilterChain.java
URL: http://svn.apache.org/viewvc/felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/dispatch/HttpFilterChain.java?rev=1607850&r1=1607849&r2=1607850&view=diff
==============================================================================
--- felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/dispatch/HttpFilterChain.java (original)
+++ felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/dispatch/HttpFilterChain.java Fri Jul 4 13:25:21 2014
@@ -24,6 +24,9 @@ import javax.servlet.http.HttpServletReq
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
+/**
+ * Convenience adapter for {@link FilterChain}s that makes the obtrusive casting unnecessary.
+ */
public abstract class HttpFilterChain implements FilterChain
{
public final void doFilter(ServletRequest req, ServletResponse res) throws IOException, ServletException
@@ -31,5 +34,8 @@ public abstract class HttpFilterChain im
doFilter((HttpServletRequest) req, (HttpServletResponse) res);
}
+ /**
+ * @see FilterChain#doFilter(ServletRequest, ServletResponse)
+ */
protected abstract void doFilter(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException;
}
Copied: felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/dispatch/HttpSessionWrapper.java (from r1607310, felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/handler/HttpSessionWrapper.java)
URL: http://svn.apache.org/viewvc/felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/dispatch/HttpSessionWrapper.java?p2=felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/dispatch/HttpSessionWrapper.java&p1=felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/handler/HttpSessionWrapper.java&r1=1607310&r2=1607850&rev=1607850&view=diff
==============================================================================
--- felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/handler/HttpSessionWrapper.java (original)
+++ felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/dispatch/HttpSessionWrapper.java Fri Jul 4 13:25:21 2014
@@ -17,7 +17,7 @@
* under the License.
*/
-package org.apache.felix.http.base.internal.handler;
+package org.apache.felix.http.base.internal.dispatch;
import java.util.Enumeration;
Modified: felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/dispatch/InvocationFilterChain.java
URL: http://svn.apache.org/viewvc/felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/dispatch/InvocationFilterChain.java?rev=1607850&r1=1607849&r2=1607850&view=diff
==============================================================================
--- felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/dispatch/InvocationFilterChain.java (original)
+++ felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/dispatch/InvocationFilterChain.java Fri Jul 4 13:25:21 2014
@@ -16,8 +16,9 @@
*/
package org.apache.felix.http.base.internal.dispatch;
+import static javax.servlet.http.HttpServletResponse.SC_OK;
+
import java.io.IOException;
-import java.util.List;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
@@ -25,35 +26,48 @@ import javax.servlet.http.HttpServletReq
import javax.servlet.http.HttpServletResponse;
import org.apache.felix.http.base.internal.handler.FilterHandler;
+import org.apache.felix.http.base.internal.handler.ServletHandler;
class InvocationFilterChain extends HttpFilterChain
{
- private final FilterHandler[] handlers;
- private final ServletPipeline servletPipeline;
- private final FilterChain proceedingChain;
+ private final ServletHandler servletHandler;
+ private final FilterHandler[] filterHandlers;
+ private final FilterChain defaultChain;
+
private int index = -1;
- public InvocationFilterChain(List<FilterHandler> handlers, ServletPipeline servletPipeline, FilterChain proceedingChain)
+ public InvocationFilterChain(ServletHandler servletHandler, FilterHandler[] filterHandlers, FilterChain defaultChain)
{
- this.handlers = handlers.toArray(new FilterHandler[handlers.size()]);
- this.servletPipeline = servletPipeline;
- this.proceedingChain = proceedingChain;
+ this.filterHandlers = filterHandlers;
+ this.servletHandler = servletHandler;
+ this.defaultChain = defaultChain;
}
protected void doFilter(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException
{
this.index++;
- if (this.index < this.handlers.length)
+ if (this.index < this.filterHandlers.length)
{
- this.handlers[this.index].handle(req, res, this);
- }
- else
- {
- if (!this.servletPipeline.handle(req, res))
+ if (this.filterHandlers[this.index].handle(req, res, this))
{
- this.proceedingChain.doFilter(req, res);
+ // We're done...
+ return;
}
}
+
+ // Last entry in the chain...
+ if (this.servletHandler != null && this.servletHandler.handle(req, res))
+ {
+ // We're done...
+ return;
+ }
+
+ // FELIX-3988: If the response is not yet committed and still has the default
+ // status, we're going to override this and send an error instead.
+ if (!res.isCommitted() && res.getStatus() == SC_OK)
+ {
+ this.defaultChain.doFilter(req, res);
+ }
}
}
Modified: felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/dispatch/NotFoundFilterChain.java
URL: http://svn.apache.org/viewvc/felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/dispatch/NotFoundFilterChain.java?rev=1607850&r1=1607849&r2=1607850&view=diff
==============================================================================
--- felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/dispatch/NotFoundFilterChain.java (original)
+++ felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/dispatch/NotFoundFilterChain.java Fri Jul 4 13:25:21 2014
@@ -16,10 +16,11 @@
*/
package org.apache.felix.http.base.internal.dispatch;
+import java.io.IOException;
+
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
-import java.io.IOException;
public final class NotFoundFilterChain extends HttpFilterChain
{
Copied: felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/dispatch/ServletContextWrapper.java (from r1607310, felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/handler/ServletContextWrapper.java)
URL: http://svn.apache.org/viewvc/felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/dispatch/ServletContextWrapper.java?p2=felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/dispatch/ServletContextWrapper.java&p1=felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/handler/ServletContextWrapper.java&r1=1607310&r2=1607850&rev=1607850&view=diff
==============================================================================
--- felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/handler/ServletContextWrapper.java (original)
+++ felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/dispatch/ServletContextWrapper.java Fri Jul 4 13:25:21 2014
@@ -17,13 +17,12 @@
* under the License.
*/
-package org.apache.felix.http.base.internal.handler;
+package org.apache.felix.http.base.internal.dispatch;
import javax.servlet.RequestDispatcher;
import org.apache.felix.http.base.internal.context.ExtServletContext;
import org.apache.felix.http.base.internal.context.ServletContextImpl;
-import org.apache.felix.http.base.internal.dispatch.RequestDispatcherProvider;
/**
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
Modified: felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/handler/AbstractHandler.java
URL: http://svn.apache.org/viewvc/felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/handler/AbstractHandler.java?rev=1607850&r1=1607849&r2=1607850&view=diff
==============================================================================
--- felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/handler/AbstractHandler.java (original)
+++ felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/handler/AbstractHandler.java Fri Jul 4 13:25:21 2014
@@ -29,8 +29,10 @@ import javax.servlet.ServletException;
import org.apache.felix.http.base.internal.context.ExtServletContext;
-public abstract class AbstractHandler
+public abstract class AbstractHandler<T extends AbstractHandler> implements Comparable<T>
{
+ public static final String ASYNC_SERVLET_PATH = "javax.servlet.async.path_info";
+
private final static AtomicInteger ID = new AtomicInteger();
private final int id;
@@ -48,6 +50,11 @@ public abstract class AbstractHandler
public abstract void destroy();
+ public final ExtServletContext getContext()
+ {
+ return this.context;
+ }
+
public final Map<String, String> getInitParams()
{
return this.initParams;
@@ -62,20 +69,11 @@ public abstract class AbstractHandler
}
return name;
}
-
+
public abstract Pattern[] getPatterns();
public abstract void init() throws ServletException;
- public final void setInitParams(Map<String, String> map)
- {
- this.initParams.clear();
- if (map != null)
- {
- this.initParams.putAll(map);
- }
- }
-
public final void setInitParams(Dictionary map)
{
this.initParams.clear();
@@ -97,9 +95,13 @@ public abstract class AbstractHandler
}
}
- protected final ExtServletContext getContext()
+ public final void setInitParams(Map<String, String> map)
{
- return this.context;
+ this.initParams.clear();
+ if (map != null)
+ {
+ this.initParams.putAll(map);
+ }
}
/**
Modified: felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/handler/FilterHandler.java
URL: http://svn.apache.org/viewvc/felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/handler/FilterHandler.java?rev=1607850&r1=1607849&r2=1607850&view=diff
==============================================================================
--- felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/handler/FilterHandler.java (original)
+++ felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/handler/FilterHandler.java Fri Jul 4 13:25:21 2014
@@ -18,8 +18,11 @@ package org.apache.felix.http.base.inter
import static javax.servlet.http.HttpServletResponse.SC_FORBIDDEN;
import static javax.servlet.http.HttpServletResponse.SC_OK;
+import static org.apache.felix.http.base.internal.util.PatternUtil.convertToRegEx;
import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
import java.util.regex.Pattern;
import javax.servlet.Filter;
@@ -28,36 +31,44 @@ import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import org.apache.felix.http.api.FilterInfo;
import org.apache.felix.http.base.internal.context.ExtServletContext;
-public final class FilterHandler extends AbstractHandler implements Comparable<FilterHandler>
+public final class FilterHandler extends AbstractHandler<FilterHandler>
{
private final Filter filter;
- private final String[] patternStrings;
+ private final FilterInfo filterInfo;
private final Pattern[] patterns;
- private final int ranking;
- public FilterHandler(ExtServletContext context, Filter filter, String[] patterns, int ranking, String name)
+ public FilterHandler(ExtServletContext context, Filter filter, FilterInfo filterInfo)
{
- super(context, name);
+ super(context, filterInfo.name);
this.filter = filter;
- this.ranking = ranking;
- this.patternStrings = patterns;
+ this.filterInfo = filterInfo;
+
+ // Compose a single array of all patterns & regexs the filter must represent...
+ String[] patterns = getFilterPatterns(filterInfo);
+
this.patterns = new Pattern[patterns.length];
for (int i = 0; i < patterns.length; i++)
{
this.patterns[i] = Pattern.compile(patterns[i]);
}
+
+ setInitParams(filterInfo.initParams);
}
public int compareTo(FilterHandler other)
{
- if (other.ranking == this.ranking)
+ int thisRanking = this.filterInfo.ranking;
+ int thatRanking = other.filterInfo.ranking;
+
+ int r = (thatRanking - thisRanking);
+ if (r == 0)
{
- return 0;
+ r = getId() - other.getId();
}
-
- return (other.ranking > this.ranking) ? 1 : -1;
+ return r;
}
@Override
@@ -71,33 +82,34 @@ public final class FilterHandler extends
return this.filter;
}
- @Override
- public Pattern[] getPatterns()
- {
- return patterns;
- }
-
- public String[] getPatternStrings()
+ public FilterInfo getFilterInfo()
{
- return patternStrings;
+ return this.filterInfo;
}
- public int getRanking()
+ @Override
+ public Pattern[] getPatterns()
{
- return ranking;
+ return patterns;
}
- public void handle(HttpServletRequest req, HttpServletResponse res, FilterChain chain) throws ServletException, IOException
+ public boolean handle(HttpServletRequest req, HttpServletResponse res, FilterChain chain) throws ServletException, IOException
{
- final boolean matches = matches(req.getPathInfo());
- if (matches)
+ if (getContext().handleSecurity(req, res))
{
- doHandle(req, res, chain);
+ this.filter.doFilter(req, res, chain);
+
+ return true;
}
- else
+
+ // FELIX-3988: If the response is not yet committed and still has the default
+ // status, we're going to override this and send an error instead.
+ if (!res.isCommitted() && res.getStatus() == SC_OK)
{
- chain.doFilter(req, res);
+ res.sendError(SC_FORBIDDEN);
}
+
+ return false;
}
@Override
@@ -106,43 +118,29 @@ public final class FilterHandler extends
this.filter.init(new FilterConfigImpl(getName(), getContext(), getInitParams()));
}
- public boolean matches(String uri)
+ @Override
+ protected Object getSubject()
{
- // assume root if uri is null
- if (uri == null)
- {
- uri = "/";
- }
- for (Pattern p : this.patterns)
- {
- if (p.matcher(uri).matches())
- {
- return true;
- }
- }
- return false;
+ return this.filter;
}
- final void doHandle(HttpServletRequest req, HttpServletResponse res, FilterChain chain) throws ServletException, IOException
+ private static String[] getFilterPatterns(FilterInfo filterInfo)
{
- if (getContext().handleSecurity(req, res))
+ List<String> result = new ArrayList<String>();
+ if (filterInfo.patterns != null)
{
- this.filter.doFilter(req, res, chain);
+ for (int i = 0; i < filterInfo.patterns.length; i++)
+ {
+ result.add(convertToRegEx(filterInfo.patterns[i]));
+ }
}
- else
+ if (filterInfo.regexs != null)
{
- // FELIX-3988: If the response is not yet committed and still has the default
- // status, we're going to override this and send an error instead.
- if (!res.isCommitted() && res.getStatus() == SC_OK)
+ for (int i = 0; i < filterInfo.regexs.length; i++)
{
- res.sendError(SC_FORBIDDEN);
+ result.add(filterInfo.regexs[i]);
}
}
- }
-
- @Override
- protected Object getSubject()
- {
- return this.filter;
+ return result.toArray(new String[result.size()]);
}
}
Modified: felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/handler/HandlerMapping.java
URL: http://svn.apache.org/viewvc/felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/handler/HandlerMapping.java?rev=1607850&r1=1607849&r2=1607850&view=diff
==============================================================================
--- felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/handler/HandlerMapping.java (original)
+++ felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/handler/HandlerMapping.java Fri Jul 4 13:25:21 2014
@@ -121,8 +121,8 @@ public class HandlerMapping<V extends Ab
}
}
- private final SortedMap<Pattern, V> exactMap;
- private final SortedMap<Pattern, V> wildcardMap;
+ private final SortedMap<Pattern, List<V>> exactMap;
+ private final SortedMap<Pattern, List<V>> wildcardMap;
private final Set<V> all;
/**
@@ -140,8 +140,8 @@ public class HandlerMapping<V extends Ab
*/
public HandlerMapping(Collection<V> elements)
{
- this.exactMap = new TreeMap<Pattern, V>(new PatternComparator());
- this.wildcardMap = new TreeMap<Pattern, V>(new PatternComparator());
+ this.exactMap = new TreeMap<Pattern, List<V>>(new PatternComparator());
+ this.wildcardMap = new TreeMap<Pattern, List<V>>(new PatternComparator());
this.all = new HashSet<V>(elements);
for (V element : elements)
@@ -150,11 +150,29 @@ public class HandlerMapping<V extends Ab
{
if (isWildcardPattern(pattern))
{
- this.wildcardMap.put(pattern, element);
+ List<V> vs = this.wildcardMap.get(pattern);
+ if (vs == null)
+ {
+ vs = new ArrayList<V>();
+ this.wildcardMap.put(pattern, vs);
+ }
+ if (!vs.contains(element))
+ {
+ vs.add(element);
+ }
}
else
{
- this.exactMap.put(pattern, element);
+ List<V> vs = this.exactMap.get(pattern);
+ if (vs == null)
+ {
+ vs = new ArrayList<V>();
+ this.exactMap.put(pattern, vs);
+ }
+ if (!vs.contains(element))
+ {
+ vs.add(element);
+ }
}
}
}
@@ -201,6 +219,29 @@ public class HandlerMapping<V extends Ab
}
/**
+ * Returns the (first) handler identified by the given name.
+ * @param name the name of the handler to return, can be <code>null</code> in which case this method will return <code>null</code>.
+ * @return the element with the given name, or <code>null</code> if not found, or the given argument was <code>null</code>.
+ */
+ public V getByName(String name)
+ {
+ if (name == null)
+ {
+ return null;
+ }
+
+ for (V element : this.all)
+ {
+ if (name.equals(element.getName()))
+ {
+ return element;
+ }
+ }
+
+ return null;
+ }
+
+ /**
* Provides information on whether there are elements mapped or not.
*
* @return <code>true</code> if there is at least one element mapped, <code>false</code> otherwise.
@@ -225,16 +266,19 @@ public class HandlerMapping<V extends Ab
List<V> result = new ArrayList<V>();
// Look for exact matches only, that is, those patterns without wildcards...
- for (Entry<Pattern, V> entry : this.exactMap.entrySet())
+ for (Entry<Pattern, List<V>> entry : this.exactMap.entrySet())
{
Matcher matcher = entry.getKey().matcher(path);
// !!! we should always match the *entire* pattern, instead of the longest prefix...
if (matcher.matches())
{
- V v = entry.getValue();
- if (!result.contains(v))
+ List<V> vs = entry.getValue();
+ for (V v : vs)
{
- result.add(v);
+ if (!result.contains(v))
+ {
+ result.add(v);
+ }
if (firstOnly)
{
@@ -245,15 +289,18 @@ public class HandlerMapping<V extends Ab
}
// Try to apply the wildcard patterns...
- for (Entry<Pattern, V> entry : this.wildcardMap.entrySet())
+ for (Entry<Pattern, List<V>> entry : this.wildcardMap.entrySet())
{
Matcher matcher = entry.getKey().matcher(path);
if (matcher.find(0))
{
- V v = entry.getValue();
- if (!result.contains(v))
+ List<V> vs = entry.getValue();
+ for (V v : vs)
{
- result.add(v);
+ if (!result.contains(v))
+ {
+ result.add(v);
+ }
if (firstOnly)
{
@@ -262,6 +309,9 @@ public class HandlerMapping<V extends Ab
}
}
}
+
+ // Make sure the results are properly sorted...
+ Collections.sort(result);
return result;
}
Modified: felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/handler/HandlerRegistry.java
URL: http://svn.apache.org/viewvc/felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/handler/HandlerRegistry.java?rev=1607850&r1=1607849&r2=1607850&view=diff
==============================================================================
--- felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/handler/HandlerRegistry.java (original)
+++ felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/handler/HandlerRegistry.java Fri Jul 4 13:25:21 2014
@@ -16,14 +16,18 @@
*/
package org.apache.felix.http.base.internal.handler;
+import java.util.ArrayList;
+import java.util.Arrays;
import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
import java.util.Map;
+import javax.servlet.DispatcherType;
import javax.servlet.Filter;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
-import org.apache.felix.http.base.internal.util.PatternUtil;
import org.osgi.service.http.NamespaceException;
public final class HandlerRegistry
@@ -62,7 +66,7 @@ public final class HandlerRegistry
{
throw new ServletException("Servlet instance " + handler.getName() + " already registered");
}
- for (String pattern : handler.getPatternStrings())
+ for (String pattern : handler.getServletInfo().patterns)
{
if (this.servletPatternMap.containsKey(pattern))
{
@@ -77,19 +81,48 @@ public final class HandlerRegistry
updateServletMapping();
}
- public HandlerMapping<FilterHandler> getFilterMapping()
+ public FilterHandler[] getFilterHandlers(ServletHandler servletHandler, DispatcherType dispatcherType, String requestURI)
{
- return this.filterMapping;
+ // See Servlet 3.0 specification, section 6.2.4...
+ List<FilterHandler> result = new ArrayList<FilterHandler>();
+ result.addAll(this.filterMapping.getAllMatches(requestURI));
+
+ // TODO this is not the most efficient/fastest way of doing this...
+ Iterator<FilterHandler> iter = result.iterator();
+ while (iter.hasNext())
+ {
+ if (!referencesDispatcherType(iter.next(), dispatcherType))
+ {
+ iter.remove();
+ }
+ }
+
+ String servletName = (servletHandler != null) ? servletHandler.getName() : null;
+ // TODO this is not the most efficient/fastest way of doing this...
+ for (FilterHandler filterHandler : this.filterMapping.getAllElements())
+ {
+ if (referencesServletByName(filterHandler, servletName))
+ {
+ result.add(filterHandler);
+ }
+ }
+
+ return result.toArray(new FilterHandler[result.size()]);
}
public synchronized Servlet getServletByAlias(String alias)
{
- return this.servletPatternMap.get(PatternUtil.convertToRegEx(alias));
+ return this.servletPatternMap.get(alias);
+ }
+
+ public ServletHandler getServletHandlerByName(String name)
+ {
+ return this.servletMapping.getByName(name);
}
- public HandlerMapping<ServletHandler> getServletMapping()
+ public ServletHandler getServletHander(String requestURI)
{
- return this.servletMapping;
+ return this.servletMapping.getBestMatch(requestURI);
}
public synchronized void removeAll()
@@ -132,7 +165,7 @@ public final class HandlerRegistry
{
updateServletMapping();
- for (String pattern : handler.getPatternStrings())
+ for (String pattern : handler.getServletInfo().patterns)
{
this.servletPatternMap.remove(pattern);
}
@@ -144,6 +177,25 @@ public final class HandlerRegistry
}
}
+ private boolean referencesDispatcherType(FilterHandler handler, DispatcherType dispatcherType)
+ {
+ return Arrays.asList(handler.getFilterInfo().dispatcher).contains(dispatcherType);
+ }
+
+ private boolean referencesServletByName(FilterHandler handler, String servletName)
+ {
+ if (servletName == null)
+ {
+ return false;
+ }
+ String[] names = handler.getFilterInfo().servletNames;
+ if (names != null && names.length > 0)
+ {
+ return Arrays.asList(names).contains(servletName);
+ }
+ return false;
+ }
+
private void updateFilterMapping()
{
this.filterMapping = new HandlerMapping<FilterHandler>(this.filterMap.values());
Modified: felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/handler/HttpServicePlugin.java
URL: http://svn.apache.org/viewvc/felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/handler/HttpServicePlugin.java?rev=1607850&r1=1607849&r2=1607850&view=diff
==============================================================================
--- felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/handler/HttpServicePlugin.java (original)
+++ felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/handler/HttpServicePlugin.java Fri Jul 4 13:25:21 2014
@@ -92,8 +92,8 @@ public class HttpServicePlugin extends H
for (FilterHandler filter : filters)
{
pw.println("<tr class=\"" + rowClass + " ui-state-default\">");
- pw.println("<td>" + Arrays.toString(filter.getPatternStrings()) + "</td>");
- pw.println("<td>" + filter.getFilter().getClass().getName() + "(" + filter.getRanking() + ")" + "</td>");
+// pw.println("<td>" + Arrays.toString(filter.getPatternStrings()) + "</td>"); // XXX
+// pw.println("<td>" + filter.getFilter().getClass().getName() + "(" + filter.getRanking() + ")" + "</td>");
printBundleDetails(pw, filter.getFilter().getClass());
@@ -126,8 +126,8 @@ public class HttpServicePlugin extends H
{
pw.println("<tr class=\"" + rowClass + " ui-state-default\">");
- pw.println("<td>" + Arrays.toString(servlet.getPatternStrings()) + "</td>");
- pw.println("<td>" + servlet.getServlet().getClass().getName() + "</td>");
+// pw.println("<td>" + Arrays.toString(servlet.getPatternStrings()) + "</td>"); // XXX
+// pw.println("<td>" + servlet.getServlet().getClass().getName() + "</td>");
printBundleDetails(pw, servlet.getServlet().getClass());
@@ -155,7 +155,7 @@ public class HttpServicePlugin extends H
ServletHandler[] servlets = new ServletHandler[0]; // XXX was: registry.getServlets();
for (ServletHandler servlet : servlets)
{
- pw.println("Patterns : " + Arrays.toString(servlet.getPatternStrings()));
+// pw.println("Patterns : " + Arrays.toString(servlet.getPatternStrings())); // XXX
addSpace(pw, 1);
pw.println("Class : " + servlet.getServlet().getClass().getName());
addSpace(pw, 1);
@@ -169,9 +169,9 @@ public class HttpServicePlugin extends H
Arrays.sort(filters);
for (FilterHandler filter : filters)
{
- pw.println("Patterns : " + Arrays.toString(filter.getPatternStrings()));
+// pw.println("Patterns : " + Arrays.toString(filter.getPatternStrings())); // XXX
addSpace(pw, 1);
- pw.println("Ranking : " + filter.getRanking());
+// pw.println("Ranking : " + filter.getRanking()); // XXX
addSpace(pw, 1);
pw.println("Class : " + filter.getFilter().getClass().getName());
addSpace(pw, 1);
Modified: felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/handler/ServletHandler.java
URL: http://svn.apache.org/viewvc/felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/handler/ServletHandler.java?rev=1607850&r1=1607849&r2=1607850&view=diff
==============================================================================
--- felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/handler/ServletHandler.java (original)
+++ felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/handler/ServletHandler.java Fri Jul 4 13:25:21 2014
@@ -16,275 +16,76 @@
*/
package org.apache.felix.http.base.internal.handler;
-import static javax.servlet.RequestDispatcher.FORWARD_CONTEXT_PATH;
-import static javax.servlet.RequestDispatcher.FORWARD_PATH_INFO;
-import static javax.servlet.RequestDispatcher.FORWARD_QUERY_STRING;
-import static javax.servlet.RequestDispatcher.FORWARD_REQUEST_URI;
-import static javax.servlet.RequestDispatcher.FORWARD_SERVLET_PATH;
-import static javax.servlet.RequestDispatcher.INCLUDE_CONTEXT_PATH;
-import static javax.servlet.RequestDispatcher.INCLUDE_PATH_INFO;
-import static javax.servlet.RequestDispatcher.INCLUDE_QUERY_STRING;
-import static javax.servlet.RequestDispatcher.INCLUDE_REQUEST_URI;
-import static javax.servlet.RequestDispatcher.INCLUDE_SERVLET_PATH;
import static javax.servlet.http.HttpServletResponse.SC_FORBIDDEN;
import static javax.servlet.http.HttpServletResponse.SC_OK;
-import static org.apache.felix.http.base.internal.util.UriUtils.concat;
-import static org.apache.felix.http.base.internal.util.UriUtils.relativePath;
+import static org.apache.felix.http.base.internal.util.PatternUtil.convertToRegEx;
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
-import javax.servlet.DispatcherType;
-import javax.servlet.RequestDispatcher;
import javax.servlet.Servlet;
import javax.servlet.ServletException;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
+import org.apache.felix.http.api.ServletInfo;
import org.apache.felix.http.base.internal.context.ExtServletContext;
/**
* @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
*/
-public class ServletHandler extends AbstractHandler implements Comparable<ServletHandler>
+public class ServletHandler extends AbstractHandler<ServletHandler>
{
- private class RequestDispatcherImpl implements RequestDispatcher
- {
- final String servletPath;
- final String requestURI;
- final String pathInfo;
- final String query;
- final boolean named;
-
- public RequestDispatcherImpl()
- {
- this.servletPath = null;
- this.requestURI = null;
- this.pathInfo = null;
- this.query = null;
- this.named = true;
- }
-
- public RequestDispatcherImpl(String uri, String servletPath, String pathInContext, String query)
- {
- this.requestURI = uri;
- this.servletPath = servletPath;
- this.pathInfo = relativePath(servletPath, pathInContext);
- this.query = query;
- this.named = false;
- }
-
- public void forward(ServletRequest req, ServletResponse res) throws ServletException, IOException
- {
- if (res.isCommitted())
- {
- throw new ServletException("Response has been committed");
- }
- else
- {
- // See section 9.4 of Servlet 3.0 spec
- res.resetBuffer();
- }
-
- // Since we're already created this RequestDispatcher for *this* servlet handler, we do not need to
- // recheck whether its patch matches, but instead can directly handle the forward-request...
- doHandle(this.pathInfo, new ServletRequestWrapper((HttpServletRequest) req, this, DispatcherType.FORWARD), (HttpServletResponse) res);
-
- // After a forward has taken place, the results should be committed,
- // see section 9.4 of Servlet 3.0 spec...
- if (!req.isAsyncStarted())
- {
- res.flushBuffer();
- res.getWriter().close();
- }
- }
-
- public void include(ServletRequest req, ServletResponse res) throws ServletException, IOException
- {
- // Since we're already created this RequestDispatcher for *this* servlet handler, we do not need to
- // recheck whether its patch matches, but instead can directly handle the include-request...
- doHandle(this.pathInfo, new ServletRequestWrapper((HttpServletRequest) req, this, DispatcherType.INCLUDE), (HttpServletResponse) res);
- }
-
- boolean isNamedDispatcher()
- {
- return this.named;
- }
- }
-
- private static class ServletRequestWrapper extends HttpServletRequestWrapper
- {
- private final RequestDispatcherImpl dispatcher;
- private final DispatcherType type;
-
- public ServletRequestWrapper(HttpServletRequest req, RequestDispatcherImpl dispatcher, DispatcherType type)
- {
- super(req);
- this.dispatcher = dispatcher;
- this.type = type;
- }
-
- @Override
- public Object getAttribute(String name)
- {
- HttpServletRequest request = (HttpServletRequest) getRequest();
- if (isInclusionDispatcher())
- {
- if (INCLUDE_REQUEST_URI.equals(name))
- {
- return concat(request.getContextPath(), this.dispatcher.requestURI);
- }
- else if (INCLUDE_CONTEXT_PATH.equals(name))
- {
- return request.getContextPath();
- }
- else if (INCLUDE_SERVLET_PATH.equals(name))
- {
- return this.dispatcher.servletPath;
- }
- else if (INCLUDE_PATH_INFO.equals(name))
- {
- return this.dispatcher.pathInfo;
- }
- else if (INCLUDE_QUERY_STRING.equals(name))
- {
- return this.dispatcher.query;
- }
- }
- else if (isForwardingDispatcher())
- {
- // NOTE: the forward.* attributes *always* yield the *original* values...
- if (FORWARD_REQUEST_URI.equals(name))
- {
- return super.getRequestURI();
- }
- else if (FORWARD_CONTEXT_PATH.equals(name))
- {
- return request.getContextPath();
- }
- else if (FORWARD_SERVLET_PATH.equals(name))
- {
- return super.getServletPath();
- }
- else if (FORWARD_PATH_INFO.equals(name))
- {
- return super.getPathInfo();
- }
- else if (FORWARD_QUERY_STRING.equals(name))
- {
- return super.getQueryString();
- }
- }
-
- return super.getAttribute(name);
- }
-
- @Override
- public DispatcherType getDispatcherType()
- {
- return this.type;
- }
-
- @Override
- public String getPathInfo()
- {
- if (isForwardingDispatcher())
- {
- return this.dispatcher.pathInfo;
- }
- return super.getPathInfo();
- }
-
- @Override
- public String getRequestURI()
- {
- if (isForwardingDispatcher())
- {
- return concat(getContextPath(), this.dispatcher.requestURI);
- }
- return super.getRequestURI();
- }
-
- @Override
- public String getServletPath()
- {
- if (isForwardingDispatcher())
- {
- return this.dispatcher.servletPath;
- }
- return super.getServletPath();
- }
-
- @Override
- public String toString()
- {
- return getClass().getSimpleName() + "->" + super.getRequest();
- }
-
- private boolean isForwardingDispatcher()
- {
- return DispatcherType.FORWARD == this.type && !this.dispatcher.isNamedDispatcher();
- }
-
- private boolean isInclusionDispatcher()
- {
- return DispatcherType.INCLUDE == this.type && !this.dispatcher.isNamedDispatcher();
- }
- }
-
- private final String[] patternStrings;
- private final Pattern[] patterns;
private final Servlet servlet;
+ private final ServletInfo servletInfo;
+ private final Pattern[] patterns;
- public ServletHandler(ExtServletContext context, Servlet servlet, String[] patterns, String name)
+ public ServletHandler(ExtServletContext context, Servlet servlet, ServletInfo servletInfo)
{
- super(context, name);
+ super(context, servletInfo.name);
this.servlet = servlet;
- this.patternStrings = patterns;
+ this.servletInfo = servletInfo;
+
+ String[] patterns = this.servletInfo.patterns;
+
this.patterns = new Pattern[patterns.length];
for (int i = 0; i < patterns.length; i++)
{
- this.patterns[i] = Pattern.compile(patterns[i]);
+ this.patterns[i] = Pattern.compile(convertToRegEx(patterns[i]));
}
+
+ setInitParams(servletInfo.initParams);
}
public int compareTo(ServletHandler other)
{
- return other.getId() - this.getId(); // XXX
+ return getId() - other.getId();
}
- public RequestDispatcher createNamedRequestDispatcher()
+ @Override
+ public void destroy()
{
- return new RequestDispatcherImpl();
+ this.servlet.destroy();
}
- /**
- * Creates a request dispatcher based on this handler if, and only if, the given pathInContext attribute matches any of the patterns in this handler.
- *
- * @param path
- * @param pathInContext the path in context, that should be matched by this handler, cannot be <code>null</code>;
- * @param query the optional query-part of the request URL, may be <code>null</code>.
- * @return a new {@link RequestDispatcher} instance, or <code>null</code> if this handler cannot handle the given request.
- */
- public RequestDispatcher createRequestDispatcher(String path, String pathInContext, String query)
+ public String determineServletPath(String uri)
{
- // Determine which servletPath we should use...
- String servletPath = determineServletPath(pathInContext);
- if (servletPath != null)
+ if (uri == null)
{
- return new RequestDispatcherImpl(path, servletPath, pathInContext, query);
+ uri = "/";
}
- return null;
- }
- @Override
- public void destroy()
- {
- this.servlet.destroy();
+ // Patterns are sorted on length in descending order, so we should get the longest match first...
+ for (int i = 0; i < this.patterns.length; i++)
+ {
+ Matcher matcher = this.patterns[i].matcher(uri);
+ if (matcher.find(0))
+ {
+ return matcher.groupCount() > 0 ? matcher.group(1) : matcher.group();
+ }
+ }
+ return null;
}
@Override
@@ -293,43 +94,33 @@ public class ServletHandler extends Abst
return patterns;
}
- public String[] getPatternStrings()
+ public Servlet getServlet()
{
- return patternStrings;
+ return this.servlet;
}
- public Servlet getServlet()
+ public ServletInfo getServletInfo()
{
- return this.servlet;
+ return this.servletInfo;
}
public boolean handle(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException
{
- String path;
- if (DispatcherType.INCLUDE == req.getDispatcherType())
- {
- path = (String) req.getAttribute(INCLUDE_SERVLET_PATH);
- }
- else if (DispatcherType.FORWARD == req.getDispatcherType())
- {
- path = (String) req.getAttribute(FORWARD_SERVLET_PATH);
- }
- else if (DispatcherType.ASYNC == req.getDispatcherType())
- {
- path = (String) req.getAttribute("javax.servlet.async.path_info");
- }
- else
+ if (getContext().handleSecurity(req, res))
{
- path = req.getPathInfo();
+ this.servlet.service(req, res);
+
+ return true;
}
- final boolean matches = matches(path);
- if (matches)
+ // FELIX-3988: If the response is not yet committed and still has the default
+ // status, we're going to override this and send an error instead.
+ if (!res.isCommitted() && res.getStatus() == SC_OK)
{
- doHandle(path, req, res);
+ res.sendError(SC_FORBIDDEN);
}
- return matches;
+ return false;
}
@Override
@@ -338,57 +129,9 @@ public class ServletHandler extends Abst
this.servlet.init(new ServletConfigImpl(getName(), getContext(), getInitParams()));
}
- public boolean matches(String uri)
- {
- return determineServletPath(uri) != null;
- }
-
- final void doHandle(String path, HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException
- {
- // Only wrap the original ServletRequest in case we're handling plain requests,
- // not inclusions or forwards from servlets. Should solve FELIX-2774 and FELIX-3054...
- if (DispatcherType.REQUEST == req.getDispatcherType())
- {
- String alias = determineServletPath(path);
- req = new ServletHandlerRequest(req, getContext(), alias);
- }
-
- if (getContext().handleSecurity(req, res))
- {
- this.servlet.service(req, res);
- }
- else
- {
- // FELIX-3988: If the response is not yet committed and still has the default
- // status, we're going to override this and send an error instead.
- if (!res.isCommitted() && res.getStatus() == SC_OK)
- {
- res.sendError(SC_FORBIDDEN);
- }
- }
- }
-
@Override
protected Object getSubject()
{
return this.servlet;
}
-
- private String determineServletPath(String uri)
- {
- if (uri == null)
- {
- uri = "/";
- }
-
- for (int i = 0; i < this.patterns.length; i++)
- {
- Matcher matcher = this.patterns[i].matcher(uri);
- if (matcher.find(0))
- {
- return matcher.groupCount() > 0 ? matcher.group(1) : matcher.group();
- }
- }
- return null;
- }
}
Modified: felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/service/HttpServiceImpl.java
URL: http://svn.apache.org/viewvc/felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/service/HttpServiceImpl.java?rev=1607850&r1=1607849&r2=1607850&view=diff
==============================================================================
--- felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/service/HttpServiceImpl.java (original)
+++ felix/sandbox/http-rfc189/base/src/main/java/org/apache/felix/http/base/internal/service/HttpServiceImpl.java Fri Jul 4 13:25:21 2014
@@ -16,14 +16,10 @@
*/
package org.apache.felix.http.base.internal.service;
-import static org.apache.felix.http.base.internal.util.PatternUtil.convertToRegEx;
-
-import java.util.ArrayList;
import java.util.Dictionary;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.HashSet;
-import java.util.List;
import java.util.Map;
import javax.servlet.Filter;
@@ -78,6 +74,11 @@ public final class HttpServiceImpl imple
return result;
}
+ static <T> boolean isEmpty(T[] array)
+ {
+ return array == null || array.length < 1;
+ }
+
static boolean isEmpty(String str)
{
return str == null || "".equals(str.trim());
@@ -98,28 +99,20 @@ public final class HttpServiceImpl imple
{
throw new IllegalArgumentException("FilterInfo cannot be null!");
}
- if ((filterInfo.patterns == null || filterInfo.patterns.length < 1) && (filterInfo.regexs == null || filterInfo.regexs.length < 1))
+ if (isEmpty(filterInfo.patterns) && isEmpty(filterInfo.regexs) && isEmpty(filterInfo.servletNames))
{
- throw new IllegalArgumentException("FilterInfo must have at least one pattern or regex!");
+ throw new IllegalArgumentException("FilterInfo must have at least one pattern or regex, or provide at least one servlet name!");
}
-
- String filterName = filterInfo.name;
- if (isEmpty(filterName))
+ if (isEmpty(filterInfo.name))
{
- filterName = filter.getClass().getName();
+ filterInfo.name = filter.getClass().getName();
}
- Map<String, String> initParams = filterInfo.initParams;
ExtServletContext servletContext = getServletContext(filterInfo.context);
- int ranking = Math.max(0, filterInfo.ranking);
-
- // Compose a single array of all patterns & regexs the filter must represent...
- String[] patterns = getFilterPatterns(filterInfo);
try
{
- FilterHandler handler = new FilterHandler(servletContext, filter, patterns, ranking, filterName);
- handler.setInitParams(initParams);
+ FilterHandler handler = new FilterHandler(servletContext, filter, filterInfo);
synchronized (this)
{
@@ -137,7 +130,7 @@ public final class HttpServiceImpl imple
}
else
{
- throw new ServletException("Failed to register filter " + filterName, e);
+ throw new ServletException("Failed to register filter " + filterInfo.name, e);
}
}
}
@@ -185,27 +178,16 @@ public final class HttpServiceImpl imple
{
throw new IllegalArgumentException("ServletInfo must at least have one pattern!");
}
-
- String servletName = servletInfo.name;
- if (isEmpty(servletName))
+ if (isEmpty(servletInfo.name))
{
- servletName = servlet.getClass().getName();
+ servletInfo.name = servlet.getClass().getName();
}
- Map<String, String> initParams = servletInfo.initParams;
ExtServletContext servletContext = getServletContext(servletInfo.context);
- // Compose a single array of all patterns/aliases the servlet must represent...
- String[] patterns = new String[servletInfo.patterns.length];
- for (int i = 0; i < servletInfo.patterns.length; i++)
- {
- patterns[i] = convertToRegEx(servletInfo.patterns[i]);
- }
-
try
{
- ServletHandler handler = new ServletHandler(servletContext, servlet, patterns, servletName);
- handler.setInitParams(initParams);
+ ServletHandler handler = new ServletHandler(servletContext, servlet, servletInfo);
synchronized (this)
{
@@ -227,7 +209,7 @@ public final class HttpServiceImpl imple
}
else
{
- throw new ServletException("Failed to register servlet " + servletName, e);
+ throw new ServletException("Failed to register servlet " + servletInfo.name, e);
}
}
}
@@ -279,26 +261,6 @@ public final class HttpServiceImpl imple
unregisterServlet(servlet, true);
}
- private String[] getFilterPatterns(FilterInfo filterInfo)
- {
- List<String> result = new ArrayList<String>();
- if (filterInfo.patterns != null)
- {
- for (int i = 0; i < filterInfo.patterns.length; i++)
- {
- result.add(convertToRegEx(filterInfo.patterns[i]));
- }
- }
- if (filterInfo.regexs != null)
- {
- for (int i = 0; i < filterInfo.regexs.length; i++)
- {
- result.add(filterInfo.regexs[i]);
- }
- }
- return result.toArray(new String[result.size()]);
- }
-
private ExtServletContext getServletContext(HttpContext context)
{
if (context == null)
Modified: felix/sandbox/http-rfc189/base/src/test/java/org/apache/felix/http/base/internal/handler/FilterHandlerTest.java
URL: http://svn.apache.org/viewvc/felix/sandbox/http-rfc189/base/src/test/java/org/apache/felix/http/base/internal/handler/FilterHandlerTest.java?rev=1607850&r1=1607849&r2=1607850&view=diff
==============================================================================
--- felix/sandbox/http-rfc189/base/src/test/java/org/apache/felix/http/base/internal/handler/FilterHandlerTest.java (original)
+++ felix/sandbox/http-rfc189/base/src/test/java/org/apache/felix/http/base/internal/handler/FilterHandlerTest.java Fri Jul 4 13:25:21 2014
@@ -20,20 +20,20 @@ import static javax.servlet.http.HttpSer
import static javax.servlet.http.HttpServletResponse.SC_OK;
import static javax.servlet.http.HttpServletResponse.SC_PAYMENT_REQUIRED;
import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertFalse;
-import static org.junit.Assert.assertTrue;
import static org.mockito.Matchers.any;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import javax.servlet.DispatcherType;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+import org.apache.felix.http.api.FilterInfo;
import org.junit.Before;
import org.junit.Test;
@@ -53,9 +53,16 @@ public class FilterHandlerTest extends A
{
FilterHandler h1 = createHandler(0, "a");
FilterHandler h2 = createHandler(10, "b");
+ FilterHandler h3 = createHandler(10, "c");
- assertEquals(1, h1.compareTo(h2));
- assertEquals(-1, h2.compareTo(h1));
+ assertEquals(0, h1.compareTo(h1));
+
+ assertEquals(10, h1.compareTo(h2));
+ assertEquals(-10, h2.compareTo(h1));
+
+ // h2 is actually registered first, so should be called first...
+ assertEquals(-1, h2.compareTo(h3));
+ assertEquals(1, h3.compareTo(h2));
}
@Test
@@ -70,12 +77,12 @@ public class FilterHandlerTest extends A
public void testHandleFound() throws Exception
{
FilterHandler h1 = createHandler(0, "/a");
- HttpServletRequest req = mock(HttpServletRequest.class);
- HttpServletResponse res = mock(HttpServletResponse.class);
+ HttpServletRequest req = createServletRequest();
+ HttpServletResponse res = createServletResponse();
FilterChain chain = mock(FilterChain.class);
when(this.context.handleSecurity(req, res)).thenReturn(true);
- when(req.getPathInfo()).thenReturn("/a");
+ when(req.getRequestURI()).thenReturn("/a");
h1.handle(req, res, chain);
verify(this.filter).doFilter(req, res, chain);
@@ -86,12 +93,12 @@ public class FilterHandlerTest extends A
public void testHandleFoundContextRoot() throws Exception
{
FilterHandler h1 = createHandler(0, "/");
- HttpServletRequest req = mock(HttpServletRequest.class);
- HttpServletResponse res = mock(HttpServletResponse.class);
+ HttpServletRequest req = createServletRequest();
+ HttpServletResponse res = createServletResponse();
FilterChain chain = mock(FilterChain.class);
when(this.context.handleSecurity(req, res)).thenReturn(true);
- when(req.getPathInfo()).thenReturn(null);
+ when(req.getRequestURI()).thenReturn(null);
h1.handle(req, res, chain);
verify(this.filter).doFilter(req, res, chain);
@@ -105,11 +112,11 @@ public class FilterHandlerTest extends A
public void testHandleFoundForbidden() throws Exception
{
FilterHandler h1 = createHandler(0, "/a");
- HttpServletRequest req = mock(HttpServletRequest.class);
- HttpServletResponse res = mock(HttpServletResponse.class);
+ HttpServletRequest req = createServletRequest();
+ HttpServletResponse res = createServletResponse();
FilterChain chain = mock(FilterChain.class);
- when(req.getPathInfo()).thenReturn("/a");
+ when(req.getRequestURI()).thenReturn("/a");
// Default behaviour: uncomitted response and default status code...
when(res.isCommitted()).thenReturn(false);
when(res.getStatus()).thenReturn(SC_OK);
@@ -130,11 +137,11 @@ public class FilterHandlerTest extends A
public void testHandleFoundForbiddenCommittedOwnResponse() throws Exception
{
FilterHandler h1 = createHandler(0, "/a");
- HttpServletRequest req = mock(HttpServletRequest.class);
- HttpServletResponse res = mock(HttpServletResponse.class);
+ HttpServletRequest req = createServletRequest();
+ HttpServletResponse res = createServletResponse();
FilterChain chain = mock(FilterChain.class);
- when(req.getPathInfo()).thenReturn("/a");
+ when(req.getRequestURI()).thenReturn("/a");
// Simulate an already committed response...
when(res.isCommitted()).thenReturn(true);
when(res.getStatus()).thenReturn(SC_OK);
@@ -156,11 +163,11 @@ public class FilterHandlerTest extends A
public void testHandleFoundForbiddenCustomStatusCode() throws Exception
{
FilterHandler h1 = createHandler(0, "/a");
- HttpServletRequest req = mock(HttpServletRequest.class);
- HttpServletResponse res = mock(HttpServletResponse.class);
+ HttpServletRequest req = createServletRequest();
+ HttpServletResponse res = createServletResponse();
FilterChain chain = mock(FilterChain.class);
- when(req.getPathInfo()).thenReturn("/a");
+ when(req.getRequestURI()).thenReturn("/a");
// Simulate an uncommitted response with a non-default status code...
when(res.isCommitted()).thenReturn(false);
when(res.getStatus()).thenReturn(SC_PAYMENT_REQUIRED);
@@ -179,30 +186,30 @@ public class FilterHandlerTest extends A
public void testHandleNotFound() throws Exception
{
FilterHandler h1 = createHandler(0, "/a");
- HttpServletRequest req = mock(HttpServletRequest.class);
- HttpServletResponse res = mock(HttpServletResponse.class);
+ HttpServletRequest req = createServletRequest();
+ HttpServletResponse res = createServletResponse();
FilterChain chain = mock(FilterChain.class);
- when(req.getPathInfo()).thenReturn("/");
+ when(req.getRequestURI()).thenReturn("/");
h1.handle(req, res, chain);
verify(this.filter, never()).doFilter(req, res, chain);
- verify(chain).doFilter(req, res);
+ verify(chain, never()).doFilter(req, res);
}
@Test
public void testHandleNotFoundContextRoot() throws Exception
{
FilterHandler h1 = createHandler(0, "/a");
- HttpServletRequest req = mock(HttpServletRequest.class);
- HttpServletResponse res = mock(HttpServletResponse.class);
+ HttpServletRequest req = createServletRequest();
+ HttpServletResponse res = createServletResponse();
FilterChain chain = mock(FilterChain.class);
- when(req.getPathInfo()).thenReturn(null);
+ when(req.getRequestURI()).thenReturn(null);
h1.handle(req, res, chain);
verify(this.filter, never()).doFilter(req, res, chain);
- verify(chain).doFilter(req, res);
+ verify(chain, never()).doFilter(req, res);
}
@Test
@@ -213,30 +220,6 @@ public class FilterHandlerTest extends A
verify(this.filter).init(any(FilterConfig.class));
}
- @Test
- public void testMatches()
- {
- FilterHandler h1 = createHandler(0, "/a/b");
- FilterHandler h2 = createHandler(0, "/a/b/.+");
- FilterHandler h3 = createHandler(0, "/");
- FilterHandler h4 = createHandler(0, "/.*");
-
- assertFalse(h1.matches(null));
- assertFalse(h1.matches("/a"));
- assertTrue(h1.matches("/a/b"));
- assertFalse(h1.matches("/a/b/c"));
- assertFalse(h2.matches(null));
- assertFalse(h1.matches("/a"));
- assertTrue(h2.matches("/a/b/c"));
- assertFalse(h2.matches("/a/b/"));
- assertTrue(h3.matches(null));
- assertTrue(h3.matches("/"));
- assertFalse(h3.matches("/a/b/"));
- assertTrue(h4.matches(null));
- assertTrue(h4.matches("/"));
- assertTrue(h4.matches("/a/b/"));
- }
-
protected AbstractHandler createHandler()
{
return createHandler(0, "dummy");
@@ -244,6 +227,27 @@ public class FilterHandlerTest extends A
private FilterHandler createHandler(int ranking, String... pattern)
{
- return new FilterHandler(this.context, this.filter, pattern, ranking, null /* name */);
+ FilterInfo info = new FilterInfo();
+ info.ranking = ranking;
+ info.patterns = pattern;
+
+ return new FilterHandler(this.context, this.filter, info);
+ }
+
+ private HttpServletRequest createServletRequest()
+ {
+ return createServletRequest(DispatcherType.REQUEST);
+ }
+
+ private HttpServletRequest createServletRequest(DispatcherType type)
+ {
+ HttpServletRequest result = mock(HttpServletRequest.class);
+ when(result.getDispatcherType()).thenReturn(type);
+ return result;
+ }
+
+ private HttpServletResponse createServletResponse()
+ {
+ return mock(HttpServletResponse.class);
}
}