Mantis - Resin
Viewing Issue Advanced Details
875 minor always 01-18-06 14:38 02-01-06 16:39
koreth  
ferg  
normal  
closed 3.0.17  
fixed  
none    
none 3.0.18  
0000875: Nested servlet forwarding goes to the wrong destination when using HttpServletRequestWrapper
Suppose I have a servlet (call it /s1) that allocates an HttpRequestWrapper subclass. Then it does

    request.getRequestDispatcher("/s2").forward(myWrappedRequest, response);

Now servlet 2 does the same thing:

    request.getRequestDispatcher("/s3").forward(anotherWrappedRequest, response);

The second forward goes to /s2 again, rather than to /s3. /s2 tries to forward to /s3 again, and you quickly get a "too many servlet includes" error.

The problem appears to be in RequestDispatcherImpl.java, which walks up the chain of HttpServletRequestWrapper objects to find the topmost ("real") request. It then calls invocation.service(topRequest, res) -- which services the innermost HttpServletRequestWrapper, not the newly constructed request wrapper that it has just pieced together.

Changing line 268 of RequestDispatcherImpl.java from

   invocation.service(topRequest, res);

to

   invocation.service(subRequest, res);

appears to fix the problem, and I haven't noticed any bad side effects. But my knowledge of Resin's request handling internals is next to nonexistent so that may not be the right fix.

Notes
(0000735)
koreth   
01-18-06 15:12   
I spoke too soon -- the proposed fix does appear to have some side effects (e.g. the parent request's parameters are visible in the child). I've now changed it to

   invocation.service(req, res);

and *that* appears to be working.
(0000826)
koreth   
01-30-06 17:58   
That hack doesn't work 100% either; <jsp:forward> is broken. Here's another, probably just as fragile, hack; with it in place the "goes to the wrong place" problem doesn't happen and <jsp:forward> works.

--- modules/resin/src/com/caucho/server/webapp/RequestDispatcherImpl.java- 2006-01-18 14:20:18.052573160 -0800
+++ modules/resin/src/com/caucho/server/webapp/RequestDispatcherImpl.java 2006-01-30 17:52:05.671355017 -0800
@@ -265,7 +265,10 @@
       res.resetBuffer();
       res.setContentLength(-1);

- invocation.service(topRequest, res);
+ if (topRequest == subRequest)
+ invocation.service(topRequest, res);
+ else
+ invocation.service(req, res);

       if (cauchoRes != null)
         cauchoRes.close();
(0000840)
ferg   
02-01-06 16:39   
server/10y4

The issue, by the way, is actually pretty complex. This part of the servlet specification is not particularly sane.