From 7288bc70a14edcfeff0a96e333a858be374cfc64 Mon Sep 17 00:00:00 2001 From: Mark Thomas Date: Mon, 30 Nov 2015 09:27:41 +0000 Subject: [PATCH] Fix https://bz.apache.org/bugzilla/show_bug.cgi?id=58660 With mapperContextRootRedirectEnabled ste to false, the redirect needs to be handled elsewhere. - Ensure the Mapper does not add the '/' handling the redirect - Handle the redirect in the DefaultServlet - Add a redirect to FORM auth if auth is occurring at the context root else the login page could be submitted to the wrong web application git-svn-id: https://svn.apache.org/repos/asf/tomcat/tc7.0.x/trunk@1717212 13f79535-47bb-0310-9956-ffa450edef68 --- .../authenticator/FormAuthenticator.java | 14 ++++++++ .../catalina/servlets/DefaultServlet.java | 33 ++++++++++++++----- .../catalina/servlets/WebdavServlet.java | 5 +++ .../tomcat/util/http/mapper/Mapper.java | 21 ++++++------ webapps/docs/changelog.xml | 9 +++++ 5 files changed, 62 insertions(+), 20 deletions(-) diff --git a/java/org/apache/catalina/authenticator/FormAuthenticator.java b/java/org/apache/catalina/authenticator/FormAuthenticator.java index 6d8f40c3e100..6c535749de9b 100644 --- a/java/org/apache/catalina/authenticator/FormAuthenticator.java +++ b/java/org/apache/catalina/authenticator/FormAuthenticator.java @@ -236,6 +236,20 @@ public boolean authenticate(Request request, // 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/servlets/DefaultServlet.java b/java/org/apache/catalina/servlets/DefaultServlet.java index a6e5a85216de..3613ae364ca8 100644 --- a/java/org/apache/catalina/servlets/DefaultServlet.java +++ b/java/org/apache/catalina/servlets/DefaultServlet.java @@ -375,6 +375,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 @@ -400,7 +404,7 @@ protected String getRelativePath(HttpServletRequest request) { if (pathInfo != null) { result.append(pathInfo); } - if (result.length() == 0) { + if (result.length() == 0 && !allowEmptyPath) { result.append('/'); } @@ -778,7 +782,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 '" + @@ -788,6 +793,12 @@ protected void serveResource(HttpServletRequest request, path + "' headers only"); } + if (path.length() == 0) { + // Context root redirect + doDirectoryRedirect(request, response); + return; + } + CacheEntry cacheEntry = resources.lookupCache(path); if (!cacheEntry.exists) { @@ -857,13 +868,7 @@ protected void serveResource(HttpServletRequest request, if (cacheEntry.context != null) { 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; } @@ -1074,6 +1079,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 836d09572aa2..53e1ff35fe60 100644 --- a/java/org/apache/catalina/servlets/WebdavServlet.java +++ b/java/org/apache/catalina/servlets/WebdavServlet.java @@ -430,6 +430,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/java/org/apache/tomcat/util/http/mapper/Mapper.java b/java/org/apache/tomcat/util/http/mapper/Mapper.java index 90ca3a7f1788..e27dc5b800df 100644 --- a/java/org/apache/tomcat/util/http/mapper/Mapper.java +++ b/java/org/apache/tomcat/util/http/mapper/Mapper.java @@ -887,20 +887,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 @@ -938,8 +931,10 @@ private final void internalMapWrapper(ContextVersion contextVersion, if(mappingData.wrapper == null && noServletPath && contextVersion.mapperContextRootRedirectEnabled) { // 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; } @@ -1060,7 +1055,11 @@ private final void internalMapWrapper(ContextVersion contextVersion, Object file = null; String pathStr = path.toString(); try { - file = contextVersion.resources.lookup(pathStr); + if (pathStr.length() == 0) { + file = contextVersion.resources.lookup("/"); + } else { + file = contextVersion.resources.lookup(pathStr); + } } catch(NamingException nex) { // Swallow, since someone else handles the 404 } diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml index 6f186354703a..dbbb8d3a8e8d 100644 --- a/webapps/docs/changelog.xml +++ b/webapps/docs/changelog.xml @@ -58,6 +58,15 @@ issues do not "pop up" wrt. others). -->
+ + + + 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) + + +