You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@felix.apache.org by cz...@apache.org on 2022/01/03 08:48:53 UTC

[felix-dev] branch master updated: FELIX-6498 : Support servlet api 4.0

This is an automated email from the ASF dual-hosted git repository.

cziegeler pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/felix-dev.git


The following commit(s) were added to refs/heads/master by this push:
     new 8d80e57  FELIX-6498 : Support servlet api 4.0
8d80e57 is described below

commit 8d80e57264136439b6b97d81fd0bb72c08bee4ba
Author: Carsten Ziegeler <cz...@apache.org>
AuthorDate: Mon Jan 3 09:48:45 2022 +0100

    FELIX-6498 : Support servlet api 4.0
---
 http/base/pom.xml                                  |  3 +-
 .../http/base/internal/dispatch/Dispatcher.java    | 12 ++---
 .../internal/dispatch/RequestDispatcherImpl.java   | 10 +++-
 .../http/base/internal/dispatch/RequestInfo.java   | 56 +++++++++++++++++++++-
 .../internal/dispatch/ServletRequestWrapper.java   | 32 +++++++++++--
 .../internal/dispatch/ServletResponseWrapper.java  |  8 ++--
 .../base/internal/registry/PathResolution.java     |  6 ++-
 .../base/internal/registry/ServletRegistry.java    |  4 +-
 .../base/internal/service/ServletContextImpl.java  | 48 ++++++++++++++++---
 .../whiteboard/PerBundleServletContextImpl.java    | 35 ++++++++++++++
 .../whiteboard/SharedServletContextImpl.java       | 47 +++++++++++++++---
 .../internal/context/ServletContextImplTest.java   | 43 +++++++++++++++++
 http/bridge/pom.xml                                |  5 +-
 http/itest/pom.xml                                 |  2 +-
 http/jetty/pom.xml                                 |  4 +-
 15 files changed, 276 insertions(+), 39 deletions(-)

diff --git a/http/base/pom.xml b/http/base/pom.xml
index 1924c90..84db8e3 100644
--- a/http/base/pom.xml
+++ b/http/base/pom.xml
@@ -46,6 +46,7 @@
         <dependency>
             <groupId>javax.servlet</groupId>
             <artifactId>javax.servlet-api</artifactId>
+            <version>4.0.1</version>
         </dependency>
         <dependency>
             <groupId>org.osgi</groupId>
@@ -78,7 +79,7 @@
         <dependency>
             <groupId>commons-fileupload</groupId>
             <artifactId>commons-fileupload</artifactId>
-            <version>1.3.3</version>
+            <version>1.4</version>
             <scope>provided</scope>
         </dependency>
     </dependencies>
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/Dispatcher.java b/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/Dispatcher.java
index 9c2fb35..47efa9b 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/Dispatcher.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/Dispatcher.java
@@ -75,7 +75,7 @@ public final class Dispatcher
         if ( mgr == null )
         {
             // not active, always return 404
-            if ( !res.isCommitted() ) 
+            if ( !res.isCommitted() )
             {
                 res.sendError(404);
             }
@@ -126,7 +126,7 @@ public final class Dispatcher
 		        final HttpServletResponse wrappedResponse = new ServletResponseWrapper(req, res, servletName, errorRegistry);
 		        if ( pr == null )
 		        {
-                    if ( !wrappedResponse.isCommitted() ) 
+                    if ( !wrappedResponse.isCommitted() )
                     {
                         wrappedResponse.sendError(404);
                     }
@@ -134,8 +134,7 @@ public final class Dispatcher
 		        }
 
 		        final ExtServletContext servletContext = pr.handler.getContext();
-		        final RequestInfo requestInfo = new RequestInfo(pr.servletPath, pr.pathInfo, null, req.getRequestURI());
-
+		        final RequestInfo requestInfo = new RequestInfo(pr.servletPath, pr.pathInfo, null, req.getRequestURI(), pr.handler.getName(), pr.matchedPattern, false);
 		        final HttpServletRequest wrappedRequest = new ServletRequestWrapper(req, servletContext, requestInfo, null,
 		                pr.handler.getServletInfo().isAsyncSupported(),
 		                pr.handler.getMultipartConfig(),
@@ -158,7 +157,7 @@ public final class Dispatcher
 		            req.setAttribute(RequestDispatcher.ERROR_EXCEPTION, e);
 		            req.setAttribute(RequestDispatcher.ERROR_EXCEPTION_TYPE, e.getClass().getName());
 
-                    if ( !wrappedResponse.isCommitted() ) 
+                    if ( !wrappedResponse.isCommitted() )
                     {
                         wrappedResponse.sendError(500);
                     }
@@ -169,7 +168,8 @@ public final class Dispatcher
 		            {
 		                servletContext.getServletRequestListener().requestDestroyed(new ServletRequestEvent(servletContext, wrappedRequest));
 		            }
-		        }			}
+		        }
+		    }
 
 			@Override
 			public void destroy()
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/RequestDispatcherImpl.java b/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/RequestDispatcherImpl.java
index 34427b2..ea9813c 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/RequestDispatcherImpl.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/RequestDispatcherImpl.java
@@ -29,6 +29,7 @@ import javax.servlet.http.HttpServletRequest;
 import org.apache.felix.http.base.internal.handler.FilterHandler;
 import org.apache.felix.http.base.internal.registry.ServletResolution;
 import org.apache.felix.http.base.internal.util.UriUtils;
+import org.jetbrains.annotations.NotNull;
 
 /**
  * Wrapper implementation for {@link RequestDispatcher}.
@@ -38,8 +39,13 @@ public final class RequestDispatcherImpl implements RequestDispatcher
     private final RequestInfo requestInfo;
     private final ServletResolution resolution;
 
-    public RequestDispatcherImpl(final ServletResolution resolution,
-            final RequestInfo requestInfo)
+    /**
+     * Create new dispatcher
+     * @param resolution The resolution
+     * @param requestInfo The request info
+     */
+    public RequestDispatcherImpl(@NotNull final ServletResolution resolution,
+            @NotNull final RequestInfo requestInfo)
     {
         this.resolution = resolution;
         this.requestInfo = requestInfo;
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/RequestInfo.java b/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/RequestInfo.java
index c9112dc..1b63f4f 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/RequestInfo.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/RequestInfo.java
@@ -16,22 +16,74 @@
  */
 package org.apache.felix.http.base.internal.dispatch;
 
-public final class RequestInfo
+import javax.servlet.http.HttpServletMapping;
+import javax.servlet.http.MappingMatch;
+
+/**
+ * Information about the request
+ */
+public final class RequestInfo implements HttpServletMapping
 {
     final String servletPath;
     final String pathInfo;
     final String queryString;
     final String requestURI;
+    private final String servletName;
+    private final String servletPattern;
+    private final MappingMatch match;
+    final boolean nameMatch;
 
+    /**
+     * Create a new request info
+     * @param servletPath The servlet path
+     * @param pathInfo The path info
+     * @param queryString The query string
+     * @param requestURI The request uri
+     * @param servletName The servlet name
+     * @param servletPattern The servlet pattern
+     * @param nameMatch Is named dispatcher
+     */
     public RequestInfo(final String servletPath,
             final String pathInfo,
             final String queryString,
-            final String requestURI)
+            final String requestURI,
+            final String servletName,
+            final String servletPattern,
+            final boolean nameMatch)
     {
         this.servletPath = servletPath;
         this.pathInfo = pathInfo;
         this.queryString = queryString;
         this.requestURI = requestURI;
+        this.servletName = servletName;
+        this.servletPattern = servletPattern;
+        if ( "".equals(servletPattern) ) {
+            this.match = MappingMatch.DEFAULT;
+        } else {
+            this.match = MappingMatch.PATH;
+        }
+        this.nameMatch = nameMatch;
+    }
+
+    @Override
+    public String getMatchValue() {
+        // TODO - this is wrong
+        return this.servletPattern;
+    }
+
+    @Override
+    public String getPattern() {
+        return this.servletPattern;
+    }
+
+    @Override
+    public String getServletName() {
+        return this.servletName;
+    }
+
+    @Override
+    public MappingMatch getMappingMatch() {
+        return this.match;
     }
 
     @Override
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/ServletRequestWrapper.java b/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/ServletRequestWrapper.java
index 09b98b6..0c676c5 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/ServletRequestWrapper.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/ServletRequestWrapper.java
@@ -17,11 +17,13 @@
 package org.apache.felix.http.base.internal.dispatch;
 
 import static javax.servlet.RequestDispatcher.FORWARD_CONTEXT_PATH;
+import static javax.servlet.RequestDispatcher.FORWARD_MAPPING;
 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_MAPPING;
 import static javax.servlet.RequestDispatcher.INCLUDE_PATH_INFO;
 import static javax.servlet.RequestDispatcher.INCLUDE_QUERY_STRING;
 import static javax.servlet.RequestDispatcher.INCLUDE_REQUEST_URI;
@@ -35,6 +37,7 @@ import java.security.AccessControlContext;
 import java.security.AccessController;
 import java.security.PrivilegedAction;
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Iterator;
 import java.util.List;
@@ -47,6 +50,7 @@ import javax.servlet.ServletException;
 import javax.servlet.ServletRequest;
 import javax.servlet.ServletRequestAttributeEvent;
 import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletMapping;
 import javax.servlet.http.HttpServletRequest;
 import javax.servlet.http.HttpServletRequestWrapper;
 import javax.servlet.http.HttpSession;
@@ -65,6 +69,11 @@ import org.osgi.service.useradmin.Authorization;
 
 final class ServletRequestWrapper extends HttpServletRequestWrapper
 {
+    private static final List<String> FORBIDDEN_ATTRIBUTES = Arrays.asList(FORWARD_CONTEXT_PATH,
+            FORWARD_MAPPING, FORWARD_PATH_INFO, FORWARD_QUERY_STRING, FORWARD_REQUEST_URI, FORWARD_SERVLET_PATH,
+            INCLUDE_CONTEXT_PATH, INCLUDE_MAPPING, INCLUDE_PATH_INFO, INCLUDE_QUERY_STRING, INCLUDE_REQUEST_URI,
+            INCLUDE_SERVLET_PATH);
+
     private final DispatcherType type;
     private final RequestInfo requestInfo;
     private final ExtServletContext servletContext;
@@ -96,7 +105,7 @@ final class ServletRequestWrapper extends HttpServletRequestWrapper
     public Object getAttribute(String name)
     {
         HttpServletRequest request = (HttpServletRequest) getRequest();
-        if (isInclusionDispatcher())
+        if (isInclusionDispatcher() && !this.requestInfo.nameMatch)
         {
             // The javax.servlet.include.* attributes refer to the information of the *included* request,
             // meaning that the request information comes from the *original* request...
@@ -120,8 +129,12 @@ final class ServletRequestWrapper extends HttpServletRequestWrapper
             {
                 return this.requestInfo.queryString;
             }
+            else if (INCLUDE_MAPPING.equals(name))
+            {
+                return this.requestInfo;
+            }
         }
-        else if (isForwardingDispatcher())
+        else if (isForwardingDispatcher() && !this.requestInfo.nameMatch)
         {
             // The javax.servlet.forward.* attributes refer to the information of the *original* request,
             // meaning that the request information comes from the *forwarded* request...
@@ -145,6 +158,13 @@ final class ServletRequestWrapper extends HttpServletRequestWrapper
             {
                 return super.getQueryString();
             }
+            else if (FORWARD_MAPPING.equals(name))
+            {
+                return super.getHttpServletMapping();
+            }
+        }
+        if ( FORBIDDEN_ATTRIBUTES.contains(name) ) {
+            return null;
         }
         return super.getAttribute(name);
     }
@@ -322,12 +342,12 @@ final class ServletRequestWrapper extends HttpServletRequestWrapper
 
     private boolean isForwardingDispatcher()
     {
-        return (DispatcherType.FORWARD == this.type) && (this.requestInfo != null);
+        return DispatcherType.FORWARD == this.type;
     }
 
     private boolean isInclusionDispatcher()
     {
-        return (DispatcherType.INCLUDE == this.type) && (this.requestInfo != null);
+        return DispatcherType.INCLUDE == this.type;
     }
 
     @Override
@@ -537,4 +557,8 @@ final class ServletRequestWrapper extends HttpServletRequestWrapper
         return null;
     }
 
+    @Override
+    public HttpServletMapping getHttpServletMapping() {
+        return this.requestInfo;
+    }
 }
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/ServletResponseWrapper.java b/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/ServletResponseWrapper.java
index 8c61d7f..28e9071 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/ServletResponseWrapper.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/dispatch/ServletResponseWrapper.java
@@ -19,8 +19,6 @@ package org.apache.felix.http.base.internal.dispatch;
 import java.io.IOException;
 import java.util.concurrent.atomic.AtomicInteger;
 
-import org.jetbrains.annotations.Nullable;
-import org.jetbrains.annotations.NotNull;
 import javax.servlet.DispatcherType;
 import javax.servlet.FilterChain;
 import javax.servlet.RequestDispatcher;
@@ -32,6 +30,8 @@ import javax.servlet.http.HttpServletResponseWrapper;
 import org.apache.felix.http.base.internal.handler.FilterHandler;
 import org.apache.felix.http.base.internal.handler.ServletHandler;
 import org.apache.felix.http.base.internal.registry.PerContextHandlerRegistry;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 
 final class ServletResponseWrapper extends HttpServletResponseWrapper
 {
@@ -86,7 +86,7 @@ final class ServletResponseWrapper extends HttpServletResponseWrapper
                 {
                     try
                     {
-                        request.setAttribute(RequestDispatcher.ERROR_STATUS_CODE, new Integer(code));
+                        request.setAttribute(RequestDispatcher.ERROR_STATUS_CODE, code);
                         if ( message != null )
                         {
                             request.setAttribute(RequestDispatcher.ERROR_MESSAGE, message);
@@ -101,7 +101,7 @@ final class ServletResponseWrapper extends HttpServletResponseWrapper
                         final String pathInfo = request.getRequestURI();
                         final String queryString = null; // XXX
 
-                        final RequestInfo requestInfo = new RequestInfo(servletPath, pathInfo, queryString, pathInfo);
+                        final RequestInfo requestInfo = new RequestInfo(servletPath, pathInfo, queryString, pathInfo, request.getHttpServletMapping().getServletName(), request.getHttpServletMapping().getPattern(), false);
 
                         final FilterHandler[] filterHandlers = errorRegistry.getFilterHandlers(errorResolution, DispatcherType.ERROR, request.getRequestURI());
 
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/registry/PathResolution.java b/http/base/src/main/java/org/apache/felix/http/base/internal/registry/PathResolution.java
index 8287f33..696c931 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/registry/PathResolution.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/registry/PathResolution.java
@@ -16,7 +16,9 @@
  */
 package org.apache.felix.http.base.internal.registry;
 
-
+/**
+ * Resolution of a servlet based on the path
+ */
 public class PathResolution extends ServletResolution {
 
     public String servletPath;
@@ -26,4 +28,6 @@ public class PathResolution extends ServletResolution {
     public String requestURI;
 
     public String[] patterns;
+
+    public String matchedPattern;
 }
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/registry/ServletRegistry.java b/http/base/src/main/java/org/apache/felix/http/base/internal/registry/ServletRegistry.java
index e849278..ef40fa6 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/registry/ServletRegistry.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/registry/ServletRegistry.java
@@ -29,13 +29,12 @@ import java.util.Set;
 import java.util.TreeMap;
 import java.util.concurrent.ConcurrentHashMap;
 
-import org.jetbrains.annotations.NotNull;
-
 import org.apache.felix.http.base.internal.handler.ServletHandler;
 import org.apache.felix.http.base.internal.runtime.ServletInfo;
 import org.apache.felix.http.base.internal.runtime.dto.BuilderConstants;
 import org.apache.felix.http.base.internal.runtime.dto.ResourceDTOBuilder;
 import org.apache.felix.http.base.internal.runtime.dto.ServletDTOBuilder;
+import org.jetbrains.annotations.NotNull;
 import org.osgi.service.http.runtime.dto.DTOConstants;
 import org.osgi.service.http.runtime.dto.FailedResourceDTO;
 import org.osgi.service.http.runtime.dto.FailedServletDTO;
@@ -81,6 +80,7 @@ public final class ServletRegistry
             {
                 // TODO - we should have all patterns under which this servlet is actively registered
                 pr.patterns = new String[] {entry.getPattern()};
+                pr.matchedPattern = entry.getPattern();
                 return pr;
             }
         }
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/service/ServletContextImpl.java b/http/base/src/main/java/org/apache/felix/http/base/internal/service/ServletContextImpl.java
index 9e9b499..fddff41 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/service/ServletContextImpl.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/service/ServletContextImpl.java
@@ -38,6 +38,7 @@ import javax.servlet.ServletContext;
 import javax.servlet.ServletContextAttributeEvent;
 import javax.servlet.ServletException;
 import javax.servlet.ServletRegistration;
+import javax.servlet.ServletRegistration.Dynamic;
 import javax.servlet.ServletRequestAttributeListener;
 import javax.servlet.ServletRequestListener;
 import javax.servlet.SessionCookieConfig;
@@ -508,7 +509,7 @@ public class ServletContextImpl implements ExtServletContext
         	resolution.handler = servletHandler;
             resolution.handlerRegistry = this.handlerRegistry;
             // TODO - what is the path of a named servlet?
-            final RequestInfo requestInfo = new RequestInfo("", null, null, null);
+            final RequestInfo requestInfo = new RequestInfo("", null, null, null, null, "", true);
             dispatcher = new RequestDispatcherImpl(resolution, requestInfo);
         }
         else
@@ -542,11 +543,10 @@ public class ServletContextImpl implements ExtServletContext
         final PathResolution pathResolution = this.handlerRegistry.resolve(requestURI);
         if ( pathResolution != null )
         {
-        	final ServletResolution resolution = new ServletResolution();
-        	resolution.handler = pathResolution.handler;
-            resolution.handlerRegistry = this.handlerRegistry;
-            final RequestInfo requestInfo = new RequestInfo(pathResolution.servletPath, pathResolution.pathInfo, query, UriUtils.concat(this.getContextPath(), encodedRequestURI));
-            dispatcher = new RequestDispatcherImpl(resolution, requestInfo);
+            pathResolution.handlerRegistry = this.handlerRegistry;
+            final RequestInfo requestInfo = new RequestInfo(pathResolution.servletPath, pathResolution.pathInfo, query, UriUtils.concat(this.getContextPath(), encodedRequestURI),
+                    pathResolution.handler.getName(), pathResolution.matchedPattern, false);
+            dispatcher = new RequestDispatcherImpl(pathResolution, requestInfo);
         }
         else
         {
@@ -555,6 +555,42 @@ public class ServletContextImpl implements ExtServletContext
         return dispatcher;
     }
 
+
+    @Override
+    public Dynamic addJspFile(final String servletName, final String jspFile) {
+        throw new IllegalStateException();
+    }
+
+    @Override
+    public int getSessionTimeout() {
+        return context.getSessionTimeout();
+    }
+
+    @Override
+    public void setSessionTimeout(final int sessionTimeout) {
+        throw new IllegalStateException();
+    }
+
+    @Override
+    public String getRequestCharacterEncoding() {
+        return context.getRequestCharacterEncoding();
+    }
+
+    @Override
+    public void setRequestCharacterEncoding(final String encoding) {
+        throw new IllegalStateException();
+    }
+
+    @Override
+    public String getResponseCharacterEncoding() {
+        return context.getResponseCharacterEncoding();
+    }
+
+    @Override
+    public void setResponseCharacterEncoding(final String encoding) {
+        throw new IllegalStateException();
+    }
+
     @Override
     public HttpConfig getConfig()
     {
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/PerBundleServletContextImpl.java b/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/PerBundleServletContextImpl.java
index 8230270..5fcb4a3 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/PerBundleServletContextImpl.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/PerBundleServletContextImpl.java
@@ -461,4 +461,39 @@ public class PerBundleServletContextImpl implements ExtServletContext {
     {
         return delegatee.getVirtualServerName();
     }
+
+    @Override
+    public Dynamic addJspFile(final String servletName, final String jspFile) {
+        return this.delegatee.addJspFile(servletName, jspFile);
+    }
+
+    @Override
+    public int getSessionTimeout() {
+        return this.delegatee.getSessionTimeout();
+    }
+
+    @Override
+    public void setSessionTimeout(final int sessionTimeout) {
+        this.delegatee.setSessionTimeout(sessionTimeout);
+    }
+
+    @Override
+    public String getRequestCharacterEncoding() {
+        return this.delegatee.getRequestCharacterEncoding();
+    }
+
+    @Override
+    public void setRequestCharacterEncoding(final String encoding) {
+        this.delegatee.setRequestCharacterEncoding(encoding);
+    }
+
+    @Override
+    public String getResponseCharacterEncoding() {
+        return this.delegatee.getResponseCharacterEncoding();
+    }
+
+    @Override
+    public void setResponseCharacterEncoding(final String encoding) {
+        this.delegatee.setRequestCharacterEncoding(encoding);
+    }
 }
diff --git a/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/SharedServletContextImpl.java b/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/SharedServletContextImpl.java
index f858bdf..5f74092 100644
--- a/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/SharedServletContextImpl.java
+++ b/http/base/src/main/java/org/apache/felix/http/base/internal/whiteboard/SharedServletContextImpl.java
@@ -38,6 +38,7 @@ import javax.servlet.ServletContextAttributeEvent;
 import javax.servlet.ServletContextAttributeListener;
 import javax.servlet.ServletException;
 import javax.servlet.ServletRegistration;
+import javax.servlet.ServletRegistration.Dynamic;
 import javax.servlet.SessionCookieConfig;
 import javax.servlet.SessionTrackingMode;
 import javax.servlet.descriptor.JspConfigDescriptor;
@@ -319,7 +320,7 @@ public class SharedServletContextImpl implements ServletContext
         	resolution.handler = servletHandler;
             resolution.handlerRegistry = this.registry;
             // TODO - what is the path of a named servlet?
-            final RequestInfo requestInfo = new RequestInfo("", null, null, null);
+            final RequestInfo requestInfo = new RequestInfo("", null, null, null, null, "", true);
             dispatcher = new RequestDispatcherImpl(resolution, requestInfo);
         }
         else
@@ -353,12 +354,11 @@ public class SharedServletContextImpl implements ServletContext
         final PathResolution pathResolution = this.registry.resolve(requestURI);
         if ( pathResolution != null )
         {
-        	final ServletResolution resolution = new ServletResolution();
-        	resolution.handler = pathResolution.handler;
-            resolution.handlerRegistry = this.registry;
+            pathResolution.handlerRegistry = this.registry;
             final RequestInfo requestInfo = new RequestInfo(pathResolution.servletPath, pathResolution.pathInfo, query,
-                    UriUtils.concat(this.contextPath, encodedRequestURI));
-            dispatcher = new RequestDispatcherImpl(resolution, requestInfo);
+                    UriUtils.concat(this.contextPath, encodedRequestURI),
+                    pathResolution.handler.getName(), pathResolution.matchedPattern, false);
+            dispatcher = new RequestDispatcherImpl(pathResolution, requestInfo);
         }
         else
         {
@@ -487,4 +487,39 @@ public class SharedServletContextImpl implements ServletContext
     {
         throw new IllegalStateException();
     }
+
+    @Override
+    public Dynamic addJspFile(final String servletName, final String jspFile) {
+        throw new IllegalStateException();
+    }
+
+    @Override
+    public int getSessionTimeout() {
+        return context.getSessionTimeout();
+    }
+
+    @Override
+    public void setSessionTimeout(final int sessionTimeout) {
+        throw new IllegalStateException();
+    }
+
+    @Override
+    public String getRequestCharacterEncoding() {
+        return context.getRequestCharacterEncoding();
+    }
+
+    @Override
+    public void setRequestCharacterEncoding(final String encoding) {
+        throw new IllegalStateException();
+    }
+
+    @Override
+    public String getResponseCharacterEncoding() {
+        return context.getResponseCharacterEncoding();
+    }
+
+    @Override
+    public void setResponseCharacterEncoding(final String encoding) {
+        throw new IllegalStateException();
+    }
 }
diff --git a/http/base/src/test/java/org/apache/felix/http/base/internal/context/ServletContextImplTest.java b/http/base/src/test/java/org/apache/felix/http/base/internal/context/ServletContextImplTest.java
index 24b6523..50dd584 100644
--- a/http/base/src/test/java/org/apache/felix/http/base/internal/context/ServletContextImplTest.java
+++ b/http/base/src/test/java/org/apache/felix/http/base/internal/context/ServletContextImplTest.java
@@ -39,6 +39,7 @@ import javax.servlet.ServletContextAttributeEvent;
 import javax.servlet.ServletContextAttributeListener;
 import javax.servlet.ServletException;
 import javax.servlet.ServletRegistration;
+import javax.servlet.ServletRegistration.Dynamic;
 import javax.servlet.SessionCookieConfig;
 import javax.servlet.SessionTrackingMode;
 import javax.servlet.descriptor.JspConfigDescriptor;
@@ -453,6 +454,48 @@ public class ServletContextImplTest
         public void setSessionTrackingModes(Set<SessionTrackingMode> modes)
         {
         }
+
+        @Override
+        public Dynamic addJspFile(String servletName, String jspFile) {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public int getSessionTimeout() {
+            // TODO Auto-generated method stub
+            return 0;
+        }
+
+        @Override
+        public void setSessionTimeout(int sessionTimeout) {
+            // TODO Auto-generated method stub
+
+        }
+
+        @Override
+        public String getRequestCharacterEncoding() {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public void setRequestCharacterEncoding(String encoding) {
+            // TODO Auto-generated method stub
+
+        }
+
+        @Override
+        public String getResponseCharacterEncoding() {
+            // TODO Auto-generated method stub
+            return null;
+        }
+
+        @Override
+        public void setResponseCharacterEncoding(String encoding) {
+            // TODO Auto-generated method stub
+
+        }
     }
 
     private Bundle bundle;
diff --git a/http/bridge/pom.xml b/http/bridge/pom.xml
index dd2b90f..14018ba 100644
--- a/http/bridge/pom.xml
+++ b/http/bridge/pom.xml
@@ -111,6 +111,7 @@
         <dependency>
             <groupId>javax.servlet</groupId>
             <artifactId>javax.servlet-api</artifactId>
+            <version>4.0.1</version>
         </dependency>
         <dependency>
             <groupId>org.osgi</groupId>
@@ -131,7 +132,7 @@
         <dependency>
             <groupId>commons-fileupload</groupId>
             <artifactId>commons-fileupload</artifactId>
-            <version>1.3.3</version>
+            <version>1.4</version>
         </dependency>
         <dependency>
             <groupId>commons-io</groupId>
@@ -141,7 +142,7 @@
         <dependency>
             <groupId>org.apache.felix</groupId>
             <artifactId>org.apache.felix.http.base</artifactId>
-            <version>4.1.6</version>
+            <version>4.1.7-SNAPSHOT</version>
         </dependency>
     </dependencies>
 
diff --git a/http/itest/pom.xml b/http/itest/pom.xml
index 4566d3e..444b451 100644
--- a/http/itest/pom.xml
+++ b/http/itest/pom.xml
@@ -34,7 +34,7 @@
         <felix.java.version>8</felix.java.version>
         <pax.exam.version>4.13.1</pax.exam.version>
         <pax.url.aether.version>2.6.2</pax.url.aether.version>
-        <http.servlet.api.version>1.1.2</http.servlet.api.version>
+        <http.servlet.api.version>1.1.5-SNAPSHOT</http.servlet.api.version>
         <http.jetty.version>4.1.15-SNAPSHOT</http.jetty.version>
     </properties>
 
diff --git a/http/jetty/pom.xml b/http/jetty/pom.xml
index 9587234..99bd77d 100644
--- a/http/jetty/pom.xml
+++ b/http/jetty/pom.xml
@@ -207,7 +207,7 @@
                             osgi.serviceloader;osgi.serviceloader="org.eclipse.jetty.http.HttpFieldPreEncoder"
                         </Provide-Capability>
                         <Require-Capability>
-                            osgi.contract;filter:="(&amp;(osgi.contract=JavaServlet)(version=3.1))",
+                            osgi.contract;filter:="(&amp;(osgi.contract=JavaServlet)(version=4.0))",
                             osgi.extender;filter:="(osgi.extender=osgi.serviceloader.registrar)";resolution:=optional,
                             osgi.extender;filter:="(osgi.extender=osgi.serviceloader.processor)";resolution:=optional,
                             osgi.serviceloader;filter:="(osgi.serviceloader=org.eclipse.jetty.http.HttpFieldPreEncoder)";resolution:=optional;cardinality:=multiple,
@@ -404,7 +404,7 @@
         <dependency>
             <groupId>commons-fileupload</groupId>
             <artifactId>commons-fileupload</artifactId>
-            <version>1.3.3</version>
+            <version>1.4</version>
         </dependency>
         <dependency>
             <groupId>commons-io</groupId>