You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by re...@apache.org on 2003/07/19 16:30:07 UTC
cvs commit: jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/valves LocalStrings.properties mbeans-descriptors.xml ErrorDispatcherValve.java
remm 2003/07/19 07:30:07
Modified: catalina/src/share/org/apache/catalina/core
LocalStrings.properties StandardHost.java
StandardHostValve.java StandardServer.java
catalina/src/share/org/apache/catalina/valves
LocalStrings.properties mbeans-descriptors.xml
Removed: catalina/src/share/org/apache/catalina/valves
ErrorDispatcherValve.java
Log:
- Merge ErrorDispacherValve functionality back into StadardHostValve, and
remove associated hacks from StandardServer and StandardHost.
Revision Changes Path
1.8 +1 -0 jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/core/LocalStrings.properties
Index: LocalStrings.properties
===================================================================
RCS file: /home/cvs/jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/core/LocalStrings.properties,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -r1.7 -r1.8
--- LocalStrings.properties 24 Jun 2003 22:37:33 -0000 1.7
+++ LocalStrings.properties 19 Jul 2003 14:30:07 -0000 1.8
@@ -93,6 +93,7 @@
standardHost.accessBase=Cannot access document base directory {0}
standardHost.alreadyStarted=Host has already been started
standardHost.appBase=Application base directory {0} does not exist
+standardHost.clientAbort=Remote Client Aborted Request, IOException: {0}
standardHost.configRequired=URL to configuration file is required
standardHost.configNotAllowed=Use of configuration file is not allowed
standardHost.installBase=Only web applications in the Host web application directory can be installed
1.19 +1 -5 jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/core/StandardHost.java
Index: StandardHost.java
===================================================================
RCS file: /home/cvs/jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/core/StandardHost.java,v
retrieving revision 1.18
retrieving revision 1.19
diff -u -r1.18 -r1.19
--- StandardHost.java 21 Jun 2003 20:00:22 -0000 1.18
+++ StandardHost.java 19 Jul 2003 14:30:07 -0000 1.19
@@ -75,7 +75,6 @@
import org.apache.catalina.LifecycleException;
import org.apache.catalina.Valve;
import org.apache.catalina.Realm;
-import org.apache.catalina.valves.ErrorDispatcherValve;
import org.apache.catalina.valves.ValveBase;
import org.apache.commons.modeler.Registry;
@@ -788,9 +787,6 @@
errorReportValveClass));
}
}
-
- // Set dispatcher valve
- addValve(new ErrorDispatcherValve());
super.start();
1.7 +317 -4 jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/core/StandardHostValve.java
Index: StandardHostValve.java
===================================================================
RCS file: /home/cvs/jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/core/StandardHostValve.java,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- StandardHostValve.java 18 Jul 2003 18:49:28 -0000 1.6
+++ StandardHostValve.java 19 Jul 2003 14:30:07 -0000 1.7
@@ -66,16 +66,28 @@
import java.io.IOException;
+import javax.servlet.RequestDispatcher;
+import javax.servlet.ServletContext;
import javax.servlet.ServletException;
+import javax.servlet.ServletRequest;
+import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.catalina.Container;
import org.apache.catalina.Context;
+import org.apache.catalina.Globals;
+import org.apache.catalina.HttpRequest;
+import org.apache.catalina.HttpResponse;
+import org.apache.catalina.Logger;
import org.apache.catalina.Manager;
import org.apache.catalina.Request;
import org.apache.catalina.Response;
import org.apache.catalina.Session;
import org.apache.catalina.ValveContext;
+import org.apache.catalina.Wrapper;
+import org.apache.catalina.connector.ClientAbortException;
+import org.apache.catalina.deploy.ErrorPage;
+import org.apache.catalina.util.RequestUtil;
import org.apache.catalina.util.StringManager;
import org.apache.catalina.valves.ValveBase;
@@ -176,6 +188,307 @@
// Ask this Context to process this request
context.getPipeline().invoke(request, response);
+ // Error page processing
+ response.setSuspended(false);
+
+ Throwable t = (Throwable) hreq.getAttribute(Globals.EXCEPTION_ATTR);
+
+ if (t != null) {
+ throwable(request, response, t);
+ } else {
+ status(request, response);
+ }
+
+ }
+
+
+ // ------------------------------------------------------ Protected Methods
+
+
+ /**
+ * Handle the specified Throwable encountered while processing
+ * the specified Request to produce the specified Response. Any
+ * exceptions that occur during generation of the exception report are
+ * logged and swallowed.
+ *
+ * @param request The request being processed
+ * @param response The response being generated
+ * @param exception The exception that occurred (which possibly wraps
+ * a root cause exception
+ */
+ protected void throwable(Request request, Response response,
+ Throwable throwable) {
+ Context context = request.getContext();
+ if (context == null)
+ return;
+
+ Throwable realError = throwable;
+
+ if (realError instanceof ServletException) {
+ realError = ((ServletException) realError).getRootCause();
+ if (realError == null) {
+ realError = throwable;
+ }
+ }
+
+ // If this is an aborted request from a client just log it and return
+ if (realError instanceof ClientAbortException ) {
+ log(sm.getString(
+ "errorDispatcherValve.clientAbort",
+ ((ClientAbortException)realError).getThrowable().getMessage()));
+ return;
+ }
+
+ ErrorPage errorPage = findErrorPage(context, realError);
+
+ if (errorPage != null) {
+ response.setAppCommitted(false);
+ ServletRequest sreq = request.getRequest();
+ ServletResponse sresp = response.getResponse();
+ sreq.setAttribute
+ (ApplicationFilterFactory.DISPATCHER_REQUEST_PATH_ATTR,
+ errorPage.getLocation());
+ sreq.setAttribute(ApplicationFilterFactory.DISPATCHER_TYPE_ATTR,
+ new Integer(ApplicationFilterFactory.ERROR));
+ sreq.setAttribute
+ (Globals.STATUS_CODE_ATTR,
+ new Integer(HttpServletResponse.SC_INTERNAL_SERVER_ERROR));
+ sreq.setAttribute(Globals.ERROR_MESSAGE_ATTR,
+ throwable.getMessage());
+ sreq.setAttribute(Globals.EXCEPTION_ATTR,
+ realError);
+ Wrapper wrapper = request.getWrapper();
+ if (wrapper != null)
+ sreq.setAttribute(Globals.SERVLET_NAME_ATTR,
+ wrapper.getName());
+ if (sreq instanceof HttpServletRequest)
+ sreq.setAttribute(Globals.EXCEPTION_PAGE_ATTR,
+ ((HttpServletRequest) sreq).getRequestURI());
+ sreq.setAttribute(Globals.EXCEPTION_TYPE_ATTR,
+ realError.getClass());
+ if (custom(request, response, errorPage)) {
+ try {
+ sresp.flushBuffer();
+ } catch (IOException e) {
+ log("Exception Processing " + errorPage, e);
+ }
+ }
+ } else {
+ // A custom error-page has not been defined for the exception
+ // that was thrown during request processing. Check if an
+ // error-page for error code 500 was specified and if so,
+ // send that page back as the response.
+ ServletResponse sresp = (ServletResponse) response;
+ if (sresp instanceof HttpServletResponse) {
+ ((HttpServletResponse) sresp).setStatus(
+ HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+ // The response is an error
+ response.setError();
+
+ status(request, response);
+ }
+ }
+
+
+ }
+
+
+ /**
+ * Handle the HTTP status code (and corresponding message) generated
+ * while processing the specified Request to produce the specified
+ * Response. Any exceptions that occur during generation of the error
+ * report are logged and swallowed.
+ *
+ * @param request The request being processed
+ * @param response The response being generated
+ */
+ protected void status(Request request, Response response) {
+
+ // Do nothing on non-HTTP responses
+ if (!(response instanceof HttpResponse))
+ return;
+ HttpResponse hresponse = (HttpResponse) response;
+ if (!(response.getResponse() instanceof HttpServletResponse))
+ return;
+ int statusCode = hresponse.getStatus();
+ String message = RequestUtil.filter(hresponse.getMessage());
+ if (message == null)
+ message = "";
+
+ // Handle a custom error page for this status code
+ Context context = request.getContext();
+ if (context == null)
+ return;
+
+ ErrorPage errorPage = context.findErrorPage(statusCode);
+ if (errorPage != null) {
+ response.setAppCommitted(false);
+ ServletRequest sreq = request.getRequest();
+ ServletResponse sresp = response.getResponse();
+ sreq.setAttribute(Globals.STATUS_CODE_ATTR,
+ new Integer(statusCode));
+ sreq.setAttribute(Globals.ERROR_MESSAGE_ATTR, message);
+ sreq.setAttribute
+ (ApplicationFilterFactory.DISPATCHER_REQUEST_PATH_ATTR,
+ errorPage.getLocation());
+ sreq.setAttribute(ApplicationFilterFactory.DISPATCHER_TYPE_ATTR,
+ new Integer(ApplicationFilterFactory.ERROR));
+
+
+ Wrapper wrapper = request.getWrapper();
+ if (wrapper != null)
+ sreq.setAttribute(Globals.SERVLET_NAME_ATTR,
+ wrapper.getName());
+ if (sreq instanceof HttpServletRequest)
+ sreq.setAttribute(Globals.EXCEPTION_PAGE_ATTR,
+ ((HttpServletRequest) sreq).getRequestURI());
+ if (custom(request, response, errorPage)) {
+ try {
+ sresp.flushBuffer();
+ } catch (IOException e) {
+ log("Exception Processing " + errorPage, e);
+ }
+ }
+ }
+
}
+
+
+ /**
+ * Find and return the ErrorPage instance for the specified exception's
+ * class, or an ErrorPage instance for the closest superclass for which
+ * there is such a definition. If no associated ErrorPage instance is
+ * found, return <code>null</code>.
+ *
+ * @param context The Context in which to search
+ * @param exception The exception for which to find an ErrorPage
+ */
+ protected static ErrorPage findErrorPage
+ (Context context, Throwable exception) {
+
+ if (exception == null)
+ return (null);
+ Class clazz = exception.getClass();
+ String name = clazz.getName();
+ while (!"java.lang.Object".equals(clazz)) {
+ ErrorPage errorPage = context.findErrorPage(name);
+ if (errorPage != null)
+ return (errorPage);
+ clazz = clazz.getSuperclass();
+ if (clazz == null)
+ break;
+ name = clazz.getName();
+ }
+ return (null);
+
+ }
+
+
+ /**
+ * Handle an HTTP status code or Java exception by forwarding control
+ * to the location included in the specified errorPage object. It is
+ * assumed that the caller has already recorded any request attributes
+ * that are to be forwarded to this page. Return <code>true</code> if
+ * we successfully utilized the specified error page location, or
+ * <code>false</code> if the default error report should be rendered.
+ *
+ * @param request The request being processed
+ * @param response The response being generated
+ * @param errorPage The errorPage directive we are obeying
+ */
+ protected boolean custom(Request request, Response response,
+ ErrorPage errorPage) {
+
+ if (debug >= 1)
+ log("Processing " + errorPage);
+
+ // Validate our current environment
+ if (!(request instanceof HttpRequest)) {
+ if (debug >= 1)
+ log(" Not processing an HTTP request --> default handling");
+ return (false); // NOTE - Nothing we can do generically
+ }
+ HttpServletRequest hreq =
+ (HttpServletRequest) request.getRequest();
+ if (!(response instanceof HttpResponse)) {
+ if (debug >= 1)
+ log("Not processing an HTTP response --> default handling");
+ return (false); // NOTE - Nothing we can do generically
+ }
+ HttpServletResponse hres =
+ (HttpServletResponse) response.getResponse();
+
+ ((HttpRequest) request).setPathInfo(errorPage.getLocation());
+
+ try {
+
+ // Reset the response if possible (else IllegalStateException)
+ //hres.reset();
+ // Reset the response (keeping the real error code and message)
+ Integer statusCodeObj =
+ (Integer) hreq.getAttribute(Globals.STATUS_CODE_ATTR);
+ int statusCode = statusCodeObj.intValue();
+ String message =
+ (String) hreq.getAttribute(Globals.ERROR_MESSAGE_ATTR);
+ ((HttpResponse) response).reset(statusCode, message);
+
+ // Forward control to the specified location
+ ServletContext servletContext =
+ request.getContext().getServletContext();
+ RequestDispatcher rd =
+ servletContext.getRequestDispatcher(errorPage.getLocation());
+ rd.forward(hreq, hres);
+
+ // If we forward, the response is suspended again
+ response.setSuspended(false);
+
+ // Indicate that we have successfully processed this custom page
+ return (true);
+
+ } catch (Throwable t) {
+
+ // Report our failure to process this custom page
+ log("Exception Processing " + errorPage, t);
+ return (false);
+
+ }
+
+ }
+
+
+ /**
+ * Log a message on the Logger associated with our Container (if any).
+ *
+ * @param message Message to be logged
+ */
+ protected void log(String message) {
+
+ Logger logger = container.getLogger();
+ if (logger != null)
+ logger.log(this.toString() + ": " + message);
+ else
+ System.out.println(this.toString() + ": " + message);
+
+ }
+
+
+ /**
+ * Log a message on the Logger associated with our Container (if any).
+ *
+ * @param message Message to be logged
+ * @param throwable Associated exception
+ */
+ protected void log(String message, Throwable throwable) {
+
+ Logger logger = container.getLogger();
+ if (logger != null)
+ logger.log(this.toString() + ": " + message, throwable);
+ else {
+ System.out.println(this.toString() + ": " + message);
+ throwable.printStackTrace(System.out);
+ }
+
+ }
+
}
1.18 +4 -5 jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/core/StandardServer.java
Index: StandardServer.java
===================================================================
RCS file: /home/cvs/jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/core/StandardServer.java,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -r1.17 -r1.18
--- StandardServer.java 22 May 2003 23:04:18 -0000 1.17
+++ StandardServer.java 19 Jul 2003 14:30:07 -0000 1.18
@@ -210,7 +210,6 @@
"org.apache.catalina.startup.EngineConfig",
"org.apache.catalina.startup.HostConfig",
"org.apache.catalina.valves.CertificatesValve",
- "org.apache.catalina.valves.ErrorDispatcherValve",
"org.apache.catalina.valves.ErrorReportValve",
"org.apache.catalina.valves.RequestListenerValve",
};
1.5 +0 -3 jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/valves/LocalStrings.properties
Index: LocalStrings.properties
===================================================================
RCS file: /home/cvs/jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/valves/LocalStrings.properties,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- LocalStrings.properties 19 Jul 2003 10:14:17 -0000 1.4
+++ LocalStrings.properties 19 Jul 2003 14:30:07 -0000 1.5
@@ -10,9 +10,6 @@
requestListenerValve.requestDestroy=Exception sending request destroyed lifecycle event to listener instance of class {0}
valveBase.noNext=Configuration error: No 'next' valve configured
-# Error Dispatcher valve
-errorDispatcherValve.clientAbort=Remote Client Aborted Request, IOException: {0}
-
# Error report valve
errorReportValve.errorReport=Error report
errorReportValve.statusHeader=HTTP Status {0} - {1}
1.5 +0 -22 jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/valves/mbeans-descriptors.xml
Index: mbeans-descriptors.xml
===================================================================
RCS file: /home/cvs/jakarta-tomcat-catalina/catalina/src/share/org/apache/catalina/valves/mbeans-descriptors.xml,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -r1.4 -r1.5
--- mbeans-descriptors.xml 11 Jun 2003 03:10:01 -0000 1.4
+++ mbeans-descriptors.xml 19 Jul 2003 14:30:07 -0000 1.5
@@ -76,28 +76,6 @@
</mbean>
- <mbean name="ErrorDispatcherValve"
- description="Implementation of a Valve that handles the error
- dispatch"
- domain="Catalina"
- group="Valve"
- type="org.apache.catalina.valves.ErrorDispatcherValve">
-
- <attribute name="className"
- description="Fully qualified class name of the managed object"
- type="java.lang.String"
- writeable="false"/>
-
- <attribute name="containerName"
- description="Object name of the container"
- type="javax.management.ObjectName"/>
-
- <attribute name="debug"
- description="The debugging detail level for this component"
- type="int"/>
-
- </mbean>
-
<mbean name="ExtendedAccessLogValve"
description="Valve that generates a web server access log"
domain="Catalina"
---------------------------------------------------------------------
To unsubscribe, e-mail: tomcat-dev-unsubscribe@jakarta.apache.org
For additional commands, e-mail: tomcat-dev-help@jakarta.apache.org