You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by Jan Luehe <Ja...@Sun.COM> on 2003/05/31 03:18:32 UTC

[PATCH] RequestDispatcher.forward() problem with wrapped requests

I am fixing a bug filed by Ryan Lubke (Bugtraq 4871238). I do have a fix
in place, but I would like to make sure it's appropriate.

Consider the following scenario: Servlet1 acquires a RequestDispatcher
and forwards the request to Servlet2. However, before forwarding the
request, it wraps the request inside an HttpServletRequestWrapper. The
problem is that Servlet2 never gets invoked.

If you look at ApplicationDispatcher.processRequest(), you'll see that
the target servlet (Servlet2) is invoked only if the
DISPATCHER_TYPE_ATTR attribute has been set on the request.

Since we're passing to the RequestDispatcher an instance of
HttpServletRequestWrapper, ApplicationDispatcher.wrapRequest() will
replace the original wrapped request with an instance of
ApplicationHttpRequest, which is constructed from the original wrapped
request. ApplicationDispatcher.wrapRequest() essentially does this:

  HttpServletRequest wrapped = wrapper.getRequest();
  wrapper.setRequest(new ApplicationHttpRequest(wrapped));

The problem is that the DISPATCHER_TYPE_ATTR and
DISPATCHER_REQUEST_PATH_ATTR attributes on the original wrapped
request do not get propagated onto the ApplicationHttpRequest, and
therefore, getting these attributes from the
HttpServletRequestWrapper, which simply delegates to the wrapped
ApplicationHttpRequest, returns null, causing the target servlet to
not get invoked.

My suggested fix is to consider these attributes when constructing an
ApplicationHttpRequest from an HttpServletRequest, like this (in
ApplicationHttpRequest.setRequest()):

Index: ApplicationHttpRequest.java
===================================================================
RCS file: /home/cvs/jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/core/ApplicationHttpRequest.java,v
retrieving revision 1.8
diff -u -r1.8 ApplicationHttpRequest.java
--- ApplicationHttpRequest.java 26 May 2003 12:02:31 -0000      1.8
+++ ApplicationHttpRequest.java 31 May 2003 01:05:08 -0000
@@ -524,6 +524,10 @@
         super.setRequest(request);
 
         // Initialize the attributes for this request
+        dispatcherType = request.getAttribute(Globals.DISPATCHER_TYPE_ATTR);
+        requestDispatcherPath
+           = request.getAttribute(Globals.DISPATCHER_REQUEST_PATH_ATTR);
+
         /*
         synchronized (attributes) {
             attributes.clear();

This fixes the problem. 

Please let me know if you agree, and I'll commit.

Thanks,


Jan

---------------------------------------------------------------------
To unsubscribe, e-mail: tomcat-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tomcat-dev-help@jakarta.apache.org


Re: [PATCH] RequestDispatcher.forward() problem with wrapped requests

Posted by Remy Maucherat <re...@apache.org>.
Jan Luehe wrote:
> I am fixing a bug filed by Ryan Lubke (Bugtraq 4871238). I do have a fix
> in place, but I would like to make sure it's appropriate.
> 
> Consider the following scenario: Servlet1 acquires a RequestDispatcher
> and forwards the request to Servlet2. However, before forwarding the
> request, it wraps the request inside an HttpServletRequestWrapper. The
> problem is that Servlet2 never gets invoked.
> 
> If you look at ApplicationDispatcher.processRequest(), you'll see that
> the target servlet (Servlet2) is invoked only if the
> DISPATCHER_TYPE_ATTR attribute has been set on the request.
> 
> Since we're passing to the RequestDispatcher an instance of
> HttpServletRequestWrapper, ApplicationDispatcher.wrapRequest() will
> replace the original wrapped request with an instance of
> ApplicationHttpRequest, which is constructed from the original wrapped
> request. ApplicationDispatcher.wrapRequest() essentially does this:
> 
>   HttpServletRequest wrapped = wrapper.getRequest();
>   wrapper.setRequest(new ApplicationHttpRequest(wrapped));
> 
> The problem is that the DISPATCHER_TYPE_ATTR and
> DISPATCHER_REQUEST_PATH_ATTR attributes on the original wrapped
> request do not get propagated onto the ApplicationHttpRequest, and
> therefore, getting these attributes from the
> HttpServletRequestWrapper, which simply delegates to the wrapped
> ApplicationHttpRequest, returns null, causing the target servlet to
> not get invoked.
> 
> My suggested fix is to consider these attributes when constructing an
> ApplicationHttpRequest from an HttpServletRequest, like this (in
> ApplicationHttpRequest.setRequest()):
> 
> Index: ApplicationHttpRequest.java
> ===================================================================
> RCS file: /home/cvs/jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/core/ApplicationHttpRequest.java,v
> retrieving revision 1.8
> diff -u -r1.8 ApplicationHttpRequest.java
> --- ApplicationHttpRequest.java 26 May 2003 12:02:31 -0000      1.8
> +++ ApplicationHttpRequest.java 31 May 2003 01:05:08 -0000
> @@ -524,6 +524,10 @@
>          super.setRequest(request);
>  
>          // Initialize the attributes for this request
> +        dispatcherType = request.getAttribute(Globals.DISPATCHER_TYPE_ATTR);
> +        requestDispatcherPath
> +           = request.getAttribute(Globals.DISPATCHER_REQUEST_PATH_ATTR);
> +
>          /*
>          synchronized (attributes) {
>              attributes.clear();
> 
> This fixes the problem. 
> 
> Please let me know if you agree, and I'll commit.

Seems ok to me :)

Remy


---------------------------------------------------------------------
To unsubscribe, e-mail: tomcat-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tomcat-dev-help@jakarta.apache.org