felix-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From j...@apache.org
Subject svn commit: r1567561 [1/2] - in /felix/trunk/http: base/src/main/java/org/apache/felix/http/base/internal/ base/src/main/java/org/apache/felix/http/base/internal/context/ base/src/main/java/org/apache/felix/http/base/internal/dispatch/ base/src/main/ja...
Date Wed, 12 Feb 2014 08:25:06 GMT
Author: jawi
Date: Wed Feb 12 08:25:05 2014
New Revision: 1567561

URL: http://svn.apache.org/r1567561
Log:
FELIX-2774, FELIX-2797 & FELIX-4424:

- implement support for including and forwarding requests using the Servlet
  RequestDispatcher, including several itests to verify behaviour [FELIX-2774];
- wrap HttpSessions in order to provide access to the correct ServletContext
  [FELIX-2797];
- rudimentary fix for possible classloader leakage [FELIX-4424];
- prepared the Servlet- & FilterHandlers for named servlet/filters;
- several fixes to make the HTTP implementation more conform the Servlet 3.0
  specification.


Added:
    felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/RequestDispatcherProvider.java   (with props)
    felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/HttpSessionWrapper.java   (with props)
    felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/ServletContextWrapper.java   (with props)
    felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/util/UriUtils.java   (with props)
    felix/trunk/http/base/src/test/java/org/apache/felix/http/base/internal/util/UriUtilsTest.java   (with props)
    felix/trunk/http/itest/src/test/java/org/apache/felix/http/itest/AsyncTest.java   (with props)
    felix/trunk/http/itest/src/test/java/org/apache/felix/http/itest/RequestDispatchTest.java   (with props)
Modified:
    felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/DispatcherServlet.java
    felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/HttpServiceController.java
    felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/context/ExtServletContext.java
    felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/context/ServletContextImpl.java
    felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/context/ServletContextManager.java
    felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/Dispatcher.java
    felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/FilterPipeline.java
    felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/HttpFilterChain.java
    felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/InvocationFilterChain.java
    felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/NotFoundFilterChain.java
    felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/ServletPipeline.java
    felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/AbstractHandler.java
    felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/FilterConfigImpl.java
    felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/FilterHandler.java
    felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/HandlerRegistry.java
    felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/ServletConfigImpl.java
    felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/ServletHandler.java
    felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/ServletHandlerRequest.java
    felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/service/HttpServiceImpl.java
    felix/trunk/http/base/src/test/java/org/apache/felix/http/base/internal/handler/AbstractHandlerTest.java
    felix/trunk/http/base/src/test/java/org/apache/felix/http/base/internal/handler/FilterHandlerTest.java
    felix/trunk/http/base/src/test/java/org/apache/felix/http/base/internal/handler/ServletHandlerRequestTest.java
    felix/trunk/http/base/src/test/java/org/apache/felix/http/base/internal/handler/ServletHandlerTest.java
    felix/trunk/http/itest/pom.xml
    felix/trunk/http/itest/src/test/java/org/apache/felix/http/itest/BaseIntegrationTest.java

Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/DispatcherServlet.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/DispatcherServlet.java?rev=1567561&r1=1567560&r2=1567561&view=diff
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/DispatcherServlet.java (original)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/DispatcherServlet.java Wed Feb 12 08:25:05 2014
@@ -16,22 +16,22 @@
  */
 package org.apache.felix.http.base.internal;
 
-import javax.servlet.http.HttpServlet;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletRequestWrapper;
-import javax.servlet.http.HttpServletResponse;
+import java.io.IOException;
+
+import javax.servlet.ServletConfig;
 import javax.servlet.ServletContext;
 import javax.servlet.ServletException;
-import javax.servlet.ServletConfig;
 import javax.servlet.ServletRequestAttributeEvent;
 import javax.servlet.ServletRequestEvent;
+import javax.servlet.http.HttpServlet;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+import javax.servlet.http.HttpServletResponse;
 
 import org.apache.felix.http.base.internal.listener.ServletRequestAttributeListenerManager;
+import org.apache.felix.http.base.internal.listener.ServletRequestListenerManager;
 
-import java.io.IOException;
-
-public final class DispatcherServlet
-    extends HttpServlet
+public final class DispatcherServlet extends HttpServlet
 {
     private final HttpServiceController controller;
 
@@ -41,8 +41,7 @@ public final class DispatcherServlet
     }
 
     @Override
-    public void init(ServletConfig config)
-        throws ServletException
+    public void init(ServletConfig config) throws ServletException
     {
         super.init(config);
         this.controller.register(getServletContext());
@@ -56,11 +55,12 @@ public final class DispatcherServlet
     }
 
     @Override
-    protected void service(HttpServletRequest req, HttpServletResponse res)
-        throws ServletException, IOException
+    protected void service(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException
     {
+        ServletRequestListenerManager requestListener = this.controller.getRequestListener();
+
         final ServletRequestEvent sre = new ServletRequestEvent(getServletContext(), req);
-        this.controller.getRequestListener().requestInitialized(sre);
+        requestListener.requestInitialized(sre);
         try
         {
             req = new AttributeEventRequest(getServletContext(), this.controller.getRequestAttributeListener(), req);
@@ -68,22 +68,20 @@ public final class DispatcherServlet
         }
         finally
         {
-            this.controller.getRequestListener().requestDestroyed(sre);
+            requestListener.requestDestroyed(sre);
         }
     }
 
     private static class AttributeEventRequest extends HttpServletRequestWrapper
     {
-
         private final ServletContext servletContext;
-        private final ServletRequestAttributeListenerManager requestAttributeListener;
+        private final ServletRequestAttributeListenerManager listener;
 
-        public AttributeEventRequest(ServletContext servletContext,
-            ServletRequestAttributeListenerManager requestAttributeListener, HttpServletRequest request)
+        public AttributeEventRequest(ServletContext servletContext, ServletRequestAttributeListenerManager requestAttributeListener, HttpServletRequest request)
         {
             super(request);
             this.servletContext = servletContext;
-            this.requestAttributeListener = requestAttributeListener;
+            this.listener = requestAttributeListener;
         }
 
         public void setAttribute(String name, Object value)
@@ -99,13 +97,11 @@ public final class DispatcherServlet
 
                 if (oldValue == null)
                 {
-                    requestAttributeListener.attributeAdded(new ServletRequestAttributeEvent(servletContext, this,
-                        name, value));
+                    this.listener.attributeAdded(new ServletRequestAttributeEvent(this.servletContext, this, name, value));
                 }
                 else
                 {
-                    requestAttributeListener.attributeReplaced(new ServletRequestAttributeEvent(servletContext, this,
-                        name, oldValue));
+                    this.listener.attributeReplaced(new ServletRequestAttributeEvent(this.servletContext, this, name, oldValue));
                 }
             }
         }
@@ -117,9 +113,14 @@ public final class DispatcherServlet
 
             if (oldValue != null)
             {
-                requestAttributeListener.attributeRemoved(new ServletRequestAttributeEvent(servletContext, this, name,
-                    oldValue));
+                this.listener.attributeRemoved(new ServletRequestAttributeEvent(this.servletContext, this, name, oldValue));
             }
         }
+
+        @Override
+        public String toString()
+        {
+            return getClass().getSimpleName() + "->" + super.getRequest();
+        }
     }
 }

Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/HttpServiceController.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/HttpServiceController.java?rev=1567561&r1=1567560&r2=1567561&view=diff
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/HttpServiceController.java (original)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/HttpServiceController.java Wed Feb 12 08:25:05 2014
@@ -81,7 +81,7 @@ public final class HttpServiceController
         this.sessionListener = new HttpSessionListenerManager(bundleContext);
         this.sessionAttributeListener = new HttpSessionAttributeListenerManager(bundleContext);
         this.sharedContextAttributes = getBoolean(FELIX_HTTP_SHARED_SERVLET_CONTEXT_ATTRIBUTES);
-        this.plugin = new HttpServicePlugin(bundleContext,registry);
+        this.plugin = new HttpServicePlugin(bundleContext, registry);
     }
 
     public Dispatcher getDispatcher()
@@ -119,7 +119,8 @@ public final class HttpServiceController
         this.serviceProps.clear();
         this.serviceProps.putAll(props);
 
-        if (this.serviceReg != null) {
+        if (this.serviceReg != null)
+        {
             this.serviceReg.setProperties(this.serviceProps);
         }
     }
@@ -133,15 +134,16 @@ public final class HttpServiceController
         this.sessionAttributeListener.open();
         this.plugin.register();
 
-        HttpServiceFactory factory = new HttpServiceFactory(servletContext, this.registry,
-            this.contextAttributeListener, this.sharedContextAttributes);
         String[] ifaces = new String[] { HttpService.class.getName(), ExtHttpService.class.getName() };
+        HttpServiceFactory factory = new HttpServiceFactory(servletContext, this.registry, this.contextAttributeListener, this.sharedContextAttributes);
+
         this.serviceReg = this.bundleContext.registerService(ifaces, factory, this.serviceProps);
     }
 
     public void unregister()
     {
-        if (this.serviceReg == null) {
+        if (this.serviceReg == null)
+        {
             return;
         }
 
@@ -152,10 +154,13 @@ public final class HttpServiceController
         this.requestAttributeListener.close();
         this.plugin.unregister();
 
-        try {
+        try
+        {
             this.serviceReg.unregister();
             this.registry.removeAll();
-        } finally {
+        }
+        finally
+        {
             this.serviceReg = null;
         }
     }

Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/context/ExtServletContext.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/context/ExtServletContext.java?rev=1567561&r1=1567560&r2=1567561&view=diff
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/context/ExtServletContext.java (original)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/context/ExtServletContext.java Wed Feb 12 08:25:05 2014
@@ -22,9 +22,7 @@ import javax.servlet.ServletContext;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
-public interface ExtServletContext
-    extends ServletContext
+public interface ExtServletContext extends ServletContext
 {
-    public boolean handleSecurity(HttpServletRequest req, HttpServletResponse res)
-        throws IOException;
+    boolean handleSecurity(HttpServletRequest req, HttpServletResponse res) throws IOException;
 }

Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/context/ServletContextImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/context/ServletContextImpl.java?rev=1567561&r1=1567560&r2=1567561&view=diff
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/context/ServletContextImpl.java (original)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/context/ServletContextImpl.java Wed Feb 12 08:25:05 2014
@@ -48,7 +48,7 @@ import org.osgi.framework.Bundle;
 import org.osgi.service.http.HttpContext;
 
 @SuppressWarnings("deprecation")
-public final class ServletContextImpl implements ExtServletContext
+public class ServletContextImpl implements ExtServletContext
 {
     private final Bundle bundle;
     private final ServletContext context;
@@ -65,6 +65,16 @@ public final class ServletContextImpl im
         this.attributes = sharedAttributes ? null : new ConcurrentHashMap<String, Object>();
     }
 
+    protected ServletContextImpl(ExtServletContext delegate)
+    {
+        ServletContextImpl impl = (ServletContextImpl) delegate;
+        this.bundle = impl.bundle;
+        this.context = impl.context;
+        this.httpContext = impl.httpContext;
+        this.attributeListener = impl.attributeListener;
+        this.attributes = impl.attributes;
+    }
+
     public FilterRegistration.Dynamic addFilter(String filterName, Class<? extends Filter> type)
     {
         throw new UnsupportedOperationException();
@@ -229,7 +239,8 @@ public final class ServletContextImpl im
     public String getRealPath(String name)
     {
         URL url = getResource(normalizePath(name));
-        if (url == null) {
+        if (url == null)
+        {
             return null;
         }
         return url.toExternalForm();
@@ -354,7 +365,7 @@ public final class ServletContextImpl im
 
         if (oldValue != null)
         {
-            attributeListener.attributeRemoved(new ServletContextAttributeEvent(this, name, oldValue));
+            this.attributeListener.attributeRemoved(new ServletContextAttributeEvent(this, name, oldValue));
         }
     }
 
@@ -379,11 +390,11 @@ public final class ServletContextImpl im
 
             if (oldValue == null)
             {
-                attributeListener.attributeAdded(new ServletContextAttributeEvent(this, name, value));
+                this.attributeListener.attributeAdded(new ServletContextAttributeEvent(this, name, value));
             }
             else
             {
-                attributeListener.attributeReplaced(new ServletContextAttributeEvent(this, name, oldValue));
+                this.attributeListener.attributeReplaced(new ServletContextAttributeEvent(this, name, oldValue));
             }
         }
     }

Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/context/ServletContextManager.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/context/ServletContextManager.java?rev=1567561&r1=1567560&r2=1567561&view=diff
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/context/ServletContextManager.java (original)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/context/ServletContextManager.java Wed Feb 12 08:25:05 2014
@@ -16,8 +16,8 @@
  */
 package org.apache.felix.http.base.internal.context;
 
-import java.util.HashMap;
 import java.util.Map;
+import java.util.WeakHashMap;
 
 import javax.servlet.ServletContext;
 import javax.servlet.ServletContextAttributeListener;
@@ -33,32 +33,35 @@ public final class ServletContextManager
     private final Map<HttpContext, ExtServletContext> contextMap;
     private final boolean sharedAttributes;
 
-    public ServletContextManager(Bundle bundle, ServletContext context,
-        ServletContextAttributeListener attributeListener, boolean sharedAttributes)
+    public ServletContextManager(Bundle bundle, ServletContext context, ServletContextAttributeListener attributeListener, boolean sharedAttributes)
     {
         this.bundle = bundle;
         this.context = context;
         this.attributeListener = attributeListener;
-        this.contextMap = new HashMap<HttpContext, ExtServletContext>();
+        // FELIX-4424 : avoid classloader leakage through HttpContext, for now this is sufficient, 
+        // the real fix should be to remove ExtServletContext's when the usage count of HttpContext 
+        // drops to zero. 
+        this.contextMap = new WeakHashMap<HttpContext, ExtServletContext>();
         this.sharedAttributes = sharedAttributes;
     }
 
     public ExtServletContext getServletContext(HttpContext httpContext)
     {
-        synchronized (this.contextMap) {
-            ExtServletContext context = this.contextMap.get(httpContext);
-            if (context == null) {
+        ExtServletContext context;
+        synchronized (this.contextMap)
+        {
+            context = this.contextMap.get(httpContext);
+            if (context == null)
+            {
                 context = addServletContext(httpContext);
             }
-
-            return context;
         }
+        return context;
     }
 
     private ExtServletContext addServletContext(HttpContext httpContext)
     {
-        ExtServletContext context = new ServletContextImpl(this.bundle, this.context, httpContext, attributeListener,
-            sharedAttributes);
+        ExtServletContext context = new ServletContextImpl(this.bundle, this.context, httpContext, this.attributeListener, this.sharedAttributes);
         this.contextMap.put(httpContext, context);
         return context;
     }

Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/Dispatcher.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/Dispatcher.java?rev=1567561&r1=1567560&r2=1567561&view=diff
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/Dispatcher.java (original)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/Dispatcher.java Wed Feb 12 08:25:05 2014
@@ -16,14 +16,21 @@
  */
 package org.apache.felix.http.base.internal.dispatch;
 
-import org.apache.felix.http.base.internal.handler.HandlerRegistry;
+import java.io.IOException;
+
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
-import javax.servlet.ServletException;
-import java.io.IOException;
+
+import org.apache.felix.http.base.internal.handler.HandlerRegistry;
 
 public final class Dispatcher
 {
+    public static final String REQUEST_DISPATCHER_PROVIDER = "org.apache.felix.http.requestDispatcherProvider";
+
+    private static final FilterChain DEFAULT_CHAIN = new NotFoundFilterChain();
+
     private final HandlerRegistry handlerRegistry;
 
     public Dispatcher(HandlerRegistry handlerRegistry)
@@ -31,11 +38,19 @@ public final class Dispatcher
         this.handlerRegistry = handlerRegistry;
     }
 
-    public void dispatch(HttpServletRequest req, HttpServletResponse res)
-        throws ServletException, IOException
+    public void dispatch(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException
     {
         ServletPipeline servletPipeline = new ServletPipeline(this.handlerRegistry.getServlets());
-        FilterPipeline filterPipeline = new FilterPipeline(this.handlerRegistry.getFilters(), servletPipeline);
-        filterPipeline.dispatch(req, res, new NotFoundFilterChain());
+        // Provides access to the correct request dispatcher...
+        req.setAttribute(REQUEST_DISPATCHER_PROVIDER, servletPipeline);
+
+        try
+        {
+            new FilterPipeline(this.handlerRegistry.getFilters(), servletPipeline).dispatch(req, res, DEFAULT_CHAIN);
+        }
+        finally
+        {
+            req.removeAttribute(REQUEST_DISPATCHER_PROVIDER);
+        }
     }
 }

Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/FilterPipeline.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/FilterPipeline.java?rev=1567561&r1=1567560&r2=1567561&view=diff
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/FilterPipeline.java (original)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/FilterPipeline.java Wed Feb 12 08:25:05 2014
@@ -16,17 +16,45 @@
  */
 package org.apache.felix.http.base.internal.dispatch;
 
-import javax.servlet.http.HttpServletResponse;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletRequestWrapper;
-import javax.servlet.ServletException;
+import java.io.IOException;
+
 import javax.servlet.FilterChain;
 import javax.servlet.RequestDispatcher;
-import java.io.IOException;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+import javax.servlet.http.HttpServletResponse;
+
 import org.apache.felix.http.base.internal.handler.FilterHandler;
 
 public final class FilterPipeline
 {
+    private static class FilterRequestWrapper extends HttpServletRequestWrapper
+    {
+        public FilterRequestWrapper(HttpServletRequest req)
+        {
+            super(req);
+        }
+
+        @Override
+        public RequestDispatcher getRequestDispatcher(String path)
+        {
+            RequestDispatcherProvider provider = (RequestDispatcherProvider) getAttribute(Dispatcher.REQUEST_DISPATCHER_PROVIDER);
+            RequestDispatcher dispatcher = null;
+            if (provider != null)
+            {
+                dispatcher = provider.getRequestDispatcher(path);
+            }
+            return (dispatcher != null) ? dispatcher : super.getRequestDispatcher(path);
+        }
+
+        @Override
+        public String toString()
+        {
+            return getClass().getSimpleName() + "->" + super.getRequest();
+        }
+    }
+
     private final FilterHandler[] handlers;
     private final ServletPipeline servletPipeline;
 
@@ -36,31 +64,15 @@ public final class FilterPipeline
         this.servletPipeline = servletPipeline;
     }
 
-    public void dispatch(HttpServletRequest req, HttpServletResponse res, FilterChain proceedingChain)
-        throws ServletException, IOException
+    public void dispatch(HttpServletRequest req, HttpServletResponse res, FilterChain proceedingChain) throws ServletException, IOException
     {
         FilterChain chain = new InvocationFilterChain(this.handlers, this.servletPipeline, proceedingChain);
 
-        if (this.servletPipeline.hasServletsMapped()) {
-            req = new RequestWrapper(req);
-        }
-
-        chain.doFilter(req, res);
-    }
-
-    private final class RequestWrapper
-        extends HttpServletRequestWrapper
-    {
-        public RequestWrapper(HttpServletRequest req)
+        if (this.servletPipeline.hasServletsMapped())
         {
-            super(req);
+            req = new FilterRequestWrapper(req);
         }
 
-        @Override
-        public RequestDispatcher getRequestDispatcher(String path)
-        {
-            final RequestDispatcher dispatcher = servletPipeline.getRequestDispatcher(path);
-            return (null != dispatcher) ? dispatcher : super.getRequestDispatcher(path);
-        }        
+        chain.doFilter(req, res);
     }
 }

Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/HttpFilterChain.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/HttpFilterChain.java?rev=1567561&r1=1567560&r2=1567561&view=diff
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/HttpFilterChain.java (original)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/HttpFilterChain.java Wed Feb 12 08:25:05 2014
@@ -24,15 +24,12 @@ import javax.servlet.http.HttpServletReq
 import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
 
-public abstract class HttpFilterChain 
-    implements FilterChain
+public abstract class HttpFilterChain implements FilterChain
 {
-    public final void doFilter(ServletRequest req, ServletResponse res)
-        throws IOException, ServletException
+    public final void doFilter(ServletRequest req, ServletResponse res) throws IOException, ServletException
     {
-        doFilter((HttpServletRequest)req, (HttpServletResponse)res);
+        doFilter((HttpServletRequest) req, (HttpServletResponse) res);
     }
 
-    protected abstract void doFilter(HttpServletRequest req, HttpServletResponse res)
-        throws IOException, ServletException;
+    protected abstract void doFilter(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException;
 }

Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/InvocationFilterChain.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/InvocationFilterChain.java?rev=1567561&r1=1567560&r2=1567561&view=diff
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/InvocationFilterChain.java (original)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/InvocationFilterChain.java Wed Feb 12 08:25:05 2014
@@ -23,12 +23,11 @@ import javax.servlet.http.HttpServletRes
 import java.io.IOException;
 import org.apache.felix.http.base.internal.handler.FilterHandler;
 
-public final class InvocationFilterChain
-    extends HttpFilterChain
+public final class InvocationFilterChain extends HttpFilterChain
 {
     private final FilterHandler[] handlers;
     private final ServletPipeline servletPipeline;
-    private final FilterChain proceedingChain;    
+    private final FilterChain proceedingChain;
     private int index = -1;
 
     public InvocationFilterChain(FilterHandler[] handlers, ServletPipeline servletPipeline, FilterChain proceedingChain)
@@ -38,15 +37,18 @@ public final class InvocationFilterChain
         this.proceedingChain = proceedingChain;
     }
 
-    protected void doFilter(HttpServletRequest req, HttpServletResponse res)
-        throws IOException, ServletException
+    protected void doFilter(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException
     {
         this.index++;
 
-        if (this.index < this.handlers.length) {
+        if (this.index < this.handlers.length)
+        {
             this.handlers[this.index].handle(req, res, this);
-        } else {
-            if (!this.servletPipeline.handle(req, res)) {
+        }
+        else
+        {
+            if (!this.servletPipeline.handle(req, res))
+            {
                 this.proceedingChain.doFilter(req, res);
             }
         }

Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/NotFoundFilterChain.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/NotFoundFilterChain.java?rev=1567561&r1=1567560&r2=1567561&view=diff
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/NotFoundFilterChain.java (original)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/NotFoundFilterChain.java Wed Feb 12 08:25:05 2014
@@ -21,11 +21,9 @@ import javax.servlet.http.HttpServletReq
 import javax.servlet.http.HttpServletResponse;
 import java.io.IOException;
 
-public final class NotFoundFilterChain
-    extends HttpFilterChain
+public final class NotFoundFilterChain extends HttpFilterChain
 {
-    protected void doFilter(HttpServletRequest req, HttpServletResponse res)
-        throws IOException, ServletException
+    protected void doFilter(HttpServletRequest req, HttpServletResponse res) throws IOException, ServletException
     {
         res.sendError(HttpServletResponse.SC_NOT_FOUND);
     }

Added: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/RequestDispatcherProvider.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/RequestDispatcherProvider.java?rev=1567561&view=auto
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/RequestDispatcherProvider.java (added)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/RequestDispatcherProvider.java Wed Feb 12 08:25:05 2014
@@ -0,0 +1,39 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.felix.http.base.internal.dispatch;
+
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletContext;
+
+/**
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public interface RequestDispatcherProvider
+{
+    /**
+     * @see ServletContext#getNamedDispatcher(String)
+     */
+    RequestDispatcher getNamedDispatcher(String name);
+
+    /**
+     * @see ServletContext#getRequestDispatcher(String)
+     */
+    RequestDispatcher getRequestDispatcher(String path);
+}

Propchange: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/RequestDispatcherProvider.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/ServletPipeline.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/ServletPipeline.java?rev=1567561&r1=1567560&r2=1567561&view=diff
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/ServletPipeline.java (original)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/ServletPipeline.java Wed Feb 12 08:25:05 2014
@@ -16,17 +16,19 @@
  */
 package org.apache.felix.http.base.internal.dispatch;
 
-import javax.servlet.http.HttpServletResponse;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletRequestWrapper;
-import javax.servlet.ServletException;
-import javax.servlet.RequestDispatcher;
-import javax.servlet.ServletRequest;
-import javax.servlet.ServletResponse;
+import static org.apache.felix.http.base.internal.util.UriUtils.decodePath;
+import static org.apache.felix.http.base.internal.util.UriUtils.removeDotSegments;
+
 import java.io.IOException;
+
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletException;
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
 import org.apache.felix.http.base.internal.handler.ServletHandler;
 
-public final class ServletPipeline
+public final class ServletPipeline implements RequestDispatcherProvider
 {
     private final ServletHandler[] handlers;
 
@@ -35,77 +37,70 @@ public final class ServletPipeline
         this.handlers = handlers;
     }
 
-    public boolean handle(HttpServletRequest req, HttpServletResponse res)
-        throws ServletException, IOException
+    public RequestDispatcher getNamedDispatcher(String name)
     {
-        for (ServletHandler handler : this.handlers) {
-            if (handler.handle(req, res)) {
-                return true;
-            }
+        // See section 9.1 of Servlet 3.x specification...
+        if (name == null)
+        {
+            return null;
         }
 
-        return false;
-    }
-
-    public boolean hasServletsMapped()
-    {
-        return this.handlers.length > 0;
-    }
-
-    public RequestDispatcher getRequestDispatcher(String path)
-    {
-        for (ServletHandler handler : this.handlers) {
-            if (handler.matches(path)) {
-                return new Dispatcher(path, handler);
+        for (ServletHandler handler : this.handlers)
+        {
+            if (name.equals(handler.getName()))
+            {
+                return handler.createNamedRequestDispatcher();
             }
         }
-        
+
         return null;
     }
 
-    private final class Dispatcher
-        implements RequestDispatcher
+    public RequestDispatcher getRequestDispatcher(String path)
     {
-        private final String path;
-        private final ServletHandler handler;
-
-        public Dispatcher(String path, ServletHandler handler)
+        // See section 9.1 of Servlet 3.x specification...
+        if (path == null || (!path.startsWith("/") && !"".equals(path)))
         {
-            this.path = path;
-            this.handler = handler;
+            return null;
         }
 
-        public void forward(ServletRequest req, ServletResponse res)
-            throws ServletException, IOException
+        String query = null;
+        int q = 0;
+        if ((q = path.indexOf('?')) > 0)
         {
-            if (res.isCommitted()) {
-                throw new ServletException("Response has been committed");
-            }
-
-            this.handler.handle(new RequestWrapper((HttpServletRequest)req, this.path), (HttpServletResponse)res);
+            query = path.substring(q + 1);
+            path = path.substring(0, q);
         }
+        // TODO remove path parameters...
+        String pathInContext = decodePath(removeDotSegments(path));
 
-        public void include(ServletRequest req, ServletResponse res)
-            throws ServletException, IOException
+        for (ServletHandler handler : this.handlers)
         {
-            this.handler.handle((HttpServletRequest)req, (HttpServletResponse)res);
+            if (handler.matches(pathInContext))
+            {
+                return handler.createRequestDispatcher(path, pathInContext, query);
+            }
         }
+
+        return null;
     }
 
-    private final class RequestWrapper
-        extends HttpServletRequestWrapper
+    public boolean handle(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException
     {
-        private final String requestUri;
-        
-        public RequestWrapper(HttpServletRequest req, String requestUri)
+        // NOTE: this code assumes that HttpServletRequest#getRequestDispatcher() is properly mapped, see FilterPipeline.FilterRequestWrapper!
+        for (ServletHandler handler : this.handlers)
         {
-            super(req);
-            this.requestUri = requestUri;
+            if (handler.handle(req, res))
+            {
+                return true;
+            }
         }
 
-        public String getRequestURI()
-        {
-            return this.requestUri;
-        }
+        return false;
+    }
+
+    public boolean hasServletsMapped()
+    {
+        return this.handlers.length > 0;
     }
 }

Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/AbstractHandler.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/AbstractHandler.java?rev=1567561&r1=1567560&r2=1567561&view=diff
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/AbstractHandler.java (original)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/AbstractHandler.java Wed Feb 12 08:25:05 2014
@@ -16,62 +16,87 @@
  */
 package org.apache.felix.http.base.internal.handler;
 
+import javax.servlet.Filter;
+import javax.servlet.Servlet;
 import javax.servlet.ServletException;
+
 import org.apache.felix.http.base.internal.context.ExtServletContext;
+
 import java.util.*;
 import java.util.concurrent.atomic.AtomicInteger;
 
 public abstract class AbstractHandler
 {
-    private final static AtomicInteger ID =
-        new AtomicInteger();
+    private final static AtomicInteger ID = new AtomicInteger();
 
-    private final String id;
+    private final int id;
+    private final String baseName;
     private final ExtServletContext context;
     private final Map<String, String> initParams;
 
-    public AbstractHandler(ExtServletContext context)
+    public AbstractHandler(ExtServletContext context, String baseName)
     {
-        this.id = "" + ID.incrementAndGet();
         this.context = context;
+        this.baseName = baseName;
+        this.id = ID.incrementAndGet();
         this.initParams = new HashMap<String, String>();
     }
 
-    public final String getId()
-    {
-        return this.id;
-    }
+    public abstract void destroy();
 
-    protected final ExtServletContext getContext()
+    public final Map<String, String> getInitParams()
     {
-        return this.context;
+        return this.initParams;
     }
 
-    public final Map<String, String> getInitParams()
+    public final String getName()
     {
-        return this.initParams;
+        String name = this.baseName;
+        if (name == null)
+        {
+            name = String.format("%s_%d", getSubject().getClass(), this.id);
+        }
+        return name;
     }
 
+    public abstract void init() throws ServletException;
+
     public final void setInitParams(Dictionary map)
     {
         this.initParams.clear();
-        if (map == null) {
+        if (map == null)
+        {
             return;
         }
 
         Enumeration e = map.keys();
-        while (e.hasMoreElements()) {
+        while (e.hasMoreElements())
+        {
             Object key = e.nextElement();
             Object value = map.get(key);
 
-            if ((key instanceof String) && (value instanceof String)) {
-                this.initParams.put((String)key, (String)value);
+            if ((key instanceof String) && (value instanceof String))
+            {
+                this.initParams.put((String) key, (String) value);
             }
         }
     }
 
-    public abstract void init()
-        throws ServletException;
+    protected final ExtServletContext getContext()
+    {
+        return this.context;
+    }
+
+    /**
+     * @return a unique ID for this handler, &gt; 0.
+     */
+    protected final int getId()
+    {
+        return id;
+    }
 
-    public abstract void destroy();
+    /**
+     * @return the {@link Servlet} or {@link Filter} this handler handles.
+     */
+    protected abstract Object getSubject();
 }

Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/FilterConfigImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/FilterConfigImpl.java?rev=1567561&r1=1567560&r2=1567561&view=diff
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/FilterConfigImpl.java (original)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/FilterConfigImpl.java Wed Feb 12 08:25:05 2014
@@ -22,8 +22,7 @@ import java.util.Enumeration;
 import java.util.Collections;
 import java.util.Map;
 
-public final class FilterConfigImpl
-    implements FilterConfig
+public final class FilterConfigImpl implements FilterConfig
 {
     private final String name;
     private final ServletContext context;

Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/FilterHandler.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/FilterHandler.java?rev=1567561&r1=1567560&r2=1567561&view=diff
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/FilterHandler.java (original)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/FilterHandler.java Wed Feb 12 08:25:05 2014
@@ -19,38 +19,36 @@ package org.apache.felix.http.base.inter
 import java.io.IOException;
 import java.util.regex.Pattern;
 
-import javax.servlet.*;
+import javax.servlet.Filter;
+import javax.servlet.FilterChain;
+import javax.servlet.ServletException;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletResponse;
 
 import org.apache.felix.http.base.internal.context.ExtServletContext;
 
-public final class FilterHandler
-    extends AbstractHandler implements Comparable<FilterHandler>
+public final class FilterHandler extends AbstractHandler implements Comparable<FilterHandler>
 {
     private final Filter filter;
     private final Pattern regex;
     private final int ranking;
 
-    public FilterHandler(ExtServletContext context, Filter filter, String pattern, int ranking)
+    public FilterHandler(ExtServletContext context, Filter filter, String pattern, int ranking, String name)
     {
-        super(context);
+        super(context, name);
         this.filter = filter;
         this.ranking = ranking;
-	    this.regex = Pattern.compile(pattern);
+        this.regex = Pattern.compile(pattern);
     }
 
-    public Filter getFilter()
+    public int compareTo(FilterHandler other)
     {
-        return this.filter;
-    }
+        if (other.ranking == this.ranking)
+        {
+            return 0;
+        }
 
-    public void init()
-        throws ServletException
-    {
-        String name = "filter_" + getId();
-        FilterConfig config = new FilterConfigImpl(name, getContext(), getInitParams());
-        this.filter.init(config);
+        return (other.ranking > this.ranking) ? 1 : -1;
     }
 
     public void destroy()
@@ -58,54 +56,65 @@ public final class FilterHandler
         this.filter.destroy();
     }
 
-    public boolean matches(String uri)
+    public Filter getFilter()
     {
-        // assume root if uri is null
-        if (uri == null) {
-            uri = "/";
-        }
+        return this.filter;
+    }
 
-        return this.regex.matcher(uri).matches();
+    public String getPattern()
+    {
+        return regex.toString();
+    }
+
+    public int getRanking()
+    {
+        return ranking;
     }
 
-    public void handle(HttpServletRequest req, HttpServletResponse res, FilterChain chain)
-        throws ServletException, IOException
+    public void handle(HttpServletRequest req, HttpServletResponse res, FilterChain chain) throws ServletException, IOException
     {
         final boolean matches = matches(req.getPathInfo());
-        if (matches) {
+        if (matches)
+        {
             doHandle(req, res, chain);
-        } else {
+        }
+        else
+        {
             chain.doFilter(req, res);
         }
     }
 
-    private void doHandle(HttpServletRequest req, HttpServletResponse res, FilterChain chain)
-        throws ServletException, IOException
+    public void init() throws ServletException
     {
-        if (!getContext().handleSecurity(req, res)) {
-            res.sendError(HttpServletResponse.SC_FORBIDDEN);
-        } else {
-            this.filter.doFilter(req, res, chain);
-        }
+        this.filter.init(new FilterConfigImpl(getName(), getContext(), getInitParams()));
     }
 
-    public int compareTo(FilterHandler other)
+    public boolean matches(String uri)
     {
-        if (other.ranking == this.ranking)
+        // assume root if uri is null
+        if (uri == null)
         {
-            return 0;
+            uri = "/";
         }
 
-        return (other.ranking > this.ranking) ? 1 : -1;
+        return this.regex.matcher(uri).matches();
     }
 
-    public int getRanking()
+    final void doHandle(HttpServletRequest req, HttpServletResponse res, FilterChain chain) throws ServletException, IOException
     {
-        return ranking;
+        if (!getContext().handleSecurity(req, res))
+        {
+            res.sendError(HttpServletResponse.SC_FORBIDDEN);
+        }
+        else
+        {
+            this.filter.doFilter(req, res, chain);
+        }
     }
-
-    public String getPattern()
+    
+    @Override
+    protected Object getSubject()
     {
-        return regex.toString();
+        return this.filter;
     }
 }

Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/HandlerRegistry.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/HandlerRegistry.java?rev=1567561&r1=1567560&r2=1567561&view=diff
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/HandlerRegistry.java (original)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/HandlerRegistry.java Wed Feb 12 08:25:05 2014
@@ -51,14 +51,15 @@ public final class HandlerRegistry
         return this.filters;
     }
 
-    public synchronized void addServlet(ServletHandler handler)
-        throws ServletException, NamespaceException
+    public synchronized void addServlet(ServletHandler handler) throws ServletException, NamespaceException
     {
-        if (this.servletMap.containsKey(handler.getServlet())) {
+        if (this.servletMap.containsKey(handler.getServlet()))
+        {
             throw new ServletException("Servlet instance already registered");
         }
 
-        if (this.aliasMap.containsKey(handler.getAlias())) {
+        if (this.aliasMap.containsKey(handler.getAlias()))
+        {
             throw new NamespaceException("Servlet with alias already registered");
         }
 
@@ -68,10 +69,10 @@ public final class HandlerRegistry
         updateServletArray();
     }
 
-    public synchronized void addFilter(FilterHandler handler)
-        throws ServletException
+    public synchronized void addFilter(FilterHandler handler) throws ServletException
     {
-        if (this.filterMap.containsKey(handler.getFilter())) {
+        if (this.filterMap.containsKey(handler.getFilter()))
+        {
             throw new ServletException("Filter instance already registered");
         }
 
@@ -83,7 +84,8 @@ public final class HandlerRegistry
     public synchronized void removeServlet(Servlet servlet, final boolean destroy)
     {
         ServletHandler handler = this.servletMap.remove(servlet);
-        if (handler != null) {
+        if (handler != null)
+        {
             updateServletArray();
             this.aliasMap.remove(handler.getAlias());
             if (destroy)
@@ -96,7 +98,8 @@ public final class HandlerRegistry
     public synchronized void removeFilter(Filter filter, final boolean destroy)
     {
         FilterHandler handler = this.filterMap.remove(filter);
-        if (handler != null) {
+        if (handler != null)
+        {
             updateFilterArray();
             if (destroy)
             {
@@ -112,11 +115,13 @@ public final class HandlerRegistry
 
     public synchronized void removeAll()
     {
-        for (ServletHandler handler : this.servletMap.values()) {
+        for (ServletHandler handler : this.servletMap.values())
+        {
             handler.destroy();
         }
 
-        for (FilterHandler handler : this.filterMap.values()) {
+        for (FilterHandler handler : this.filterMap.values())
+        {
             handler.destroy();
         }
 

Added: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/HttpSessionWrapper.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/HttpSessionWrapper.java?rev=1567561&view=auto
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/HttpSessionWrapper.java (added)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/HttpSessionWrapper.java Wed Feb 12 08:25:05 2014
@@ -0,0 +1,130 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.felix.http.base.internal.handler;
+
+import java.util.Enumeration;
+
+import javax.servlet.ServletContext;
+import javax.servlet.http.HttpSession;
+import javax.servlet.http.HttpSessionContext;
+
+/**
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+@SuppressWarnings("deprecation")
+public class HttpSessionWrapper implements HttpSession
+{
+    private final HttpSession delegate;
+    private final ServletContext context;
+
+    /**
+     * Creates a new {@link HttpSessionWrapper} instance.
+     */
+    public HttpSessionWrapper(HttpSession session, ServletContext context)
+    {
+        this.delegate = session;
+        this.context = context;
+    }
+
+    public Object getAttribute(String name)
+    {
+        return this.delegate.getAttribute(name);
+    }
+
+    public Enumeration<String> getAttributeNames()
+    {
+        return this.delegate.getAttributeNames();
+    }
+
+    public long getCreationTime()
+    {
+        return this.delegate.getCreationTime();
+    }
+
+    public String getId()
+    {
+        return this.delegate.getId();
+    }
+
+    public long getLastAccessedTime()
+    {
+        return this.delegate.getLastAccessedTime();
+    }
+
+    public int getMaxInactiveInterval()
+    {
+        return this.delegate.getMaxInactiveInterval();
+    }
+
+    public ServletContext getServletContext()
+    {
+        return this.context;
+    }
+
+    public HttpSessionContext getSessionContext()
+    {
+        return this.delegate.getSessionContext();
+    }
+
+    public Object getValue(String name)
+    {
+        return this.delegate.getValue(name);
+    }
+
+    public String[] getValueNames()
+    {
+        return this.delegate.getValueNames();
+    }
+
+    public void invalidate()
+    {
+        this.delegate.invalidate();
+    }
+
+    public boolean isNew()
+    {
+        return this.delegate.isNew();
+    }
+
+    public void putValue(String name, Object value)
+    {
+        this.delegate.putValue(name, value);
+    }
+
+    public void removeAttribute(String name)
+    {
+        this.delegate.removeAttribute(name);
+    }
+
+    public void removeValue(String name)
+    {
+        this.delegate.removeValue(name);
+    }
+
+    public void setAttribute(String name, Object value)
+    {
+        this.delegate.setAttribute(name, value);
+    }
+
+    public void setMaxInactiveInterval(int interval)
+    {
+        this.delegate.setMaxInactiveInterval(interval);
+    }
+}

Propchange: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/HttpSessionWrapper.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/ServletConfigImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/ServletConfigImpl.java?rev=1567561&r1=1567560&r2=1567561&view=diff
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/ServletConfigImpl.java (original)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/ServletConfigImpl.java Wed Feb 12 08:25:05 2014
@@ -22,8 +22,7 @@ import java.util.Enumeration;
 import java.util.Collections;
 import java.util.Map;
 
-public final class ServletConfigImpl
-    implements ServletConfig
+public final class ServletConfigImpl implements ServletConfig
 {
     private final String name;
     private final ServletContext context;

Added: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/ServletContextWrapper.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/ServletContextWrapper.java?rev=1567561&view=auto
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/ServletContextWrapper.java (added)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/ServletContextWrapper.java Wed Feb 12 08:25:05 2014
@@ -0,0 +1,69 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.felix.http.base.internal.handler;
+
+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>
+ */
+class ServletContextWrapper extends ServletContextImpl
+{
+    private final RequestDispatcherProvider provider;
+
+    /**
+     * Creates a new {@link ServletContextWrapper} instance.
+     */
+    public ServletContextWrapper(ExtServletContext delegate, RequestDispatcherProvider provider)
+    {
+        super(delegate);
+
+        this.provider = provider;
+    }
+
+    @Override
+    public RequestDispatcher getNamedDispatcher(String name)
+    {
+        if (name == null)
+        {
+            return null;
+        }
+
+        RequestDispatcher dispatcher = this.provider.getNamedDispatcher(name);
+        return dispatcher != null ? dispatcher : super.getNamedDispatcher(name);
+    }
+
+    @Override
+    public RequestDispatcher getRequestDispatcher(String path)
+    {
+        // See section 9.1 of Servlet 3.x specification...
+        if (path == null || (!path.startsWith("/") && !"".equals(path)))
+        {
+            return null;
+        }
+
+        RequestDispatcher dispatcher = this.provider.getRequestDispatcher(path);
+        return dispatcher != null ? dispatcher : super.getRequestDispatcher(path);
+    }
+}

Propchange: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/ServletContextWrapper.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/ServletHandler.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/ServletHandler.java?rev=1567561&r1=1567560&r2=1567561&view=diff
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/ServletHandler.java (original)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/ServletHandler.java Wed Feb 12 08:25:05 2014
@@ -16,43 +16,245 @@
  */
 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 org.apache.felix.http.base.internal.util.UriUtils.concat;
+
+import java.io.IOException;
+
+import javax.servlet.DispatcherType;
+import javax.servlet.RequestDispatcher;
 import javax.servlet.Servlet;
 import javax.servlet.ServletException;
-import javax.servlet.ServletConfig;
+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.base.internal.context.ExtServletContext;
-import java.io.IOException;
 
-public final class ServletHandler
-    extends AbstractHandler implements Comparable<ServletHandler>
+/**
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+public final class ServletHandler extends AbstractHandler implements Comparable<ServletHandler>
 {
+    private class RequestDispatcherImpl implements RequestDispatcher
+    {
+        final String servletPath;
+        final String requestURI;
+        final String pathInfo;
+        final String query;
+        final boolean named;
+
+        public RequestDispatcherImpl()
+        {
+            this.requestURI = null;
+            // PathMap.pathMatch(servlet_path_spec,target);
+            this.servletPath = getAlias(); // XXX handle wildcard aliases!
+            this.pathInfo = null;
+            this.query = null;
+            this.named = true;
+        }
+
+        public RequestDispatcherImpl(String uri, String pathInContext, String query)
+        {
+            this.requestURI = uri;
+            this.servletPath = getAlias(); // XXX handle wildcard aliases!
+            this.pathInfo = this.servletPath.equals(pathInContext) ? null : 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(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(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 alias;
     private final Servlet servlet;
 
-    public ServletHandler(ExtServletContext context, Servlet servlet, String alias)
+    public ServletHandler(ExtServletContext context, Servlet servlet, String alias, String name)
     {
-        super(context);
+        super(context, name);
         this.alias = alias;
         this.servlet = servlet;
     }
 
-    public String getAlias()
+    public int compareTo(ServletHandler other)
     {
-        return this.alias;
+        return other.alias.length() - this.alias.length();
     }
 
-    public Servlet getServlet()
+    public RequestDispatcher createNamedRequestDispatcher()
     {
-        return this.servlet;
+        return new RequestDispatcherImpl();
     }
 
-    public void init()
-        throws ServletException
+    public RequestDispatcher createRequestDispatcher(String path, String pathInContext, String query)
     {
-        String name = "servlet_" + getId();
-        ServletConfig config = new ServletConfigImpl(name, getContext(), getInitParams());
-        this.servlet.init(config);
+        return new RequestDispatcherImpl(path, pathInContext, query);
     }
 
     public void destroy()
@@ -60,30 +262,68 @@ public final class ServletHandler
         this.servlet.destroy();
     }
 
-    public boolean matches(String uri)
+    public String getAlias()
     {
-        if (uri == null) {
-            return this.alias.equals("/");
-        } else if (this.alias.equals("/")) {
-            return uri.startsWith(this.alias);
-        } else {
-            return uri.equals(this.alias) || uri.startsWith(this.alias + "/");
-        }
+        return this.alias;
     }
 
-    public boolean handle(HttpServletRequest req, HttpServletResponse res)
-        throws ServletException, IOException
+    public Servlet getServlet()
     {
-        final boolean matches = matches(req.getPathInfo());
-        if (matches) {
+        return this.servlet;
+    }
+
+    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
+        {
+            path = req.getPathInfo();
+        }
+
+        final boolean matches = matches(path);
+        if (matches)
+        {
             doHandle(req, res);
         }
 
         return matches;
     }
 
-    private void doHandle(HttpServletRequest req, HttpServletResponse res)
-        throws ServletException, IOException
+    public void init() throws ServletException
+    {
+        this.servlet.init(new ServletConfigImpl(getName(), getContext(), getInitParams()));
+    }
+
+    public boolean matches(String uri)
+    {
+        // TODO handle wildcard aliases and extension specs...
+        if (uri == null)
+        {
+            return this.alias.equals("/");
+        }
+        else if (this.alias.equals("/"))
+        {
+            return uri.startsWith(this.alias);
+        }
+        else
+        {
+            return uri.equals(this.alias) || uri.startsWith(this.alias + "/");
+        }
+    }
+
+    final void doHandle(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException
     {
         // set a sensible status code in case handleSecurity returns false
         // but fails to send a response
@@ -93,12 +333,22 @@ public final class ServletHandler
             // reset status to OK for further processing
             res.setStatus(HttpServletResponse.SC_OK);
 
-            this.servlet.service(new ServletHandlerRequest(req, this.alias), res);
+            // Only wrap the original ServletRequest in case we're handling plain requests, 
+            // not inclusions or forwards from servlets. Should solve FELIX-2774 (partly)... 
+            if (DispatcherType.REQUEST == req.getDispatcherType())
+            {
+                this.servlet.service(new ServletHandlerRequest(req, getContext(), this.alias), res);
+            }
+            else
+            {
+                this.servlet.service(req, res);
+            }
         }
     }
 
-    public int compareTo(ServletHandler other)
+    @Override
+    protected Object getSubject()
     {
-        return other.alias.length() - this.alias.length();
+        return this.servlet;
     }
 }

Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/ServletHandlerRequest.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/ServletHandlerRequest.java?rev=1567561&r1=1567560&r2=1567561&view=diff
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/ServletHandlerRequest.java (original)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/handler/ServletHandlerRequest.java Wed Feb 12 08:25:05 2014
@@ -16,22 +16,35 @@
  */
 package org.apache.felix.http.base.internal.handler;
 
-import javax.servlet.http.HttpServletRequestWrapper;
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletContext;
 import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequestWrapper;
+import javax.servlet.http.HttpSession;
 
+import org.apache.felix.http.base.internal.context.ExtServletContext;
+import org.apache.felix.http.base.internal.dispatch.Dispatcher;
+import org.apache.felix.http.base.internal.dispatch.RequestDispatcherProvider;
+import org.apache.felix.http.base.internal.util.UriUtils;
 import org.osgi.service.http.HttpContext;
+import org.osgi.service.useradmin.Authorization;
 
-final class ServletHandlerRequest
-    extends HttpServletRequestWrapper
+/**
+ * @author <a href="mailto:dev@felix.apache.org">Felix Project Team</a>
+ */
+@SuppressWarnings("deprecation")
+class ServletHandlerRequest extends HttpServletRequestWrapper
 {
     private final String alias;
+    private final ServletContextWrapper context;
     private String contextPath;
     private String pathInfo;
     private boolean pathInfoCalculated = false;
 
-    public ServletHandlerRequest(HttpServletRequest req, String alias)
+    public ServletHandlerRequest(HttpServletRequest req, ExtServletContext context, String alias)
     {
         super(req);
+        this.context = new ServletContextWrapper(context, (RequestDispatcherProvider) req.getAttribute(Dispatcher.REQUEST_DISPATCHER_PROVIDER));
         this.alias = alias;
     }
 
@@ -39,7 +52,8 @@ final class ServletHandlerRequest
     public String getAuthType()
     {
         String authType = (String) getAttribute(HttpContext.AUTHENTICATION_TYPE);
-        if (authType != null) {
+        if (authType != null)
+        {
             return authType;
         }
 
@@ -53,14 +67,20 @@ final class ServletHandlerRequest
          * FELIX-2030 Calculate the context path for the Http Service
          * registered servlets from the container context and servlet paths
          */
-        if (contextPath == null) {
+        if (contextPath == null)
+        {
             final String context = super.getContextPath();
             final String servlet = super.getServletPath();
-            if (context.length() == 0) {
+            if (context == null || context.length() == 0)
+            {
                 contextPath = servlet;
-            } else if (servlet.length() == 0) {
+            }
+            else if (servlet == null || servlet.length() == 0)
+            {
                 contextPath = context;
-            } else {
+            }
+            else
+            {
                 contextPath = context + servlet;
             }
         }
@@ -71,7 +91,8 @@ final class ServletHandlerRequest
     @Override
     public String getPathInfo()
     {
-        if (!this.pathInfoCalculated) {
+        if (!this.pathInfoCalculated)
+        {
             this.pathInfo = calculatePathInfo();
             this.pathInfoCalculated = true;
         }
@@ -90,7 +111,8 @@ final class ServletHandlerRequest
     public String getRemoteUser()
     {
         String remoteUser = (String) getAttribute(HttpContext.REMOTE_USER);
-        if (remoteUser != null) {
+        if (remoteUser != null)
+        {
             return remoteUser;
         }
 
@@ -98,14 +120,68 @@ final class ServletHandlerRequest
     }
 
     @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 = UriUtils.concat(this.alias, path);
+        }
+        return super.getRequestDispatcher(path);
+    }
+
+    @Override
+    public ServletContext getServletContext()
+    {
+        return this.context;
+    }
+
+    @Override
     public String getServletPath()
     {
-        if ("/".equals(this.alias)) {
+        if ("/".equals(this.alias))
+        {
             return "";
         }
         return this.alias;
     }
 
+    @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.context);
+    }
+
+    @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 String calculatePathInfo()
     {
         /*
@@ -118,20 +194,20 @@ final class ServletHandlerRequest
          * Note, the servlet container pathInfo may also be null if the
          * servlet is registered as the root servlet
          */
-
         String pathInfo = super.getPathInfo();
-        if (pathInfo != null) {
-
+        if (pathInfo != null)
+        {
             // cut off alias of this servlet (if not the root servlet)
-            if (!"/".equals(alias)) {
+            if (!"/".equals(this.alias) && pathInfo.startsWith(this.alias))
+            {
                 pathInfo = pathInfo.substring(alias.length());
             }
 
             // ensure empty string is coerced to null
-            if (pathInfo.length() == 0) {
+            if (pathInfo.length() == 0)
+            {
                 pathInfo = null;
             }
-
         }
 
         return pathInfo;

Modified: felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/service/HttpServiceImpl.java
URL: http://svn.apache.org/viewvc/felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/service/HttpServiceImpl.java?rev=1567561&r1=1567560&r2=1567561&view=diff
==============================================================================
--- felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/service/HttpServiceImpl.java (original)
+++ felix/trunk/http/base/src/main/java/org/apache/felix/http/base/internal/service/HttpServiceImpl.java Wed Feb 12 08:25:05 2014
@@ -30,8 +30,7 @@ import org.osgi.framework.Bundle;
 import org.osgi.service.http.HttpContext;
 import org.osgi.service.http.NamespaceException;
 
-public final class HttpServiceImpl
-    implements ExtHttpService
+public final class HttpServiceImpl implements ExtHttpService
 {
     private final Bundle bundle;
     private final HandlerRegistry handlerRegistry;
@@ -39,33 +38,33 @@ public final class HttpServiceImpl
     private final HashSet<Filter> localFilters;
     private final ServletContextManager contextManager;
 
-    public HttpServiceImpl(Bundle bundle, ServletContext context, HandlerRegistry handlerRegistry,
-        ServletContextAttributeListener servletAttributeListener, boolean sharedContextAttributes)
+    public HttpServiceImpl(Bundle bundle, ServletContext context, HandlerRegistry handlerRegistry, ServletContextAttributeListener servletAttributeListener, boolean sharedContextAttributes)
     {
         this.bundle = bundle;
         this.handlerRegistry = handlerRegistry;
         this.localServlets = new HashSet<Servlet>();
         this.localFilters = new HashSet<Filter>();
-        this.contextManager = new ServletContextManager(this.bundle, context, servletAttributeListener,
-            sharedContextAttributes);
+        this.contextManager = new ServletContextManager(this.bundle, context, servletAttributeListener, sharedContextAttributes);
     }
 
     private ExtServletContext getServletContext(HttpContext context)
     {
-        if (context == null) {
+        if (context == null)
+        {
             context = createDefaultHttpContext();
         }
 
         return this.contextManager.getServletContext(context);
     }
 
-    public void registerFilter(Filter filter, String pattern, Dictionary initParams, int ranking, HttpContext context)
-        throws ServletException
+    public void registerFilter(Filter filter, String pattern, Dictionary initParams, int ranking, HttpContext context) throws ServletException
     {
-        if (filter == null ) {
+        if (filter == null)
+        {
             throw new IllegalArgumentException("Filter must not be null");
         }
-        FilterHandler handler = new FilterHandler(getServletContext(context), filter, pattern, ranking);
+        String filterName = null; // XXX
+        FilterHandler handler = new FilterHandler(getServletContext(context), filter, pattern, ranking, filterName);
         handler.setInitParams(initParams);
         this.handlerRegistry.addFilter(handler);
         this.localFilters.add(filter);
@@ -81,32 +80,37 @@ public final class HttpServiceImpl
         unregisterServlet(servlet, true);
     }
 
-    public void registerServlet(String alias, Servlet servlet, Dictionary initParams, HttpContext context)
-        throws ServletException, NamespaceException
+    public void registerServlet(String alias, Servlet servlet, Dictionary initParams, HttpContext context) throws ServletException, NamespaceException
     {
-        if (servlet == null ) {
+        if (servlet == null)
+        {
             throw new IllegalArgumentException("Servlet must not be null");
         }
-        if (!isAliasValid(alias)) {
-            throw new IllegalArgumentException( "Malformed servlet alias [" + alias + "]");
+        if (!isAliasValid(alias))
+        {
+            throw new IllegalArgumentException("Malformed servlet alias [" + alias + "]");
         }
-        ServletHandler handler = new ServletHandler(getServletContext(context), servlet, alias);
+        String servletName = null; // XXX
+        ServletHandler handler = new ServletHandler(getServletContext(context), servlet, alias, servletName);
         handler.setInitParams(initParams);
         this.handlerRegistry.addServlet(handler);
         this.localServlets.add(servlet);
     }
 
-    public void registerResources(String alias, String name, HttpContext context)
-        throws NamespaceException
+    public void registerResources(String alias, String name, HttpContext context) throws NamespaceException
     {
-        if (!isNameValid(name)) {
-            throw new IllegalArgumentException( "Malformed resource name [" + name + "]");
+        if (!isNameValid(name))
+        {
+            throw new IllegalArgumentException("Malformed resource name [" + name + "]");
         }
 
-        try {
+        try
+        {
             Servlet servlet = new ResourceServlet(name);
             registerServlet(alias, servlet, null, context);
-        } catch (ServletException e) {
+        }
+        catch (ServletException e)
+        {
             SystemLogger.error("Failed to register resources", e);
         }
     }
@@ -124,19 +128,22 @@ public final class HttpServiceImpl
     public void unregisterAll()
     {
         HashSet<Servlet> servlets = new HashSet<Servlet>(this.localServlets);
-        for (Servlet servlet : servlets) {
+        for (Servlet servlet : servlets)
+        {
             unregisterServlet(servlet, false);
         }
 
         HashSet<Filter> filters = new HashSet<Filter>(this.localFilters);
-        for (Filter fiter : filters) {
+        for (Filter fiter : filters)
+        {
             unregisterFilter(fiter, false);
         }
     }
 
     private void unregisterFilter(Filter filter, final boolean destroy)
     {
-        if (filter != null) {
+        if (filter != null)
+        {
             this.handlerRegistry.removeFilter(filter, destroy);
             this.localFilters.remove(filter);
         }
@@ -144,7 +151,8 @@ public final class HttpServiceImpl
 
     private void unregisterServlet(Servlet servlet, final boolean destroy)
     {
-        if (servlet != null) {
+        if (servlet != null)
+        {
             this.handlerRegistry.removeServlet(servlet, destroy);
             this.localServlets.remove(servlet);
         }
@@ -152,11 +160,13 @@ public final class HttpServiceImpl
 
     private boolean isNameValid(String name)
     {
-        if (name == null) {
+        if (name == null)
+        {
             return false;
         }
 
-        if (!name.equals("/") && name.endsWith( "/" )) {
+        if (!name.equals("/") && name.endsWith("/"))
+        {
             return false;
         }
 
@@ -165,11 +175,13 @@ public final class HttpServiceImpl
 
     private boolean isAliasValid(String alias)
     {
-        if (alias == null) {
+        if (alias == null)
+        {
             return false;
         }
 
-        if (!alias.equals("/") && ( !alias.startsWith("/") || alias.endsWith("/"))) {
+        if (!alias.equals("/") && (!alias.startsWith("/") || alias.endsWith("/")))
+        {
             return false;
         }
 



Mime
View raw message