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.
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.
*** Bug 9754 has been marked as a duplicate of this bug. ***
*** Bug 21782 has been marked as a duplicate of this bug. ***