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]

Reply via email to