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)
+