问题
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.
回答1:
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.
回答2:
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;
}
来源:https://stackoverflow.com/questions/2815986/where-does-tomcat-append-to-directory-paths