diff --git a/java/org/apache/catalina/servlets/DefaultServlet.java b/java/org/apache/catalina/servlets/DefaultServlet.java index 1bf261dff2a..465627e7a05 100644 --- a/java/org/apache/catalina/servlets/DefaultServlet.java +++ b/java/org/apache/catalina/servlets/DefaultServlet.java @@ -860,23 +860,6 @@ protected void serveResource(HttpServletRequest request, return; } - // If the resource is not a collection, and the resource path - // ends with "/" or "\", return NOT FOUND - if (cacheEntry.context == null) { - if (path.endsWith("/") || (path.endsWith("\\"))) { - // Check if we're included so we can return the appropriate - // missing resource name in the error - String requestUri = (String) request.getAttribute( - RequestDispatcher.INCLUDE_REQUEST_URI); - if (requestUri == null) { - requestUri = request.getRequestURI(); - } - response.sendError(HttpServletResponse.SC_NOT_FOUND, - requestUri); - return; - } - } - // Check if the conditions specified in the optional If headers are // satisfied. if (cacheEntry.context == null) { diff --git a/java/org/apache/naming/resources/FileDirContext.java b/java/org/apache/naming/resources/FileDirContext.java index 3edb303512d..2c94a80bd4e 100644 --- a/java/org/apache/naming/resources/FileDirContext.java +++ b/java/org/apache/naming/resources/FileDirContext.java @@ -801,11 +801,18 @@ protected File file(String name) { */ protected File file(String name, boolean mustExist) { File file = new File(base, name); - return validate(file, mustExist, absoluteBase); + return validate(file, name, mustExist, absoluteBase); } - protected File validate(File file, boolean mustExist, String absoluteBase) { + protected File validate(File file, String name, boolean mustExist, String absoluteBase) { + + // If the requested names ends in '/', the Java File API will return a + // matching file if one exists. This isn't what we want as it is not + // consistent with the Servlet spec rules for request mapping. + if (file.isFile() && name.endsWith("/")) { + return null; + } if (!mustExist || file.exists() && file.canRead()) { diff --git a/java/org/apache/naming/resources/VirtualDirContext.java b/java/org/apache/naming/resources/VirtualDirContext.java index ce19ed65a45..c04cc5b42e6 100644 --- a/java/org/apache/naming/resources/VirtualDirContext.java +++ b/java/org/apache/naming/resources/VirtualDirContext.java @@ -163,7 +163,7 @@ public Attributes getAttributes(String name) throws NamingException { String resourcesDir = dirList.get(0); if (name.equals(path)) { File f = new File(resourcesDir); - f = validate(f, true, resourcesDir); + f = validate(f, name, true, resourcesDir); if (f != null) { return new FileResourceAttributes(f); } @@ -171,8 +171,8 @@ public Attributes getAttributes(String name) throws NamingException { path += "/"; if (name.startsWith(path)) { String res = name.substring(path.length()); - File f = new File(resourcesDir + "/" + res); - f = validate(f, true, resourcesDir); + File f = new File(resourcesDir, res); + f = validate(f, res, true, resourcesDir); if (f != null) { return new FileResourceAttributes(f); } @@ -206,7 +206,7 @@ protected File file(String name, boolean mustExist) { if (name.equals(path)) { for (String resourcesDir : dirList) { file = new File(resourcesDir); - file = validate(file, true, resourcesDir); + file = validate(file, name, true, resourcesDir); if (file != null) { return file; } @@ -216,7 +216,7 @@ protected File file(String name, boolean mustExist) { String res = name.substring(path.length()); for (String resourcesDir : dirList) { file = new File(resourcesDir, res); - file = validate(file, true, resourcesDir); + file = validate(file, res, true, resourcesDir); if (file != null) { return file; } @@ -252,7 +252,7 @@ protected List list(File file) { if (res != null) { for (String resourcesDir : dirList) { File f = new File(resourcesDir, res); - f = validate(f, true, resourcesDir); + f = validate(f, res, true, resourcesDir); if (f != null && f.isDirectory()) { List virtEntries = super.list(f); for (NamingEntry entry : virtEntries) { @@ -288,7 +288,7 @@ protected Object doLookup(String name) { if (name.equals(path)) { for (String resourcesDir : dirList) { File f = new File(resourcesDir); - f = validate(f, true, resourcesDir); + f = validate(f, name, true, resourcesDir); if (f != null) { if (f.isFile()) { return new FileResource(f); @@ -304,8 +304,8 @@ protected Object doLookup(String name) { if (name.startsWith(path)) { String res = name.substring(path.length()); for (String resourcesDir : dirList) { - File f = new File(resourcesDir + "/" + res); - f = validate(f, true, resourcesDir); + File f = new File(resourcesDir, res); + f = validate(f, res, true, resourcesDir); if (f != null) { if (f.isFile()) { return new FileResource(f); diff --git a/test/org/apache/naming/resources/TestFileDirContext.java b/test/org/apache/naming/resources/TestFileDirContext.java new file mode 100644 index 00000000000..76e0a040b17 --- /dev/null +++ b/test/org/apache/naming/resources/TestFileDirContext.java @@ -0,0 +1,46 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.naming.resources; + +import java.io.File; + +import javax.servlet.http.HttpServletResponse; + +import org.junit.Assert; +import org.junit.Test; + +import org.apache.catalina.startup.Tomcat; +import org.apache.catalina.startup.TomcatBaseTest; +import org.apache.tomcat.util.buf.ByteChunk; + +public class TestFileDirContext extends TomcatBaseTest { + + @Test + public void testLookupResourceWithTrailingSlash() throws Exception { + Tomcat tomcat = getTomcatInstance(); + + File appDir = new File("test/webapp-3.0"); + // app dir is relative to server home + tomcat.addWebapp(null, "/test", appDir.getAbsolutePath()); + + tomcat.start(); + + int sc = getUrl("http://localhost:" + getPort() + + "/test/index.html/", new ByteChunk(), null); + Assert.assertEquals(HttpServletResponse.SC_NOT_FOUND, sc); + } +}