Bug 35270 - RequestDispatcher forward not handling a ServletRequestWrapper correctly when updating forward request params
Summary: RequestDispatcher forward not handling a ServletRequestWrapper correctly when...
Status: RESOLVED FIXED
Alias: None
Product: Tomcat 5
Classification: Unclassified
Component: Servlet & JSP API (show other bugs)
Version: 5.0.28
Hardware: PC Windows XP
: P2 normal with 2 votes (vote)
Target Milestone: ---
Assignee: Tomcat Developers Mailing List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2005-06-08 17:34 UTC by Carlin Rogers
Modified: 2005-07-31 14:40 UTC (History)
0 users



Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Carlin Rogers 2005-06-08 17:34:20 UTC
Tomcats implementation of RequestDispatcher forward not handling a 
ServletRequestWrapper correctly when updating forward request params.
Seems to modify the value of the javax.servlet.forward.request_uri
request attribute incorrectly, according to servlet spec SRV.8.4.2.

Here are some specifics, at least with version 5.0.28.

Stepping through the Tomcat source in the debugger, it
appears that the request's requestURI field gets stomped
on in the forward method of the RequestDispatcher
(ApplicationDispatcher.doForward()). I'm not sure Tomcat 
is handling a ServletRequestWrapper correctly.

I gather the servlet spec says that users may wrap the
request/response objects with their own implementation.

Tomcat's ApplicationDispatcher gets the request from
the outer request (the ServletRequestWrapper), trying to
keep track of the previous wrapper and current wrapper
(or request) as it loops through to get the real request.
With a single wrapper, the value of "previous" is the
same as the original outer request. Then Tomcat calls...

((ServletRequestWrapper) previous).setRequest(wrapper);

which is the same as calling setRequest(wrapper) on the
incoming request. Tomcat does not get and save the value
of the original request URI. It calls setRequestURI(path)
on the wrapper, effectively changing the request URI of the
original incoming request to the path of the forward.

Then Tomcat sets the javax.servlet.forward.request_uri
attribute by calling getRequestURI() from the original
request... but that just got modified. Implying the
javax.servlet.forward.request_uri attribute is going to
get the value of the path for the forward.

You can test this on Tomcat by using a couple JSP to. Use
a HttpServletRequestWrapper in one JSP for the forward.

First create "result.jsp" to display the desired request attribute...

<%@ page language="java" contentType="text/html;charset=UTF-8"%>
<html>
    <head>
        <title>RequestDispatcher Test</title>
    </head>
    <body>
        <h1>Forward Request URI</h1>
        javax.servlet.forward.request_uri =
        <%= request.getAttribute("javax.servlet.forward.request_uri") %>
    </body>
</html>

Create a JSP to forward without using a wrapper, "forward.jsp"...

<%
    javax.servlet.RequestDispatcher rd =
        request.getRequestDispatcher("result.jsp");
    rd.forward(request, response);
%>

and a second forward using HttpServletRequestWrapper, "wrapperforward.jsp"...

<%
    HttpServletRequestWrapper wrapper = new HttpServletRequestWrapper(request);
    javax.servlet.RequestDispatcher rd =
        wrapper.getRequestDispatcher("result.jsp");
    rd.forward(wrapper, response);
%>

When you hit forward.jsp, the result page displays "/some-context/forward.jsp"
for the javax.servlet.forward.request_uri request attribute.
However, hit wrapperforward.jsp and the result page displays
"/some-context/result.jsp". From looking at the spec, I'd expect this 
should be "/some-context/wrapperforward.jsp".
Comment 1 Brian DeHamer 2005-06-08 17:44:07 UTC
I was able to reproduce this same bug on Tomcat 5.5.9 as well.  The 
javax.servlet.forward.request_uri attribute is definitely NOT being 
set correctly when forwarding with a wrapped request
Comment 2 Brian DeHamer 2005-06-08 17:54:42 UTC
I'm guessing that the root cause is the same, but it should also be noted that 
the javax.servlet.forward.servlet_path attribute is not being set correctly 
under these conditions either.
Comment 3 william.barker 2005-06-09 07:54:23 UTC
This is now fixed in the CVS head, and will appear in 5.5.10.

It currently seems unlikely that there will be another release on the 5.0.x 
line, so the 5.5.x line is all that there is.
Comment 4 Brian DeHamer 2005-07-06 00:36:01 UTC
It looks like there is a 5.0.30 Tomcat version in the works, will this fix be 
included in that version as well?
Comment 5 Topper Lu 2005-07-31 20:22:40 UTC
Forgive my poor English, it is not my native language.
I found following bugs since 5.5.x, may be early.
5.5.9, 5.5.10 have same bugs, too.

org.apache.catalina.core.ApplicationDispatcher.doInclude
  //HTTP named dispatcher include
  //HTTP path based include
  invoke(outerRequest, outerResponse); // bug here
  --> invoke(wrequest, wresponse); // crect one

org.apache.catalina.core.ApplicationDispatcher.processRequest
  //HTTP named dispatcher forward
  //HTTP path based forward
  invoke(outerRequest, response); // bug here
  --> invoke(wrequest, response); // crect


1) If you have n HttpServletRequestWrapper, then
Original HttpServletRequest
Dispatcher's HttpServletRequestWrapper <-- wrequest <-- suppose to invoke this one
Your HttpServletRequestWrapper #1
Your HttpServletRequestWrapper #2
...
Your HttpServletRequestWrapper #n <-- outerRequest

2) If no HttpServletRequestWrapper, then
Original HttpServletRequest
Dispatcher's HttpServletRequestWrapper <-- wrequest==outerRequest <-- it works



Topper Lu
email: topper@tlk.com.tw
Comment 6 Remy Maucherat 2005-07-31 22:40:24 UTC
Ehhh, ok, I see the light now ;)

Forgive me for not being friendly, it is not my native behavior.
Please do not reopen the report.