diff --git a/java/org/apache/catalina/authenticator/FormAuthenticator.java b/java/org/apache/catalina/authenticator/FormAuthenticator.java index ebf48648c..5f5c1804e 100644 --- a/java/org/apache/catalina/authenticator/FormAuthenticator.java +++ b/java/org/apache/catalina/authenticator/FormAuthenticator.java @@ -214,6 +214,20 @@ public boolean authenticate(Request request, HttpServletResponse response) // No -- Save this request and redirect to the form login page if (!loginAction) { + // If this request was to the root of the context without a trailing + // '/', need to redirect to add it else the submit of the login form + // may not go to the correct web application + if (request.getServletPath().length() == 0 && request.getPathInfo() == null) { + StringBuilder location = new StringBuilder(requestURI); + location.append('/'); + if (request.getQueryString() != null) { + location.append('?'); + location.append(request.getQueryString()); + } + response.sendRedirect(response.encodeRedirectURL(location.toString())); + return false; + } + session = request.getSessionInternal(true); if (log.isDebugEnabled()) { log.debug("Save request in session '" + session.getIdInternal() + "'"); diff --git a/java/org/apache/catalina/mapper/Mapper.java b/java/org/apache/catalina/mapper/Mapper.java index 318031c5f..76bc8f3c0 100644 --- a/java/org/apache/catalina/mapper/Mapper.java +++ b/java/org/apache/catalina/mapper/Mapper.java @@ -836,20 +836,13 @@ private final void internalMapWrapper(ContextVersion contextVersion, int pathOffset = path.getOffset(); int pathEnd = path.getEnd(); - int servletPath = pathOffset; boolean noServletPath = false; int length = contextVersion.path.length(); - if (length != (pathEnd - pathOffset)) { - servletPath = pathOffset + length; - } else { + if (length == (pathEnd - pathOffset)) { noServletPath = true; - path.append('/'); - pathOffset = path.getOffset(); - pathEnd = path.getEnd(); - servletPath = pathOffset+length; } - + int servletPath = pathOffset + length; path.setOffset(servletPath); // Rule 1 -- Exact Match @@ -887,8 +880,10 @@ private final void internalMapWrapper(ContextVersion contextVersion, if(mappingData.wrapper == null && noServletPath && mappingData.context.getMapperContextRootRedirectEnabled()) { // The path is empty, redirect to "/" + path.append('/'); + pathEnd = path.getEnd(); mappingData.redirectPath.setChars - (path.getBuffer(), pathOffset, pathEnd-pathOffset); + (path.getBuffer(), pathOffset, pathEnd - pathOffset); path.setEnd(pathEnd - 1); return; } @@ -1003,7 +998,13 @@ private final void internalMapWrapper(ContextVersion contextVersion, char[] buf = path.getBuffer(); if (contextVersion.resources != null && buf[pathEnd -1 ] != '/') { String pathStr = path.toString(); - WebResource file = contextVersion.resources.getResource(pathStr); + WebResource file; + // Handle context root + if (pathStr.length() == 0) { + file = contextVersion.resources.getResource("/"); + } else { + file = contextVersion.resources.getResource(pathStr); + } if (file != null && file.isDirectory() && mappingData.context.getMapperDirectoryRedirectEnabled()) { // Note: this mutates the path: do not do any processing diff --git a/java/org/apache/catalina/servlets/DefaultServlet.java b/java/org/apache/catalina/servlets/DefaultServlet.java index 2405d4bb9..b33caa4a7 100644 --- a/java/org/apache/catalina/servlets/DefaultServlet.java +++ b/java/org/apache/catalina/servlets/DefaultServlet.java @@ -331,6 +331,10 @@ public void init() throws ServletException { * @param request The servlet request we are processing */ protected String getRelativePath(HttpServletRequest request) { + return getRelativePath(request, false); + } + + protected String getRelativePath(HttpServletRequest request, boolean allowEmptyPath) { // IMPORTANT: DefaultServlet can be mapped to '/' or '/path/*' but always // serves resources from the web app root with context rooted paths. // i.e. it can not be used to mount the web app root under a sub-path @@ -356,7 +360,7 @@ protected String getRelativePath(HttpServletRequest request) { if (pathInfo != null) { result.append(pathInfo); } - if (result.length() == 0) { + if (result.length() == 0 && !allowEmptyPath) { result.append('/'); } @@ -686,7 +690,8 @@ protected void serveResource(HttpServletRequest request, boolean serveContent = content; // Identify the requested resource path - String path = getRelativePath(request); + String path = getRelativePath(request, true); + if (debug > 0) { if (serveContent) log("DefaultServlet.serveResource: Serving resource '" + @@ -696,6 +701,12 @@ protected void serveResource(HttpServletRequest request, path + "' headers only"); } + if (path.length() == 0) { + // Context root redirect + doDirectoryRedirect(request, response); + return; + } + WebResource resource = resources.getResource(path); if (!resource.exists()) { @@ -811,13 +822,7 @@ protected void serveResource(HttpServletRequest request, if (resource.isDirectory()) { if (!path.endsWith("/")) { - StringBuilder location = new StringBuilder(request.getRequestURI()); - location.append('/'); - if (request.getQueryString() != null) { - location.append('?'); - location.append(request.getQueryString()); - } - response.sendRedirect(response.encodeRedirectURL(location.toString())); + doDirectoryRedirect(request, response); return; } @@ -1026,6 +1031,16 @@ protected void serveResource(HttpServletRequest request, } } + private void doDirectoryRedirect(HttpServletRequest request, HttpServletResponse response) + throws IOException { + StringBuilder location = new StringBuilder(request.getRequestURI()); + location.append('/'); + if (request.getQueryString() != null) { + location.append('?'); + location.append(request.getQueryString()); + } + response.sendRedirect(response.encodeRedirectURL(location.toString())); + } /** * Parse the content-range header. diff --git a/java/org/apache/catalina/servlets/WebdavServlet.java b/java/org/apache/catalina/servlets/WebdavServlet.java index 9a1c6f8de..926945fb9 100644 --- a/java/org/apache/catalina/servlets/WebdavServlet.java +++ b/java/org/apache/catalina/servlets/WebdavServlet.java @@ -375,6 +375,11 @@ protected boolean checkIfHeaders(HttpServletRequest request, */ @Override protected String getRelativePath(HttpServletRequest request) { + return getRelativePath(request, false); + } + + @Override + protected String getRelativePath(HttpServletRequest request, boolean allowEmptyPath) { String pathInfo; if (request.getAttribute(RequestDispatcher.INCLUDE_REQUEST_URI) != null) { diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml index fbc11d4c4..3c2dc8b2a 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -61,6 +61,11 @@ running Tomcat with a Java agent. Based on a patch by Huxing Zhang. (markt) + + 58660: Correct a regression in 8.0.29 caused by the change + that moved the redirection for context roots from the Mapper to the + Default Servlet. (markt) +