Where does Tomcat append / to directory paths?
Asked Answered
R

2

6

Suppose my Tomcat webapps directory looks like this:

webapps/
webapps/fooapp/
webapps/fooapp/WEB-INF/
webapps/fooapp/WEB-INF/web.xml
webapps/fooapp/bardir/

When I make a GET request for /fooapp/bardir, Tomcat sees that webapps/fooapp/bardir is a directory and sends back a 302 to /fooapp/bardir/ (with a slash at the end).

Here is my question: Where in the Tomcat source code does this take place? (I'm looking at 6.0.x but a correct answer for any version would be a great starting point.)

The only reference material I can find on this subject is in the Catalina Functional Specifications which states, regarding the Default Servlet:

On each HTTP GET request processed by this servlet, the following processing shall be performed:

[...]

  • If the requested resource is a directory:
    • If the request path does not end with "/", redirect to a corresponding path with "/" appended so that relative references in welcome files are resolved correctly.

However, this functionality does not appear to be in org.apache.catalina.servlets.DefaultServlet; or at least, it's not there exclusively: if I replace the default servlet in web.xml with a servlet whose servlet-class does not exist, directory paths still come back 302 to add the slash, while every other request comes back with an error as expected.

Rosenberg answered 12/5, 2010 at 3:40 Comment(0)
H
3

I think it happens in org.apache.tomcat.util.http.mapper.Mapper, namely in the internalMapWrapper (Context, CharChunk, MappingData) method.

But unfortunately I'm not really sure -- maybe this really is a question better suited for the tomcat-users mailing list. Sorry for not having a better answer.

Hafnium answered 12/5, 2010 at 21:38 Comment(3)
I think you found it! And the 'default servlet' comment seems to show that someone was a bit confused on when servlet mapping ought to happen, exactly as I suspected. Thanks for your help.Rosenberg
+1 I asked the same question differently here: #5579048 thanks!Barnacle
PS Jeppe from the Lift group posted this related bug (as yet unfixed): issues.apache.org/bugzilla/show_bug.cgi?id=32424Barnacle
D
0

The Eclipse debugger learnt me that the redirect happens in line 504 of CoyoteAdapter class, almost in the end of the postParseRequest() method.

    // Possible redirect
    MessageBytes redirectPathMB = request.getMappingData().redirectPath;
    if (!redirectPathMB.isNull()) {
        // ...
        response.sendRedirect(redirectPath); // <--- Here.
        return false;
    }

Tomcat 6.0.20 btw.

Update: actually, the redirectPath is indeed filled by the Mapper as mentioned in @Henning's answer, indeed in the internalMapWrapper() method. Checkout the source code here.

    if(mappingData.wrapper == null && noServletPath) {
        // The path is empty, redirect to "/"
        mappingData.redirectPath.setChars
            (path.getBuffer(), pathOffset, pathEnd);
        path.setEnd(pathEnd - 1);
        return;
    }
Distinctive answered 13/5, 2010 at 1:55 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.