Bug 56430

Summary: Extension mapping that includes a dot in the extension does not work
Product: Tomcat 7 Reporter: Benjamin Plocek <smail>
Component: Servlet & JSP APIAssignee: Tomcat Developers Mailing List <dev>
Status: RESOLVED FIXED    
Severity: enhancement    
Priority: P2    
Version: 7.0.53   
Target Milestone: ---   
Hardware: PC   
OS: Linux   

Description Benjamin Plocek 2014-04-18 15:32:35 UTC
Chapter SRV.11.2 of the servlet specification defines...

    A string beginning with a '*.' prefix is used as an extension mapping.

http://download.oracle.com/otndocs/jcp/servlet-2.5-mrel2-eval-oth-JSpec/

So, this tells us, the url-pattern '*.jsp' forwards all requests ending with '.jsp' to the mapped servlet or filtes. With this, one might also assume that the url-pattern '*.my.txt' forwards all requests ending with 'my.txt' to the configured servlet or filters. But the latter does not work with Tomcat.

I set up a tiny maven project, for illustrating the problem: https://bitbucket.org/benplocek/servlet-extension-mapping-test

This project contains a Servlet and a Filter, both mapped to '.my.html':

  <servlet-mapping>
    <servlet-name>MyServlet</servlet-name>
    <url-pattern>*.my.html</url-pattern>
  </servlet-mapping>

When sending a request to /test.my.html Tomcat responds with a 404.

I also deployed this app to Jetty 9.1.4 which behaves as expected: /test.my.html invokes the filter and also serves the servlet. Because of this I assume this is a bug in Tomcat.

Note: Also applies to Tomcat 8.0.5.
Comment 1 Christopher Schultz 2014-04-18 19:41:14 UTC
This is probably a spec-clarification question, really: does * match a dot? Is it greedy-matching? If it behaves like a Perl-compatible RE ".*" (or really any RE ".*"), then what you'll match is ".txt" and not ".my.txt".

I agree with you that Tomcat's behavior is "surprising", at least in this case.
Comment 2 Konstantin Kolinko 2014-04-18 21:03:21 UTC
From Servlet 3.1-final.pdf
Ch. 12.1 Use of URL Paths (page #12-121 ("141 of 240"))

[quote]
3. If the last segment in the URL path contains an extension (e.g. .jsp), the servlet
container will try to match a servlet that handles requests for the extension. An
extension is defined as the part of the last segment after the last ’.’ character.
[/quote]

In Servlet 2.5 spec that is chapter SRV.11.1
Comment 3 Benjamin Plocek 2014-04-18 21:10:58 UTC
Ok, but then it would be great, to get any kind of a feedback when deploying the application. When I use an invalid pattern like '/*.jsp' the server also complains. But when I use '*.my.txt' I get no hint that something is wrong.

So I end up with a servlet-/filter-mapping that does not have any effect.
Comment 4 Remy Maucherat 2014-04-20 10:14:42 UTC
Since this is at best an enhancement, it can be considered fixed in Tomcat 8 which includes a rewrite valve that can easily do this sort of matching.

Documentation available here: http://tomcat.apache.org/tomcat-8.0-doc/rewrite.html
Comment 5 Karl Peterbauer 2014-04-22 19:30:57 UTC
I think both the Servlet spec and Tomcat's implementation are quite unfortunate. Patterns like '*.jsp' or '*.my.txt' closely resemble the venerable UNIX glob style pattern matching, and consequenty they should behave accordingly. For example, the UNIX command "ls *.my.txt" does match a file named "test.my.txt".
Comment 6 Christopher Schultz 2014-04-22 19:40:47 UTC
Thanks for the further clarification, Konstantin. I stopped reading too soon. I see Tomcat as implementing the spec faithfully, here, so there is no bug. Marking INVALID.

If you'd like to request an enhancement, please REOPEN this bug and state your request.
Comment 7 Remy Maucherat 2014-04-22 20:49:31 UTC
As an enhancement, it should be fine to say the rewrite valve should be used. It is a generic solution that can take care of any matching scenario, but it would be bad to add tiny proprietary extensions however.
Comment 8 Benjamin Plocek 2014-04-22 23:03:35 UTC
Using the rewrite valve is not an enhancement. It's a workaround that doesn't work with Tomcat 7.

Please, read my comment #3. I now see why Tomcat doesn't support extension mappings including multiple dots. But hey, then please fix your code so that it is consistent.

In StandardContext.java you have a method validateURLPattern which is used at startup. For this method the String '*.my.txt' _is valid_, but when it comes to using this pattern, it does not have an effect, because the rest of the code seems to agree with your explanation and takes this pattern as invalid.

So, again, I REOPEN this issue and request this enhancement: Fix the check at startup, so that it is clear why the given filter mapping with multiple dots does not work. It's a pain, when you have to find out why your filter does not work and you don't even get a warning in your logs.
Comment 9 Mark Thomas 2014-04-24 08:32:43 UTC
I've extended the check for suspicious URL patterns to include *.a.b style patterns. The fix has been applied to 8.0.x for 8.0.6 onwards and to 7.0.x for 7.0.54 onwards.

While we can't realistically detect every possible error that a user might make when specifying a pattern this is looks like it could be a common error and the test was simple to add.