Add support for WebFilter
authormarkt <markt@13f79535-47bb-0310-9956-ffa450edef68>
Mon, 7 Dec 2009 16:43:25 +0000 (16:43 +0000)
committermarkt <markt@13f79535-47bb-0310-9956-ffa450edef68>
Mon, 7 Dec 2009 16:43:25 +0000 (16:43 +0000)
Remove wrappers to implement isAsyncSupported() having found the setAttribute() code
It is individual filters rather than the whole filter chain that need to be considered for isAsyncSupported

git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@887992 13f79535-47bb-0310-9956-ffa450edef68

java/org/apache/catalina/core/ApplicationDispatcher.java
java/org/apache/catalina/core/ApplicationFilterChain.java
java/org/apache/catalina/core/StandardWrapperValve.java
java/org/apache/catalina/deploy/FilterDef.java
java/org/apache/catalina/startup/ContextConfig.java
java/org/apache/catalina/startup/WebXml.java

index 74b2dff..f5248b3 100644 (file)
@@ -641,15 +641,6 @@ final class ApplicationDispatcher
         ApplicationFilterChain filterChain = factory.createFilterChain(request,
                                                                 wrapper,servlet);
         
-        Object origAsyncSupported = request.getAttribute(Globals.ASYNC_SUPPORTED_ATTR);
-        //we have a new filter chain, setup isAsyncSupported here
-        boolean filterAsyncSupported = filterChain.isAsyncSupported();
-        if (!filterAsyncSupported && request.isAsyncSupported()) {
-            //the request says we support it, but the filters don't
-            //TODO SERVLET3 - async
-            request.setAttribute(Globals.ASYNC_SUPPORTED_ATTR, Boolean.FALSE);
-        }
-        
         // Call the service() method for the allocated servlet instance
         try {
             String jspFile = wrapper.getJspFile();
@@ -704,8 +695,6 @@ final class ApplicationDispatcher
             wrapper.getLogger().error(sm.getString("applicationDispatcher.serviceException",
                              wrapper.getName()), e);
             runtimeException = e;
-        } finally {
-            request.setAttribute(Globals.ASYNC_SUPPORTED_ATTR, origAsyncSupported);
         }
 
         // Release the filter chain (if any) for this request
@@ -715,7 +704,7 @@ final class ApplicationDispatcher
         } catch (Throwable e) {
             wrapper.getLogger().error(sm.getString("standardWrapper.releaseFilters",
                              wrapper.getName()), e);
-            // FIXME: Exception handling needs to be simpiler to what is in the StandardWrapperValue
+            // FIXME: Exception handling needs to be simpler to what is in the StandardWrapperValue
         }
 
         // Deallocate the allocated servlet instance
index 64df629..438d92c 100644 (file)
@@ -28,10 +28,8 @@ import javax.servlet.FilterChain;
 import javax.servlet.Servlet;
 import javax.servlet.ServletException;
 import javax.servlet.ServletRequest;
-import javax.servlet.ServletRequestWrapper;
 import javax.servlet.ServletResponse;
 import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletRequestWrapper;
 import javax.servlet.http.HttpServletResponse;
 
 import org.apache.catalina.Globals;
@@ -224,6 +222,11 @@ final class ApplicationFilterChain implements FilterChain, CometFilterChain {
                 support.fireInstanceEvent(InstanceEvent.BEFORE_FILTER_EVENT,
                                           filter, request, response);
                 
+                if (request.isAsyncSupported() && "false".equalsIgnoreCase(
+                        filterConfig.getFilterDef().getAsyncSupported())) {
+                    request.setAttribute(Globals.ASYNC_SUPPORTED_ATTR,
+                            Boolean.FALSE);
+                }
                 if( Globals.IS_SECURITY_ENABLED ) {
                     final ServletRequest req = request;
                     final ServletResponse res = response;
@@ -275,25 +278,17 @@ final class ApplicationFilterChain implements FilterChain, CometFilterChain {
 
             support.fireInstanceEvent(InstanceEvent.BEFORE_SERVICE_EVENT,
                                       servlet, request, response);
-            ServletRequest wRequest; 
             if (request.isAsyncSupported()
                     && !support.getWrapper().isAsyncSupported()) {
-                if (request instanceof HttpServletRequest) {
-                    wRequest = new HttpServletRequestNoAsyc(
-                            (HttpServletRequest) request);
-                } else {
-                    // Must be a ServletRequest
-                    wRequest = new ServletRequestNoAsyc(request);
-                }
-            } else {
-                wRequest = request;
+                request.setAttribute(Globals.ASYNC_SUPPORTED_ATTR,
+                        Boolean.FALSE);
             }
             // Use potentially wrapped request from this point
-            if ((wRequest instanceof HttpServletRequest) &&
+            if ((request instanceof HttpServletRequest) &&
                 (response instanceof HttpServletResponse)) {
                     
                 if( Globals.IS_SECURITY_ENABLED ) {
-                    final ServletRequest req = wRequest;
+                    final ServletRequest req = request;
                     final ServletResponse res = response;
                     Principal principal = 
                         ((HttpServletRequest) req).getUserPrincipal();
@@ -305,12 +300,11 @@ final class ApplicationFilterChain implements FilterChain, CometFilterChain {
                                                principal);   
                     args = null;
                 } else {  
-                    servlet.service(wRequest, response);
+                    servlet.service(request, response);
                 }
             } else {
-                servlet.service(wRequest, response);
+                servlet.service(request, response);
             }
-            // Stop using wrapped request now Servlet has been processed
             support.fireInstanceEvent(InstanceEvent.AFTER_SERVICE_EVENT,
                                       servlet, request, response);
         } catch (IOException e) {
@@ -586,42 +580,4 @@ final class ApplicationFilterChain implements FilterChain, CometFilterChain {
         this.support = support;
 
     }
-    
-    public boolean isAsyncSupported() {
-        boolean supported = true;
-        for (ApplicationFilterConfig config : filters) {
-            if (config!=null && config.getFilterDef()!=null) {
-                supported = supported & config.getFilterDef().isAsyncSupported();
-            }
-        }
-        return supported;
-    }
-
-
-    // --------------------------------- Wrapper classes for isAsyncSupported()
-    
-    private class HttpServletRequestNoAsyc extends HttpServletRequestWrapper {
-
-        public HttpServletRequestNoAsyc(HttpServletRequest request) {
-            super(request);
-        }
-        
-        @Override
-        public boolean isAsyncSupported() {
-            return false;
-        }
-    }
-
-    private class ServletRequestNoAsyc extends ServletRequestWrapper {
-
-        public ServletRequestNoAsyc(ServletRequest request) {
-            super(request);
-        }
-        
-        @Override
-        public boolean isAsyncSupported() {
-            return false;
-        }
-    }
-
 }
index 542ffc1..01fd140 100644 (file)
@@ -203,10 +203,6 @@ final class StandardWrapperValve
         
         // Reset comet flag value after creating the filter chain
         request.setComet(false);
-        //check filters to see if we support async or not.
-        if (filterChain != null && request.isAsyncSupported()) {
-            request.setAsyncSupported(filterChain.isAsyncSupported());
-        }
 
         // Call the filter chain for this request
         // NOTE: This also calls the servlet's service() method
index a3ddd40..c1a4833 100644 (file)
@@ -136,13 +136,13 @@ public class FilterDef implements Serializable {
         this.smallIcon = smallIcon;
     }
     
-    private boolean asyncSupported = false;
+    private String asyncSupported = null;
     
-    public boolean isAsyncSupported() {
+    public String getAsyncSupported() {
         return asyncSupported;
     }
-    
-    public void setAsyncSupported(boolean asyncSupported) {
+
+    public void setAsyncSupported(String asyncSupported) {
         this.asyncSupported = asyncSupported;
     }
 
index fcd3832..0b2cc1a 100644 (file)
@@ -1673,10 +1673,11 @@ public class ContextConfig
             String type = ae.getAnnotationType();
             if ("Ljavax/servlet/annotation/WebServlet;".equals(type)) {
                 processAnnotationWebServlet(className, ae, fragment);
+            }else if ("Ljavax/servlet/annotation/WebFilter;".equals(type)) {
+                processAnnotationWebFilter(className, ae, fragment);
             }else if ("Ljavax/servlet/annotation/WebListener;".equals(type)) {
                 fragment.addListener(className);
             } else {
-                // TODO SERVLET 3 - Other annotations
                 // Unknown annotation - ignore
             }
         }
@@ -1688,22 +1689,22 @@ public class ContextConfig
             // Skip this annotation. Entry in web.xml takes priority
             return;
         }
-        boolean mappingSet = false;
+        boolean urlPatternsSet = false;
         ServletDef servletDef = new ServletDef();
         servletDef.setServletName(className);
         servletDef.setServletClass(className);
-        String[] mappings = null;
+        String[] urlPatterns = null;
 
         ElementValuePair[] evps = ae.getElementValuePairs();
         for (ElementValuePair evp : evps) {
             String name = evp.getNameString();
             if ("value".equals(name) || "urlPatterns".equals(name)) {
-                if (mappingSet) {
+                if (urlPatternsSet) {
                     throw new IllegalArgumentException(sm.getString(
                             "contextConfig.urlPatternValue", className));
                 }
-                mappingSet = true;
-                mappings = processAnnotationsUrlPatterns(evp.getValue());
+                urlPatternsSet = true;
+                urlPatterns = processAnnotationsStringArray(evp.getValue());
             } else if ("name".equals(name)) {
                 servletDef.setServletName(evp.getValue().stringifyValue());
             } else if ("description".equals(name)) {
@@ -1729,16 +1730,82 @@ public class ContextConfig
                 // Ignore
             }
         }
-        if (mappings != null) {
+        if (urlPatterns != null) {
             fragment.addServlet(servletDef);
-            for (String mapping : mappings) {
-                fragment.addServletMapping(mapping,
+            for (String urlPattern : urlPatterns) {
+                fragment.addServletMapping(urlPattern,
                         servletDef.getServletName());
             }
         }
     }
 
-    protected String[] processAnnotationsUrlPatterns(ElementValue ev) {
+    protected void processAnnotationWebFilter(String className,
+            AnnotationEntry ae, WebXml fragment) {
+        if (fragment.getFilters().containsKey(className)) {
+            // Skip this annotation. Entry in web.xml takes priority
+            return;
+        }
+        boolean urlPatternsSet = false;
+        FilterDef filterDef = new FilterDef();
+        FilterMap filterMap = new FilterMap();
+        filterDef.setFilterName(className);
+        filterDef.setFilterClass(className);
+        String[] urlPatterns = null;
+
+        ElementValuePair[] evps = ae.getElementValuePairs();
+        for (ElementValuePair evp : evps) {
+            String name = evp.getNameString();
+            if ("value".equals(name) || "urlPatterns".equals(name)) {
+                if (urlPatternsSet) {
+                    throw new IllegalArgumentException(sm.getString(
+                            "contextConfig.urlPatternValue", className));
+                }
+                urlPatternsSet = true;
+                urlPatterns = processAnnotationsStringArray(evp.getValue());
+                for (String urlPattern : urlPatterns) {
+                    filterMap.addURLPattern(urlPattern);
+                }
+            } else if ("filterName".equals(name)) {
+                filterDef.setFilterName(evp.getValue().stringifyValue());
+            } else if ("servletNames".equals(name)) {
+                String[] servletNames =
+                    processAnnotationsStringArray(evp.getValue());
+                for (String servletName : servletNames) {
+                    filterMap.addServletName(servletName);
+                }
+            } else if ("dispatcherTypes".equals(name)) {
+                String[] dispatcherTypes =
+                    processAnnotationsStringArray(evp.getValue());
+                for (String dispatcherType : dispatcherTypes) {
+                    filterMap.setDispatcher(dispatcherType);
+                }
+            } else if ("description".equals(name)) {
+                filterDef.setDescription(evp.getValue().stringifyValue());
+            } else if ("displayName".equals(name)) {
+                filterDef.setDisplayName(evp.getValue().stringifyValue());
+            } else if ("largeIcon".equals(name)) {
+                filterDef.setLargeIcon(evp.getValue().stringifyValue());
+            } else if ("smallIcon".equals(name)) {
+                filterDef.setSmallIcon(evp.getValue().stringifyValue());
+            } else if ("asyncSupported".equals(name)) {
+                filterDef.setAsyncSupported(evp.getValue().stringifyValue());
+            } else if ("initParams".equals(name)) {
+                Map<String,String> initParams =
+                    processAnnotationWebInitParams(evp.getValue());
+                for (String paramName : initParams.keySet()) {
+                    filterDef.addInitParameter(paramName,
+                            initParams.get(paramName));
+                }
+            } else {
+                // Ignore
+            }
+        }
+        fragment.addFilter(filterDef);
+        filterMap.setFilterName(filterDef.getFilterName());
+        fragment.addFilterMapping(filterMap);
+    }
+
+    protected String[] processAnnotationsStringArray(ElementValue ev) {
         ArrayList<String> values = new ArrayList<String>();
         if (ev instanceof ArrayElementValue) {
             ElementValue[] arrayValues =
index ba7a352..06643fb 100644 (file)
@@ -962,11 +962,15 @@ public class WebXml {
     }
     
     private boolean mergeFilter(FilterDef src, FilterDef dest, boolean failOnConflict) {
-        if (src.isAsyncSupported() != dest.isAsyncSupported()) {
-            // Always fail
-            return false;
+        if (dest.getAsyncSupported() == null) {
+            dest.setAsyncSupported(src.getAsyncSupported());
+        } else if (src.getAsyncSupported() != null) {
+            if (failOnConflict &&
+                    !src.getAsyncSupported().equals(dest.getAsyncSupported())) {
+                return false;
+            }
         }
-        
+
         if (dest.getFilterClass()  == null) {
             dest.setFilterClass(src.getFilterClass());
         } else if (src.getFilterClass() != null) {