This is an automated email from the ASF dual-hosted git repository. dsoumis pushed a commit to branch 11.0.x in repository https://gitbox.apache.org/repos/asf/tomcat.git
commit 30229533c3570220b7c46504721826c5a3ab45c2 Author: Dimitris Soumis <[email protected]> AuthorDate: Tue Jun 9 14:08:39 2026 +0300 Add showReport attribute in ProxyErrorReportValve. --- .../catalina/valves/ProxyErrorReportValve.java | 23 +++--- .../catalina/valves/TestProxyErrorReportValve.java | 87 ++++++++++++++++++++++ webapps/docs/config/valve.xml | 12 +++ 3 files changed, 112 insertions(+), 10 deletions(-) diff --git a/java/org/apache/catalina/valves/ProxyErrorReportValve.java b/java/org/apache/catalina/valves/ProxyErrorReportValve.java index 80883f51a7..a813f51c9b 100644 --- a/java/org/apache/catalina/valves/ProxyErrorReportValve.java +++ b/java/org/apache/catalina/valves/ProxyErrorReportValve.java @@ -193,19 +193,22 @@ public class ProxyErrorReportValve extends ErrorReportValve { reason = smClient.getString("errorReportValve.unknownReason"); description = smClient.getString("errorReportValve.noDescription"); } - stringBuilder.append("&statusDescription="); - stringBuilder.append(URLEncoder.encode(description, StandardCharsets.UTF_8)); stringBuilder.append("&statusReason="); stringBuilder.append(URLEncoder.encode(reason, StandardCharsets.UTF_8)); - String message = response.getMessage(); - if (message != null) { - stringBuilder.append("&message="); - stringBuilder.append(URLEncoder.encode(message, StandardCharsets.UTF_8)); - } - if (throwable != null) { - stringBuilder.append("&throwable="); - stringBuilder.append(URLEncoder.encode(throwable.toString(), StandardCharsets.UTF_8)); + if (isShowReport()) { + stringBuilder.append("&statusDescription="); + stringBuilder.append(URLEncoder.encode(description, StandardCharsets.UTF_8)); + + String message = response.getMessage(); + if (message != null) { + stringBuilder.append("&message="); + stringBuilder.append(URLEncoder.encode(message, StandardCharsets.UTF_8)); + } + if (throwable != null) { + stringBuilder.append("&throwable="); + stringBuilder.append(URLEncoder.encode(throwable.toString(), StandardCharsets.UTF_8)); + } } urlString = stringBuilder.toString(); diff --git a/test/org/apache/catalina/valves/TestProxyErrorReportValve.java b/test/org/apache/catalina/valves/TestProxyErrorReportValve.java index 0010397eec..8a53b0649f 100644 --- a/test/org/apache/catalina/valves/TestProxyErrorReportValve.java +++ b/test/org/apache/catalina/valves/TestProxyErrorReportValve.java @@ -18,6 +18,9 @@ package org.apache.catalina.valves; import java.io.IOException; import java.io.Serial; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import jakarta.servlet.http.HttpServlet; import jakarta.servlet.http.HttpServletRequest; @@ -249,6 +252,90 @@ public class TestProxyErrorReportValve extends TomcatBaseTest { } + @Test + public void testRedirectShowReportFalse() throws Exception { + Tomcat tomcat = getTomcatInstance(); + StandardHost host = (StandardHost) tomcat.getHost(); + host.setErrorReportValveClass(PROXY_VALVE); + + Context ctx = getProgrammaticRootContext(); + + Tomcat.addServlet(ctx, "sendError", new SendErrorServlet( + HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Server broke")); + ctx.addServletMappingDecoded("/", "sendError"); + + Tomcat.addServlet(ctx, "errorPage", new ErrorPageServlet()); + ctx.addServletMappingDecoded("/error-page", "errorPage"); + + tomcat.start(); + + ProxyErrorReportValve proxyErrorReportValve = null; + for (Valve valve : host.getPipeline().getValves()) { + if (valve instanceof ProxyErrorReportValve) { + proxyErrorReportValve = (ProxyErrorReportValve) valve; + break; + } + } + Assert.assertNotNull(proxyErrorReportValve); + proxyErrorReportValve.setUseRedirect(true); + proxyErrorReportValve.setShowReport(false); + proxyErrorReportValve.setProperty("errorCode." + HttpServletResponse.SC_INTERNAL_SERVER_ERROR, + "http://localhost:" + getPort() + "/error-page"); + + ByteChunk res = new ByteChunk(); + Map<String, List<String>> resHead = new HashMap<>(); + int rc = methodUrl("http://localhost:" + getPort(), res, + DEFAULT_CLIENT_TIMEOUT_MS, null, resHead, "GET", false); + + Assert.assertEquals(HttpServletResponse.SC_FOUND, rc); + + List<String> locationHeader = resHead.get("Location"); + Assert.assertNotNull(locationHeader); + String location = locationHeader.get(0); + + Assert.assertTrue(location.contains("statusCode=")); + Assert.assertTrue(location.contains("statusReason=")); + Assert.assertFalse(location.contains("message=")); + Assert.assertFalse(location.contains("throwable=")); + Assert.assertFalse(location.contains("statusDescription=")); + } + + + @Test + public void testNoErrorPageShowReportFalse() throws Exception { + Tomcat tomcat = getTomcatInstance(); + StandardHost host = (StandardHost) tomcat.getHost(); + host.setErrorReportValveClass(PROXY_VALVE); + + Context ctx = getProgrammaticRootContext(); + + Tomcat.addServlet(ctx, "sendError", new SendErrorServlet( + HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Server broke")); + ctx.addServletMappingDecoded("/", "sendError"); + + tomcat.start(); + + ProxyErrorReportValve proxyErrorReportValve = null; + for (Valve valve : host.getPipeline().getValves()) { + if (valve instanceof ProxyErrorReportValve) { + proxyErrorReportValve = (ProxyErrorReportValve) valve; + break; + } + } + Assert.assertNotNull(proxyErrorReportValve); + proxyErrorReportValve.setShowReport(false); + + ByteChunk res = new ByteChunk(); + int rc = getUrl("http://localhost:" + getPort(), res, null); + + Assert.assertEquals(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, rc); + + String body = res.toString(); + Assert.assertNotNull(body); + Assert.assertFalse(body.contains("Server broke")); + } + + private static final class SendErrorServlet extends HttpServlet { @Serial diff --git a/webapps/docs/config/valve.xml b/webapps/docs/config/valve.xml index 971c378ca9..62cfb974db 100644 --- a/webapps/docs/config/valve.xml +++ b/webapps/docs/config/valve.xml @@ -2498,6 +2498,18 @@ value is <code>false</code>.</p> </attribute> + <attribute name="showReport" required="false"> + <p>Flag to determine if the error report details (description, custom + error message and/or stack trace) are included in the query + parameters of the redirect or proxy URL when an error occurs. If + set to <code>false</code>, then only the status code and reason + phrase are included. When falling back to the default error report + valve (no error page configured), this flag also controls whether + the HTML error report includes these details. + Default value: <code>true</code> + </p> + </attribute> + <attribute name="useRedirect" required="false"> <p>If <code>true</code>, the valve will redirect the client to the URL that displays the error and the redirect will include full details of --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
