From: markt Date: Mon, 7 Dec 2009 14:17:14 +0000 (+0000) Subject: Add async-supported impl for Servlets X-Git-Url: https://git.internetallee.de/?a=commitdiff_plain;h=63aae04fe684661254e0e8e696dcf275635dfd3a;p=tomcat7.0 Add async-supported impl for Servlets git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@887928 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/java/org/apache/catalina/Wrapper.java b/java/org/apache/catalina/Wrapper.java index bd684374f..fbefbd3c2 100644 --- a/java/org/apache/catalina/Wrapper.java +++ b/java/org/apache/catalina/Wrapper.java @@ -347,5 +347,17 @@ public interface Wrapper extends Container { * Set the multi-part configuration for the associated servlet. To clear the * multi-part configuration specify null as the new value. */ - public void setMultipartConfigElement(MultipartConfigElement multipartConfig); + public void setMultipartConfigElement( + MultipartConfigElement multipartConfig); + + /** + * Does the associated Servlet support async processing? Defaults to + * true + */ + public boolean isAsyncSupported(); + + /** + * Set the async support for the associated servlet. + */ + public void setAsyncSupported(boolean asyncSupport); } diff --git a/java/org/apache/catalina/core/ApplicationFilterChain.java b/java/org/apache/catalina/core/ApplicationFilterChain.java index 0082aada1..64df629e4 100644 --- a/java/org/apache/catalina/core/ApplicationFilterChain.java +++ b/java/org/apache/catalina/core/ApplicationFilterChain.java @@ -28,8 +28,10 @@ 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; @@ -273,11 +275,25 @@ final class ApplicationFilterChain implements FilterChain, CometFilterChain { support.fireInstanceEvent(InstanceEvent.BEFORE_SERVICE_EVENT, servlet, request, response); - if ((request instanceof HttpServletRequest) && + 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; + } + // Use potentially wrapped request from this point + if ((wRequest instanceof HttpServletRequest) && (response instanceof HttpServletResponse)) { if( Globals.IS_SECURITY_ENABLED ) { - final ServletRequest req = request; + final ServletRequest req = wRequest; final ServletResponse res = response; Principal principal = ((HttpServletRequest) req).getUserPrincipal(); @@ -289,11 +305,12 @@ final class ApplicationFilterChain implements FilterChain, CometFilterChain { principal); args = null; } else { - servlet.service(request, response); + servlet.service(wRequest, response); } } else { - servlet.service(request, response); + servlet.service(wRequest, response); } + // Stop using wrapped request now Servlet has been processed support.fireInstanceEvent(InstanceEvent.AFTER_SERVICE_EVENT, servlet, request, response); } catch (IOException e) { @@ -581,4 +598,30 @@ final class ApplicationFilterChain implements FilterChain, CometFilterChain { } + // --------------------------------- 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; + } + } + } diff --git a/java/org/apache/catalina/core/StandardWrapper.java b/java/org/apache/catalina/core/StandardWrapper.java index 90435d61f..5b8843443 100644 --- a/java/org/apache/catalina/core/StandardWrapper.java +++ b/java/org/apache/catalina/core/StandardWrapper.java @@ -260,6 +260,11 @@ public class StandardWrapper * Multipart config */ protected MultipartConfigElement multipartConfigElement = null; + + /** + * Async support + */ + protected boolean asyncSupported = true; /** * Static class array used when the SecurityManager is turned on and @@ -1502,6 +1507,15 @@ public class StandardWrapper this.multipartConfigElement = multipartConfigElement; } + @Override + public boolean isAsyncSupported() { + return asyncSupported; + } + + public void setAsyncSupported(boolean asyncSupported) { + this.asyncSupported = asyncSupported; + } + // -------------------------------------------------------- Package Methods diff --git a/java/org/apache/catalina/deploy/ServletDef.java b/java/org/apache/catalina/deploy/ServletDef.java index 9ec90ba0f..72e2a4b16 100644 --- a/java/org/apache/catalina/deploy/ServletDef.java +++ b/java/org/apache/catalina/deploy/ServletDef.java @@ -220,4 +220,18 @@ public class ServletDef implements Serializable { public void setMultipartDef(MultipartDef multipartDef) { this.multipartDef = multipartDef; } + + + /** + * Does this servlet support async. + */ + private String asyncSupported = null; + + public String getAsyncSupported() { + return this.asyncSupported; + } + + public void setAsyncSupported(String asyncSupported) { + this.asyncSupported = asyncSupported; + } } diff --git a/java/org/apache/catalina/startup/WebRuleSet.java b/java/org/apache/catalina/startup/WebRuleSet.java index 78a0564cf..3a3a3d25a 100644 --- a/java/org/apache/catalina/startup/WebRuleSet.java +++ b/java/org/apache/catalina/startup/WebRuleSet.java @@ -383,6 +383,10 @@ public class WebRuleSet extends RuleSetBase { digester.addCallMethod(fullPrefix + "/servlet/multipart-config/file-size-threshold", "setFileSizeThreshold", 0); + digester.addCallMethod(fullPrefix + "/servlet/async-supported", + "setAsyncSupported", 0); + + digester.addRule(fullPrefix + "/servlet-mapping", new CallMethodMultiRule("addServletMapping", 2, 0)); digester.addCallParam(fullPrefix + "/servlet-mapping/servlet-name", 1); diff --git a/java/org/apache/catalina/startup/WebXml.java b/java/org/apache/catalina/startup/WebXml.java index 82f8252a5..ba7a352c8 100644 --- a/java/org/apache/catalina/startup/WebXml.java +++ b/java/org/apache/catalina/startup/WebXml.java @@ -18,7 +18,6 @@ package org.apache.catalina.startup; -import java.io.File; import java.net.URL; import java.util.HashMap; import java.util.HashSet; @@ -30,7 +29,6 @@ import java.util.Map; import java.util.Set; import javax.servlet.MultipartConfigElement; -import javax.servlet.ServletContext; import org.apache.catalina.Context; import org.apache.catalina.Wrapper; @@ -517,9 +515,6 @@ public class WebXml { // messageDestinations were ignored in Tomcat 6, so ignore here - // TODO SERVLET3 - This needs to be more fine-grained. Whether or not to - // process annotations on destroy() will depend on where - // the filter/servlet was loaded from. Joy. context.setIgnoreAnnotations(metadataComplete); for (String extension : mimeMappings.keySet()) { context.addMimeMapping(extension, mimeMappings.get(extension)); @@ -582,6 +577,10 @@ public class WebXml { multipartdef.getLocation())); } } + if (servlet.getAsyncSupported() != null) { + wrapper.setAsyncSupported( + Boolean.parseBoolean(servlet.getAsyncSupported())); + } context.addChild(wrapper); } for (String pattern : servletMappings.keySet()) { @@ -1050,6 +1049,15 @@ public class WebXml { dest.getMultipartDef(), failOnConflict); } + if (dest.getAsyncSupported() == null) { + dest.setAsyncSupported(src.getAsyncSupported()); + } else if (src.getAsyncSupported() != null) { + if (failOnConflict && + !src.getAsyncSupported().equals(dest.getAsyncSupported())) { + return false; + } + } + return true; }