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 2022/03/15 20:52:26 UTC
[tomcat] branch 8.5.x updated: Backport errorCode.nnn handling to 8.5.x
This is an automated email from the ASF dual-hosted git repository.
markt pushed a commit to branch 8.5.x
in repository https://gitbox.apache.org/repos/asf/tomcat.git
The following commit(s) were added to refs/heads/8.5.x by this push:
new 2366a69 Backport errorCode.nnn handling to 8.5.x
2366a69 is described below
commit 2366a695507aa261fdada21ca4072faa57319fa2
Author: Mark Thomas <ma...@apache.org>
AuthorDate: Wed Feb 14 10:17:19 2018 +0000
Backport errorCode.nnn handling to 8.5.x
Fix https://bz.apache.org/bugzilla/show_bug.cgi?id=41007
Add the ability to specify static HTML responses for specific error
codes and/or exception types with the ErrorReportValve.
---
.../org/apache/catalina/util/ErrorPageSupport.java | 4 -
.../apache/catalina/valves/ErrorReportValve.java | 107 +++++++++++++++++++++
.../apache/catalina/valves/LocalStrings.properties | 2 +
.../catalina/valves/LocalStrings_fr.properties | 2 +
.../catalina/valves/LocalStrings_ja.properties | 2 +
.../catalina/valves/LocalStrings_ko.properties | 2 +
.../catalina/valves/LocalStrings_zh_CN.properties | 2 +
webapps/docs/changelog.xml | 9 ++
webapps/docs/config/valve.xml | 29 +++++-
9 files changed, 154 insertions(+), 5 deletions(-)
diff --git a/java/org/apache/catalina/util/ErrorPageSupport.java b/java/org/apache/catalina/util/ErrorPageSupport.java
index 0a241e8..19ebba7 100644
--- a/java/org/apache/catalina/util/ErrorPageSupport.java
+++ b/java/org/apache/catalina/util/ErrorPageSupport.java
@@ -68,11 +68,7 @@ public class ErrorPageSupport {
*
* @return The ErrorPage for the named exception type, or {@code null} if
* none is configured
- *
- * @deprecated Unused. Will be removed in Tomcat 10.
- * Use {@link #find(Throwable)} instead.
*/
- @Deprecated
public ErrorPage find(String exceptionType) {
return exceptionPages.get(exceptionType);
}
diff --git a/java/org/apache/catalina/valves/ErrorReportValve.java b/java/org/apache/catalina/valves/ErrorReportValve.java
index 74ccc1f..ae02d62 100644
--- a/java/org/apache/catalina/valves/ErrorReportValve.java
+++ b/java/org/apache/catalina/valves/ErrorReportValve.java
@@ -16,7 +16,11 @@
*/
package org.apache.catalina.valves;
+import java.io.File;
+import java.io.FileInputStream;
import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
import java.io.Writer;
import java.util.Scanner;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -27,10 +31,13 @@ import javax.servlet.http.HttpServletResponse;
import org.apache.catalina.connector.Request;
import org.apache.catalina.connector.Response;
+import org.apache.catalina.util.ErrorPageSupport;
+import org.apache.catalina.util.IOTools;
import org.apache.catalina.util.ServerInfo;
import org.apache.catalina.util.TomcatCSS;
import org.apache.coyote.ActionCode;
import org.apache.tomcat.util.ExceptionUtils;
+import org.apache.tomcat.util.descriptor.web.ErrorPage;
import org.apache.tomcat.util.res.StringManager;
import org.apache.tomcat.util.security.Escape;
@@ -54,7 +61,11 @@ public class ErrorReportValve extends ValveBase {
private boolean showServerInfo = true;
+ private final ErrorPageSupport errorPageSupport = new ErrorPageSupport();
+
+
//------------------------------------------------------ Constructor
+
public ErrorReportValve() {
super(true);
}
@@ -168,6 +179,27 @@ public class ErrorReportValve extends ValveBase {
return;
}
+ ErrorPage errorPage = null;
+ if (throwable != null) {
+ errorPage = errorPageSupport.find(throwable);
+ }
+ if (errorPage == null) {
+ errorPage = errorPageSupport.find(statusCode);
+ }
+ if (errorPage == null) {
+ // Default error page
+ errorPage = errorPageSupport.find(0);
+ }
+
+
+ if (errorPage != null) {
+ if (sendErrorPage(errorPage.getLocation(), response)) {
+ // If the page was sent successfully, don't write the standard
+ // error page.
+ return;
+ }
+ }
+
String message = Escape.htmlElementContent(response.getMessage());
if (message == null) {
if (throwable != null) {
@@ -331,6 +363,37 @@ public class ErrorReportValve extends ValveBase {
return trace.toString();
}
+
+ private boolean sendErrorPage(String location, Response response) {
+ File file = new File(location);
+ if (!file.isAbsolute()) {
+ file = new File(getContainer().getCatalinaBase(), location);
+ }
+ if (!file.isFile() || !file.canRead()) {
+ getContainer().getLogger().warn(
+ sm.getString("errorReportValve.errorPageNotFound", location));
+ return false;
+ }
+
+ // Hard coded for now. Consider making this optional. At Valve level or
+ // page level?
+ response.setContentType("text/html");
+ response.setCharacterEncoding("UTF-8");
+
+ try {
+ OutputStream os = response.getOutputStream();
+ InputStream is = new FileInputStream(file);
+ IOTools.flow(is, os);
+ } catch (IOException e) {
+ getContainer().getLogger().warn(
+ sm.getString("errorReportValve.errorPageIOException", location), e);
+ return false;
+ }
+
+ return true;
+ }
+
+
/**
* Enables/Disables full error reports
*
@@ -356,4 +419,48 @@ public class ErrorReportValve extends ValveBase {
public boolean isShowServerInfo() {
return showServerInfo;
}
+
+
+ public boolean setProperty(String name, String value) {
+ if (name.startsWith("errorCode.")) {
+ int code = Integer.parseInt(name.substring(10));
+ ErrorPage ep = new ErrorPage();
+ ep.setErrorCode(code);
+ ep.setLocation(value);
+ errorPageSupport.add(ep);
+ return true;
+ } else if (name.startsWith("exceptionType.")) {
+ String className = name.substring(14);
+ ErrorPage ep = new ErrorPage();
+ ep.setExceptionType(className);
+ ep.setLocation(value);
+ errorPageSupport.add(ep);
+ return true;
+ }
+ return false;
+ }
+
+ public String getProperty(String name) {
+ String result;
+ if (name.startsWith("errorCode.")) {
+ int code = Integer.parseInt(name.substring(10));
+ ErrorPage ep = errorPageSupport.find(code);
+ if (ep == null) {
+ result = null;
+ } else {
+ result = ep.getLocation();
+ }
+ } else if (name.startsWith("exceptionType.")) {
+ String className = name.substring(14);
+ ErrorPage ep = errorPageSupport.find(className);
+ if (ep == null) {
+ result = null;
+ } else {
+ result = ep.getLocation();
+ }
+ } else {
+ result = null;
+ }
+ return result;
+ }
}
diff --git a/java/org/apache/catalina/valves/LocalStrings.properties b/java/org/apache/catalina/valves/LocalStrings.properties
index b7f38fc..a144166 100644
--- a/java/org/apache/catalina/valves/LocalStrings.properties
+++ b/java/org/apache/catalina/valves/LocalStrings.properties
@@ -27,6 +27,8 @@ accessLogValve.unsupportedEncoding=Failed to set encoding to [{0}], will use the
accessLogValve.writeFail=Failed to write log message [{0}]
errorReportValve.description=Description
+errorReportValve.errorPageIOException=Unable to display error page at [{0}] due to an exception
+errorReportValve.errorPageNotFound=Unable to find a static error page at [{0}]
errorReportValve.exception=Exception
errorReportValve.exceptionReport=Exception Report
errorReportValve.message=Message
diff --git a/java/org/apache/catalina/valves/LocalStrings_fr.properties b/java/org/apache/catalina/valves/LocalStrings_fr.properties
index bafd479..01eb334 100644
--- a/java/org/apache/catalina/valves/LocalStrings_fr.properties
+++ b/java/org/apache/catalina/valves/LocalStrings_fr.properties
@@ -27,6 +27,8 @@ accessLogValve.unsupportedEncoding=Impossible de changer l''encodage en [{0}], l
accessLogValve.writeFail=Impossible d''écrire le message de log [{0}]
errorReportValve.description=description
+errorReportValve.errorPageIOException=Impossible d''afficher la page d''erreur à [{0}] à cause d''une exception
+errorReportValve.errorPageNotFound=Impossible de trouver une erreur page statique à [{0}]
errorReportValve.exception=exception
errorReportValve.exceptionReport=Rapport d'exception
errorReportValve.message=message
diff --git a/java/org/apache/catalina/valves/LocalStrings_ja.properties b/java/org/apache/catalina/valves/LocalStrings_ja.properties
index a04dca2..94004bf 100644
--- a/java/org/apache/catalina/valves/LocalStrings_ja.properties
+++ b/java/org/apache/catalina/valves/LocalStrings_ja.properties
@@ -27,6 +27,8 @@ accessLogValve.unsupportedEncoding=文字エンコーディングに [{0}] を
accessLogValve.writeFail=ログメッセージ [{0}] の書き込みに失敗しました
errorReportValve.description=説明
+errorReportValve.errorPageIOException=例外のため [{0}] にエラーページを表示できません
+errorReportValve.errorPageNotFound=[{0}]に静的エラーページが見つかりません。
errorReportValve.exception=例外
errorReportValve.exceptionReport=例外報告
errorReportValve.message=メッセージ
diff --git a/java/org/apache/catalina/valves/LocalStrings_ko.properties b/java/org/apache/catalina/valves/LocalStrings_ko.properties
index bd8918f..55502ce 100644
--- a/java/org/apache/catalina/valves/LocalStrings_ko.properties
+++ b/java/org/apache/catalina/valves/LocalStrings_ko.properties
@@ -27,6 +27,8 @@ accessLogValve.unsupportedEncoding=인코딩을 [{0}](으)로 설정하지 못
accessLogValve.writeFail=다음 로그 메시지를 쓰지 못했습니다: [{0}]
errorReportValve.description=설명
+errorReportValve.errorPageIOException=예외 발생으로 인하여 [{0}]에 위치한 오류 페이지를 표시할 수 없습니다.
+errorReportValve.errorPageNotFound=[{0}]에 위치한 정적 오류 페이지를 찾을 수 없습니다.
errorReportValve.exception=예외
errorReportValve.exceptionReport=예외 보고
errorReportValve.message=메시지
diff --git a/java/org/apache/catalina/valves/LocalStrings_zh_CN.properties b/java/org/apache/catalina/valves/LocalStrings_zh_CN.properties
index 063525d..15b734d 100644
--- a/java/org/apache/catalina/valves/LocalStrings_zh_CN.properties
+++ b/java/org/apache/catalina/valves/LocalStrings_zh_CN.properties
@@ -27,6 +27,8 @@ accessLogValve.unsupportedEncoding=未能将编码设置为[{0}],将使用系
accessLogValve.writeFail=无法写入日志消息[{0}]
errorReportValve.description=描述
+errorReportValve.errorPageIOException=由于出现异常,无法在[{0}]处显示错误页
+errorReportValve.errorPageNotFound=在[{0}]无法找到静态错误页面
errorReportValve.exception=例外情况
errorReportValve.exceptionReport=异常报告
errorReportValve.message=消息
diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index dc71da6..f1deb1c 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -105,6 +105,15 @@
issues do not "pop up" wrt. others).
-->
<section name="Tomcat 8.5.78 (schultz)" rtext="in development">
+ <subsection name="Catalina">
+ <changelog>
+ <add>
+ <bug>41007</bug>: Add the ability to specify static HTML responses for
+ specific error codes and/or exception types with the
+ <code>ErrorReportValve</code>. (markt)
+ </add>
+ </changelog>
+ </subsection>
<subsection name="Web applications">
<changelog>
<fix>
diff --git a/webapps/docs/config/valve.xml b/webapps/docs/config/valve.xml
index 04760d9..ee9bdf4 100644
--- a/webapps/docs/config/valve.xml
+++ b/webapps/docs/config/valve.xml
@@ -2103,7 +2103,9 @@
<subsection name="Introduction">
<p>The <strong>Error Report Valve</strong> is a simple error handler
- for HTTP status codes that will generate and return HTML error pages.</p>
+ for HTTP status codes that will generate and return HTML error pages. It can
+ also be configured to return pre-defined static HTML pages for specific
+ status codes and/or exception types.</p>
<p><strong>NOTE:</strong> Disabling both showServerInfo and showReport will
only return the HTTP status code.</p>
@@ -2123,6 +2125,31 @@
default error report valve.</p>
</attribute>
+ <attribute name="errorCode.nnn" required="false">
+ <p>The location of the UTF-8 encoded HTML file to return for the HTTP
+ error code represented by <code>nnn</code>. For example,
+ <code>errorCode.404</code> specifies the file to return for an HTTP 404
+ error. The location may be relative or absolule. If relative, it must be
+ relative to <code>$CATALINA_BASE</code>. The special value of
+ <code>errorCode.0</code> may be used to define a default error page to
+ be used if no error page is defined for a status code. If no matching
+ error page is found, the default <strong>Error Report Valve</strong>
+ response will be returned.</p>
+ </attribute>
+
+ <attribute name="exceptionType.fullyQualifiedClassName" required="false">
+ <p>The location of the UTF-8 encoded HTML file to return if an error has
+ occurred and the <code>javax.servlet.error.exception</code> request
+ attribute has been set to an instance of
+ <code>fullyQualifiedClassName</code> or a sub-class of it. For example,
+ <code>errorCode.java.io.IOException</code> specifies the file to return
+ for an <code>IOException</code>. The location may be relative or
+ absolule. If relative, it must be relative to
+ <code>$CATALINA_BASE</code>. If no matching error page is found, the
+ default <strong>Error Report Valve</strong> response will be
+ returned.</p>
+ </attribute>
+
<attribute name="showReport" required="false">
<p>Flag to determine if the error report (custom error message and/or
stack trace) is presented when an error occurs. If set to
---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org