Author: violetagg
Date: Wed Jun 26 07:48:36 2013
New Revision: 1496809
URL: http://svn.apache.org/r1496809
Log:
Merged revisions 1496732, 1496734 from tomcat/trunk:
When AsyncContext.dispatch(...) is invoked do not cast request and response to
HttpServletRequest/HttpServletResponse.
ServletRequest.startAsync(ServletRequest,ServletResponse) can be invoked with
custom ServletRequest/ServletResponse.
Modified:
tomcat/tc7.0.x/trunk/ (props changed)
tomcat/tc7.0.x/trunk/java/org/apache/catalina/core/AsyncContextImpl.java
tomcat/tc7.0.x/trunk/test/org/apache/catalina/core/TestAsyncContextImpl.java
tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml
Propchange: tomcat/tc7.0.x/trunk/
------------------------------------------------------------------------------
Merged /tomcat/trunk:r1496732,1496734
Modified:
tomcat/tc7.0.x/trunk/java/org/apache/catalina/core/AsyncContextImpl.java
URL:
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/java/org/apache/catalina/core/AsyncContextImpl.java?rev=1496809&r1=1496808&r2=1496809&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/java/org/apache/catalina/core/AsyncContextImpl.java
(original)
+++ tomcat/tc7.0.x/trunk/java/org/apache/catalina/core/AsyncContextImpl.java
Wed Jun 26 07:48:36 2013
@@ -168,9 +168,17 @@ public class AsyncContextImpl implements
@Override
public void dispatch() {
check();
- HttpServletRequest sr = (HttpServletRequest)getRequest();
- String path = sr.getRequestURI();
- String cpath = sr.getContextPath();
+ String path;
+ String cpath;
+ ServletRequest servletRequest = getRequest();
+ if (servletRequest instanceof HttpServletRequest) {
+ HttpServletRequest sr = (HttpServletRequest) servletRequest;
+ path = sr.getRequestURI();
+ cpath = sr.getContextPath();
+ } else {
+ path = request.getRequestURI();
+ cpath = request.getContextPath();
+ }
if (cpath.length()>1) path = path.substring(cpath.length());
dispatch(path);
}
@@ -205,10 +213,8 @@ public class AsyncContextImpl implements
}
final AsyncDispatcher applicationDispatcher =
(AsyncDispatcher) requestDispatcher;
- final HttpServletRequest servletRequest =
- (HttpServletRequest) getRequest();
- final HttpServletResponse servletResponse =
- (HttpServletResponse) getResponse();
+ final ServletRequest servletRequest = getRequest();
+ final ServletResponse servletResponse = getResponse();
Runnable run = new Runnable() {
@Override
public void run() {
Modified:
tomcat/tc7.0.x/trunk/test/org/apache/catalina/core/TestAsyncContextImpl.java
URL:
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/test/org/apache/catalina/core/TestAsyncContextImpl.java?rev=1496809&r1=1496808&r2=1496809&view=diff
==============================================================================
---
tomcat/tc7.0.x/trunk/test/org/apache/catalina/core/TestAsyncContextImpl.java
(original)
+++
tomcat/tc7.0.x/trunk/test/org/apache/catalina/core/TestAsyncContextImpl.java
Wed Jun 26 07:48:36 2013
@@ -30,11 +30,15 @@ import javax.servlet.AsyncContext;
import javax.servlet.AsyncEvent;
import javax.servlet.AsyncListener;
import javax.servlet.DispatcherType;
+import javax.servlet.GenericServlet;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
import javax.servlet.ServletRequestEvent;
import javax.servlet.ServletRequestListener;
+import javax.servlet.ServletRequestWrapper;
import javax.servlet.ServletResponse;
+import javax.servlet.ServletResponseWrapper;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -1741,9 +1745,9 @@ public class TestAsyncContextImpl extend
Wrapper wrapper = Tomcat.addServlet(ctx, "nonAsyncServlet",
nonAsyncServlet);
wrapper.setAsyncSupported(true);
- ctx.addServletMapping("/nonAsyncServlet", "nonAsyncServlet");
+ ctx.addServletMapping("/target", "nonAsyncServlet");
- ForbiddenDispatchingServlet forbiddenDispatchingServlet = new
ForbiddenDispatchingServlet();
+ DispatchingGenericServlet forbiddenDispatchingServlet = new
DispatchingGenericServlet();
Wrapper wrapper1 = Tomcat.addServlet(ctx,
"forbiddenDispatchingServlet", forbiddenDispatchingServlet);
wrapper1.setAsyncSupported(true);
@@ -1767,20 +1771,92 @@ public class TestAsyncContextImpl extend
assertTrue(body.toString().contains("NonAsyncServletGet"));
}
- private static class ForbiddenDispatchingServlet extends HttpServlet {
+ private static class DispatchingGenericServlet extends GenericServlet {
private static final long serialVersionUID = 1L;
+ private static final String CUSTOM_REQ_RESP = "crr";
+ private static final String EMPTY_DISPATCH = "empty";
@Override
- protected void doGet(HttpServletRequest req, HttpServletResponse resp)
+ public void service(ServletRequest req, ServletResponse resp)
throws ServletException, IOException {
- AsyncContext asyncContext = req.startAsync();
- asyncContext.dispatch("/nonAsyncServlet");
- try {
- asyncContext.dispatch("/nonExistingServlet");
- resp.getWriter().println("FAIL");
- } catch (IllegalStateException e) {
- resp.getWriter().println("OK");
+ if (DispatcherType.ASYNC != req.getDispatcherType()) {
+ AsyncContext asyncContext;
+ if ("y".equals(req.getParameter(CUSTOM_REQ_RESP))) {
+ asyncContext = req.startAsync(
+ new ServletRequestWrapper(req),
+ new ServletResponseWrapper(resp));
+ } else {
+ asyncContext = req.startAsync();
+ }
+ if ("y".equals(req.getParameter(EMPTY_DISPATCH))) {
+ asyncContext.dispatch();
+ } else {
+ asyncContext.dispatch("/target");
+ }
+ try {
+ asyncContext.dispatch("/nonExistingServlet");
+ resp.getWriter().print("FAIL");
+ } catch (IllegalStateException e) {
+ resp.getWriter().print("OK");
+ }
+ } else {
+ resp.getWriter().print("DispatchingGenericServletGet-");
+ }
+ }
+
+ }
+
+ @Test
+ public void testDispatchWithCustomRequestResponse() throws Exception {
+ // Setup Tomcat instance
+ Tomcat tomcat = getTomcatInstance();
+
+ // Must have a real docBase - just use temp
+ File docBase = new File(System.getProperty("java.io.tmpdir"));
+
+ Context ctx = tomcat.addContext("", docBase.getAbsolutePath());
+
+ DispatchingGenericServlet dispatch = new DispatchingGenericServlet();
+ Wrapper wrapper = Tomcat.addServlet(ctx, "dispatch", dispatch);
+ wrapper.setAsyncSupported(true);
+ ctx.addServletMapping("/dispatch", "dispatch");
+
+ CustomGenericServlet customGeneric = new CustomGenericServlet();
+ Wrapper wrapper2 = Tomcat.addServlet(ctx, "customGeneric",
+ customGeneric);
+ wrapper2.setAsyncSupported(true);
+ ctx.addServletMapping("/target", "customGeneric");
+
+ tomcat.start();
+
+ ByteChunk res = getUrl("http://localhost:" + getPort()
+ + "/dispatch?crr=y");
+
+ StringBuilder expected = new StringBuilder();
+ expected.append("OK");
+ expected.append("CustomGenericServletGet-");
+ assertEquals(expected.toString(), res.toString());
+
+ res = getUrl("http://localhost:" + getPort()
+ + "/dispatch?crr=y&empty=y");
+
+ expected = new StringBuilder();
+ expected.append("OK");
+ expected.append("DispatchingGenericServletGet-");
+ assertEquals(expected.toString(), res.toString());
+ }
+
+ private static class CustomGenericServlet extends GenericServlet {
+
+ private static final long serialVersionUID = 1L;
+
+ @Override
+ public void service(ServletRequest req, ServletResponse res)
+ throws ServletException, IOException {
+ if (req instanceof ServletRequestWrapper
+ && res instanceof ServletResponseWrapper) {
+ res.getWriter().print("CustomGenericServletGet-");
}
}
Modified: tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml
URL:
http://svn.apache.org/viewvc/tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml?rev=1496809&r1=1496808&r2=1496809&view=diff
==============================================================================
--- tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/tc7.0.x/trunk/webapps/docs/changelog.xml Wed Jun 26 07:48:36 2013
@@ -103,6 +103,13 @@
<code>Users:type=UserDatabase,database=UserDatabase</code> at Tomcat
shutdown. (pero)
</fix>
+ <fix>
+ Avoid <code>ClassCastException</code> when an asynchronous dispatch is
+ invoked in an asynchronous cycle which is started by a call to
+ <code>ServletRequest.startAsync(ServletRequest,ServletResponse)</code>
+ where ServletRequest/ServletResponse are custom implementations.
+ (violetagg)
+ </fix>
</changelog>
</subsection>
<subsection name="Cluster">
---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]