Bug 45441 - Matching of relevant servlet filters fails when request is forwarded...
Summary: Matching of relevant servlet filters fails when request is forwarded...
Status: RESOLVED FIXED
Alias: None
Product: Tomcat 6
Classification: Unclassified
Component: Catalina (show other bugs)
Version: 6.0.18
Hardware: All All
: P2 normal (vote)
Target Milestone: default
Assignee: Tomcat Developers Mailing List
URL:
Keywords:
Depends on:
Blocks:
 
Reported: 2008-07-20 10:54 UTC by Andrzej Taramina
Modified: 2014-02-17 13:53 UTC (History)
0 users



Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Andrzej Taramina 2008-07-20 10:54:40 UTC
I ran into a situation where Tomcat will not execute appropriate filters on a request that has been forwarded.

I'm using the handy URLRewriteFilter implementation (from tuckey.org).  When I forwarded a request internally, filters that had a matching url-pattern (in the web.xml file) and with a dispatcher setting of both REQUEST and FORWARD were not invoked.

On tracing the code (hours later), I found that the problem lies inside the ApplicationDispatcher code.  It set the DISPATCHER_REQUEST_PATH_ATTR state attribue to be the servletPath.  That meant that only matches using the servlet path would match, but longer (more exact) urls would fail to match.

For example, using the following filter mapping:

<filter-mapping>
   <filter-name>my-filter</filter-name>		   
   <url-pattern>/app/level/mycode.do</url-pattern>
   <dispatcher>REQUEST</dispatcher> 
   <dispatcher>FORWARD</dispatcher>
</filter-mapping>

would not match a request that was forwarded to /app/level/mycode.do, which it should! 

Changing the url pattern to be "/app/*" would match, but "/app/level/*" would not, since the servletPath was /app in this example.

The fix for this is quite simple.  In the ApplicationDispatcher.java code, in the method processRequest() (which is only called for forwards), change the following statement:

state.outerRequest.setAttribute
   (ApplicationFilterFactory.DISPATCHER_REQUEST_PATH_ATTR,
   servletPath);

to use requestURI instead as follows:

state.outerRequest.setAttribute
   (ApplicationFilterFactory.DISPATCHER_REQUEST_PATH_ATTR,
   requestURI );

This resolves the problem and let all the examples above correctly match and run the filter on a forward.

I believe includes will also be broken in the same manner. Similar changes to the doInclude() method in ApplicationDispatcher.java will likely resolve that issue as well, though I have not tested this personally.

Be nice to see this resolved in 6.0.17+.

Thanks!

....Andrzej
Comment 1 Andrzej Taramina 2008-08-23 13:46:04 UTC
This is still a bug in .0.1.  Same fix/patch as before.

Sure would be nice if someone implemented this in the trunk code base.
Comment 2 Andrzej Taramina 2008-08-23 13:47:17 UTC
Ooops.  That should have said 6.0.18...
Comment 3 Mark Thomas 2008-09-17 04:15:35 UTC
Note that the proposed patch will not work for contexts other than the ROOT context since, as per SRV.3.4:
requestURI = contextPath + servletPath + pathInfo

The correct fix is to append pathInfo to servletPath.

This has been fixed in trunk and proposed for 6.0.x.
Comment 4 Mark Thomas 2008-10-27 06:30:01 UTC
This has been applied to 6.0.x and will be in 6.0.19 onwards.