Mantis - Resin
Viewing Issue Advanced Details
875 minor always 01-18-06 14:38 02-01-06 16:39
closed 3.0.17  
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, 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 from

   invocation.service(topRequest, res);


   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.

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.
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/ 2006-01-18 14:20:18.052573160 -0800
+++ modules/resin/src/com/caucho/server/webapp/ 2006-01-30 17:52:05.671355017 -0800
@@ -265,7 +265,10 @@

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

       if (cauchoRes != null)
02-01-06 16:39   

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