Bug 8566 - Filter using ServletRequestWrapper breaks RequestDispatcher.forward
Summary: Filter using ServletRequestWrapper breaks RequestDispatcher.forward
Status: RESOLVED INVALID
Alias: None
Product: Tomcat 4
Classification: Unclassified
Component: Catalina (show other bugs)
Version: 4.0.3 Final
Hardware: PC All
: P3 major (vote)
Target Milestone: ---
Assignee: Tomcat Developers Mailing List
URL: http://qlink.queensu.ca/~9cw4/loop-bu...
Keywords:
: 9754 21782 (view as bug list)
Depends on:
Blocks:
 
Reported: 2002-04-26 19:16 UTC by Chris Wolfe
Modified: 2005-03-20 17:06 UTC (History)
2 users (show)



Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Chris Wolfe 2002-04-26 19:16:26 UTC
http://qlink.queensu.ca/~9cw4/loop-bug.zip contains a simple web-app that
produces the bug and implements a simple workaround.

* Problem:

When a filter uses a ServletRequestWrapper to modify the request in doFilter,
any changes made by ApplicationDispatcher will be completely ignored.

* Workaround:

When getRequest is called on the wrapper, its getServletPath reverts to calling
super.getServletPath(). This works correctly in 4.0.3, but could be broken
easily in future versions.

* Context:

In org.apache.catalina.core.ApplicationDispatcher:

doForward(request, response) calls wrapRequest for HTTP path-based forwards.

wrapRequest walks up the request chain past any ServletRequestWrappers and
inserts a new ApplicationHttpRequest before the first wrapper, this new request
is returned.

doForward modifies the returned request to match the target of the forward.

* Discussion:

Why does the insertion need to take place before the first ServletRequestWrapper? 

Considering the JSP spec specifically talks about using ServletRequestWrapper in
a Filter to redirect requests, it breaking forward is a serious problem.
Removing the chain walking code would seem to be the obvious fix, but I am
worried about breaking includes or other behavior.
Comment 1 Craig McClanahan 2002-04-26 20:57:59 UTC
When processing a RequestDispatcher.forward() or RequestDispatcher.include()
call, the container is required to ensure that any wrapped request (or response)
provided by the calling servlet is the very same instance that is handed to the
calling servlet (Servlet 2.3 Spec, Section 6.2.2, last paragraph).  Therefore,
it is not legal to implement request dispatcher processing by wrapping the
request provided by the calling servlet.

A consequence of this is that your wrapper class *must* delegate calls like
getServletPath() to its superclass in order to see the modified values set by
the container -- which are conceptually performed on the underlying "real"
request object itself.  If your application fails to do this, then it is the
application's problem that the "wrong" answer is returned -- just as it would be
if you overrode getServletPath() and always returned a null value, or some
constant String.
Comment 2 Tim Funk 2003-05-30 12:07:40 UTC
*** Bug 9754 has been marked as a duplicate of this bug. ***
Comment 3 Tim Funk 2003-07-21 22:35:20 UTC
*** Bug 21782 has been marked as a duplicate of this bug. ***