You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2019/03/21 17:32:10 UTC
[tomcat] branch 7.0.x updated:
https://bz.apache.org/bugzilla/show_bug.cgi?id=63275 enc getContextPath
This is an automated email from the ASF dual-hosted git repository.
markt pushed a commit to branch 7.0.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/7.0.x by this push:
new 4d571d6 https://bz.apache.org/bugzilla/show_bug.cgi?id=63275 enc getContextPath
4d571d6 is described below
commit 4d571d6897131f533a3e3ac41ccaebcde3768720
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Thu Mar 21 14:46:14 2019 +0000
https://bz.apache.org/bugzilla/show_bug.cgi?id=63275 enc getContextPath
When using a RequestDispatcher ensure that
HttpServletRequest.getContextPath() returns an encoded path in the
dispatched request.
---
.../catalina/core/ApplicationDispatcher.java | 71 +++++++++++-----------
...TestApplicationContextGetRequestDispatcher.java | 14 ++++-
webapps/docs/changelog.xml | 5 ++
3 files changed, 51 insertions(+), 39 deletions(-)
diff --git a/java/org/apache/catalina/core/ApplicationDispatcher.java b/java/org/apache/catalina/core/ApplicationDispatcher.java
index 49acfd6..8e2bfac 100644
--- a/java/org/apache/catalina/core/ApplicationDispatcher.java
+++ b/java/org/apache/catalina/core/ApplicationDispatcher.java
@@ -5,9 +5,9 @@
* 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.
@@ -70,7 +70,7 @@ final class ApplicationDispatcher implements AsyncDispatcher, RequestDispatcher
static {
STRICT_SERVLET_COMPLIANCE = Globals.STRICT_SERVLET_COMPLIANCE;
-
+
String wrapSameObject = System.getProperty(
"org.apache.catalina.core.ApplicationDispatcher.WRAP_SAME_OBJECT");
if (wrapSameObject == null) {
@@ -156,7 +156,7 @@ final class ApplicationDispatcher implements AsyncDispatcher, RequestDispatcher
* The outermost response that will be passed on to the invoked servlet.
*/
ServletResponse outerResponse = null;
-
+
/**
* The request wrapper we have created and installed (if any).
*/
@@ -167,7 +167,7 @@ final class ApplicationDispatcher implements AsyncDispatcher, RequestDispatcher
* The response wrapper we have created and installed (if any).
*/
ServletResponse wrapResponse = null;
-
+
/**
* Are we performing an include() instead of a forward()?
*/
@@ -341,7 +341,7 @@ final class ApplicationDispatcher implements AsyncDispatcher, RequestDispatcher
private void doForward(ServletRequest request, ServletResponse response)
throws ServletException, IOException
{
-
+
// Reset any output that has been buffered, but keep headers/cookies
if (response.isCommitted()) {
throw new IllegalStateException
@@ -382,7 +382,6 @@ final class ApplicationDispatcher implements AsyncDispatcher, RequestDispatcher
ApplicationHttpRequest wrequest =
(ApplicationHttpRequest) wrapRequest(state);
- String contextPath = context.getPath();
HttpServletRequest hrequest = state.hrequest;
if (hrequest.getAttribute(
RequestDispatcher.FORWARD_REQUEST_URI) == null) {
@@ -397,8 +396,8 @@ final class ApplicationDispatcher implements AsyncDispatcher, RequestDispatcher
wrequest.setAttribute(RequestDispatcher.FORWARD_QUERY_STRING,
hrequest.getQueryString());
}
-
- wrequest.setContextPath(contextPath);
+
+ wrequest.setContextPath(context.getEncodedPath());
wrequest.setRequestURI(requestURI);
wrequest.setServletPath(servletPath);
wrequest.setPathInfo(pathInfo);
@@ -424,9 +423,9 @@ final class ApplicationDispatcher implements AsyncDispatcher, RequestDispatcher
((ResponseFacade) response).finish();
} else {
// Servlet SRV.6.2.2. The Request/Response may have been wrapped
- // and may no longer be instance of RequestFacade
+ // and may no longer be instance of RequestFacade
if (wrapper.getLogger().isDebugEnabled()){
- wrapper.getLogger().debug( " The Response is vehiculed using a wrapper: "
+ wrapper.getLogger().debug( " The Response is vehiculed using a wrapper: "
+ response.getClass().getName() );
}
@@ -450,7 +449,7 @@ final class ApplicationDispatcher implements AsyncDispatcher, RequestDispatcher
}
-
+
/**
* Prepare the request based on the filter configuration.
* @param request The servlet request we are processing
@@ -460,15 +459,15 @@ final class ApplicationDispatcher implements AsyncDispatcher, RequestDispatcher
* @exception IOException if an input/output error occurs
* @exception ServletException if a servlet error occurs
*/
- private void processRequest(ServletRequest request,
+ private void processRequest(ServletRequest request,
ServletResponse response,
State state)
throws IOException, ServletException {
-
+
DispatcherType disInt = (DispatcherType) request.getAttribute(Globals.DISPATCHER_TYPE_ATTR);
if (disInt != null) {
boolean doInvoke = true;
-
+
if (context.getFireRequestListenersOnForwards() &&
!context.fireRequestInitEvent(request)) {
doInvoke = false;
@@ -486,15 +485,15 @@ final class ApplicationDispatcher implements AsyncDispatcher, RequestDispatcher
} else {
invoke(state.outerRequest, response, state);
}
-
+
if (context.getFireRequestListenersOnForwards()) {
context.fireRequestDestroyEvent(request);
}
}
}
}
-
-
+
+
/**
* Combine the servletPath and the pathInfo. If pathInfo is
* <code>null</code> it is ignored. If servletPath is <code>null</code> then
@@ -553,7 +552,7 @@ final class ApplicationDispatcher implements AsyncDispatcher, RequestDispatcher
// Check SRV.8.2 / SRV.14.2.5.1 compliance
checkSameObjects(request, response);
}
-
+
// Create a wrapped response to use for this request
wrapResponse(state);
@@ -595,7 +594,7 @@ final class ApplicationDispatcher implements AsyncDispatcher, RequestDispatcher
queryString);
wrequest.setQueryParams(queryString);
}
-
+
wrequest.setAttribute(Globals.DISPATCHER_TYPE_ATTR,
DispatcherType.INCLUDE);
wrequest.setAttribute(Globals.DISPATCHER_REQUEST_PATH_ATTR,
@@ -642,7 +641,7 @@ final class ApplicationDispatcher implements AsyncDispatcher, RequestDispatcher
wrequest.setAttribute(Globals.DISPATCHER_REQUEST_PATH_ATTR,
getCombinedPath());
- wrequest.setContextPath(context.getPath());
+ wrequest.setContextPath(context.getEncodedPath());
wrequest.setRequestURI(requestURI);
wrequest.setServletPath(servletPath);
wrequest.setPathInfo(pathInfo);
@@ -699,7 +698,7 @@ final class ApplicationDispatcher implements AsyncDispatcher, RequestDispatcher
// Check for the servlet being marked unavailable
if (wrapper.isUnavailable()) {
wrapper.getLogger().warn(
- sm.getString("applicationDispatcher.isUnavailable",
+ sm.getString("applicationDispatcher.isUnavailable",
wrapper.getName()));
long available = wrapper.getAvailable();
if ((available > 0L) && (available < Long.MAX_VALUE))
@@ -728,12 +727,12 @@ final class ApplicationDispatcher implements AsyncDispatcher, RequestDispatcher
wrapper.getName()), e);
servlet = null;
}
-
+
// Get the FilterChain Here
ApplicationFilterFactory factory = ApplicationFilterFactory.getInstance();
ApplicationFilterChain filterChain = factory.createFilterChain(request,
wrapper,servlet);
-
+
// Call the service() method for the allocated servlet instance
try {
support.fireInstanceEvent(InstanceEvent.BEFORE_DISPATCH_EVENT,
@@ -811,14 +810,14 @@ final class ApplicationDispatcher implements AsyncDispatcher, RequestDispatcher
// Reset the old context class loader
if (oldCCL != null)
Thread.currentThread().setContextClassLoader(oldCCL);
-
+
// Unwrap request/response if needed
// See Bugzilla 30949
unwrapRequest(state);
unwrapResponse(state);
// Recycle request if necessary (also BZ 30949)
recycleRequestWrapper(state);
-
+
// Rethrow an exception if one was thrown by the invoked servlet
if (ioException != null)
throw ioException;
@@ -871,7 +870,7 @@ final class ApplicationDispatcher implements AsyncDispatcher, RequestDispatcher
}
}
-
+
/**
* Unwrap the response if we have wrapped it.
*/
@@ -948,7 +947,7 @@ final class ApplicationDispatcher implements AsyncDispatcher, RequestDispatcher
if ((state.outerRequest instanceof ApplicationHttpRequest) ||
(state.outerRequest instanceof Request) ||
(state.outerRequest instanceof HttpServletRequest)) {
- HttpServletRequest houterRequest =
+ HttpServletRequest houterRequest =
(HttpServletRequest) state.outerRequest;
Object contextPath = houterRequest.getAttribute(
RequestDispatcher.INCLUDE_CONTEXT_PATH);
@@ -1023,15 +1022,15 @@ final class ApplicationDispatcher implements AsyncDispatcher, RequestDispatcher
ApplicationFilterChain.getLastServicedRequest();
ServletResponse originalResponse =
ApplicationFilterChain.getLastServicedResponse();
-
- // Some forwards, eg from valves will not set original values
+
+ // Some forwards, eg from valves will not set original values
if (originalRequest == null || originalResponse == null) {
return;
}
-
+
boolean same = false;
ServletRequest dispatchedRequest = appRequest;
-
+
//find the request that was passed into the service method
while (originalRequest instanceof ServletRequestWrapper &&
((ServletRequestWrapper) originalRequest).getRequest()!=null ) {
@@ -1054,13 +1053,13 @@ final class ApplicationDispatcher implements AsyncDispatcher, RequestDispatcher
throw new ServletException(sm.getString(
"applicationDispatcher.specViolation.request"));
}
-
+
same = false;
ServletResponse dispatchedResponse = appResponse;
-
+
//find the response that was passed into the service method
while (originalResponse instanceof ServletResponseWrapper &&
- ((ServletResponseWrapper) originalResponse).getResponse() !=
+ ((ServletResponseWrapper) originalResponse).getResponse() !=
null ) {
originalResponse =
((ServletResponseWrapper) originalResponse).getResponse();
@@ -1070,7 +1069,7 @@ final class ApplicationDispatcher implements AsyncDispatcher, RequestDispatcher
if (originalResponse.equals(dispatchedResponse)) {
same = true;
}
-
+
if (!same && dispatchedResponse instanceof ServletResponseWrapper) {
dispatchedResponse =
((ServletResponseWrapper) dispatchedResponse).getResponse();
diff --git a/test/org/apache/catalina/core/TestApplicationContextGetRequestDispatcher.java b/test/org/apache/catalina/core/TestApplicationContextGetRequestDispatcher.java
index b2177f4..c2be051 100644
--- a/test/org/apache/catalina/core/TestApplicationContextGetRequestDispatcher.java
+++ b/test/org/apache/catalina/core/TestApplicationContextGetRequestDispatcher.java
@@ -372,8 +372,11 @@ public class TestApplicationContextGetRequestDispatcher extends TomcatBaseTest {
// Setup Tomcat instance
Tomcat tomcat = getTomcatInstance();
+ // Need to make sure we use UTF-8 for the URI
+ tomcat.getConnector().setURIEncoding("UTF-8");
+
// No file system docBase required
- Context ctx = tomcat.addContext("/test", null);
+ Context ctx = tomcat.addContext("/test\u6771\u4eac", null);
ctx.setDispatchersUseEncodedPaths(useEncodedDispatchPaths);
// Add a default servlet to return 404 for not found resources
@@ -399,7 +402,7 @@ public class TestApplicationContextGetRequestDispatcher extends TomcatBaseTest {
StringBuilder url = new StringBuilder("http://localhost:");
url.append(getPort());
- url.append("/test");
+ url.append("/test%E6%9D%B1%E4%BA%AC");
url.append(startPath);
if (startQueryString != null) {
url.append('?');
@@ -466,7 +469,12 @@ public class TestApplicationContextGetRequestDispatcher extends TomcatBaseTest {
throws ServletException, IOException {
resp.setContentType("text/plain");
resp.setCharacterEncoding("UTF-8");
- resp.getWriter().print(OK);
+ String contextPath = req.getContextPath();
+ if ("/test%E6%9D%B1%E4%BA%AC".equals(contextPath)) {
+ resp.getWriter().print(OK);
+ } else {
+ resp.getWriter().print("FAIL - ContextPath");
+ }
String qs = req.getQueryString();
if (qs != null) {
resp.getWriter().print(qs);
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 387c850..79d78b3 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -115,6 +115,11 @@
Ensure that the JarScanner correctly tests whether JARs found on the
class path should be skipped when running on Java 9 or later. (markt)
</fix>
+ <fix>
+ <bug>63275</bug>: When using a <code>RequestDispatcher</code> ensure
+ that <code>HttpServletRequest.getContextPath()</code> returns an encoded
+ path in the dispatched request. (markt)
+ </fix>
</changelog>
</subsection>
<subsection name="Coyote">
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org