/** * Return the set of defined error pages for all specified error codes * and exception types. */ @Override public ErrorPage[] findErrorPages() { synchronized(exceptionPages) { synchronized(statusPages) { ErrorPage results1[] = new ErrorPage[exceptionPages.size()]; results1 = exceptionPages.values().toArray(results1); ErrorPage results2[] = new ErrorPage[statusPages.size()]; results2 = statusPages.values().toArray(results2); ErrorPage results[] = new ErrorPage[results1.length + results2.length]; for (int i = 0; i < results1.length; i++) results[i] = results1[i]; for (int i = results1.length; i < results.length; i++) results[i] = results2[i - results1.length]; return (results); } } }
/** * Remove the error page for the specified error code or * Java language exception, if it exists; otherwise, no action is taken. * * @param errorPage The error page definition to be removed */ @Override public void removeErrorPage(ErrorPage errorPage) { String exceptionType = errorPage.getExceptionType(); if (exceptionType != null) { synchronized (exceptionPages) { exceptionPages.remove(exceptionType); } } else { synchronized (statusPages) { if (errorPage.getErrorCode() == 200) { this.okErrorPage = null; } statusPages.remove(Integer.valueOf(errorPage.getErrorCode())); } } fireContainerEvent("removeErrorPage", errorPage); }
/** * 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 */ private static ErrorPage findErrorPage (Context context, Throwable exception) { if (exception == null) return (null); Class<?> clazz = exception.getClass(); String name = clazz.getName(); while (!Object.class.equals(clazz)) { ErrorPage errorPage = context.findErrorPage(name); if (errorPage != null) return (errorPage); clazz = clazz.getSuperclass(); if (clazz == null) break; name = clazz.getName(); } return (null); }
@Test public void testTimeoutDispatchCustomErrorPage() throws Exception { Tomcat tomcat = getTomcatInstance(); Context context = tomcat.addContext("", null); tomcat.addServlet("", "timeout", Bug58751AsyncServlet.class.getName()) .setAsyncSupported(true); CustomErrorServlet customErrorServlet = new CustomErrorServlet(); Tomcat.addServlet(context, "customErrorServlet", customErrorServlet); context.addServletMapping("/timeout", "timeout"); context.addServletMapping("/error", "customErrorServlet"); ErrorPage errorPage = new ErrorPage(); errorPage.setLocation("/error"); context.addErrorPage(errorPage); tomcat.start(); ByteChunk responseBody = new ByteChunk(); int rc = getUrl("http://localhost:" + getPort() + "/timeout", responseBody, null); Assert.assertEquals(503, rc); Assert.assertEquals(CustomErrorServlet.ERROR_MESSAGE, responseBody.toString()); }
/** * Return the set of defined error pages for all specified error codes * and exception types. */ public ErrorPage[] findErrorPages() { synchronized(exceptionPages) { synchronized(statusPages) { ErrorPage results1[] = new ErrorPage[exceptionPages.size()]; results1 = (ErrorPage[]) exceptionPages.values().toArray(results1); ErrorPage results2[] = new ErrorPage[statusPages.size()]; results2 = (ErrorPage[]) statusPages.values().toArray(results2); ErrorPage results[] = new ErrorPage[results1.length + results2.length]; for (int i = 0; i < results1.length; i++) results[i] = results1[i]; for (int i = results1.length; i < results.length; i++) results[i] = results2[i - results1.length]; return (results); } } }
/** * Remove the error page for the specified error code or * Java language exception, if it exists; otherwise, no action is taken. * * @param errorPage The error page definition to be removed */ public void removeErrorPage(ErrorPage errorPage) { String exceptionType = errorPage.getExceptionType(); if (exceptionType != null) { synchronized (exceptionPages) { exceptionPages.remove(exceptionType); } } else { synchronized (statusPages) { if (errorPage.getErrorCode() == 200) { this.okErrorPage = null; } statusPages.remove(new Integer(errorPage.getErrorCode())); } } fireContainerEvent("removeErrorPage", errorPage); }
/** * 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 (!Object.class.equals(clazz)) { ErrorPage errorPage = context.findErrorPage(name); if (errorPage != null) return (errorPage); clazz = clazz.getSuperclass(); if (clazz == null) break; name = clazz.getName(); } return (null); }
/** * 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); }
/** * Remove the error page for the specified error code or * Java language exception, if it exists; otherwise, no action is taken. * * @param errorPage The error page definition to be removed */ public void removeErrorPage(ErrorPage errorPage) { String exceptionType = errorPage.getExceptionType(); if (exceptionType != null) { synchronized (exceptionPages) { exceptionPages.remove(exceptionType); } } else { synchronized (statusPages) { statusPages.remove(new Integer(errorPage.getErrorCode())); } } fireContainerEvent("removeErrorPage", errorPage); }
/** * 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 */ private static ErrorPage findErrorPage(Context context, Throwable exception) { if (exception == null) return (null); Class<?> clazz = exception.getClass(); String name = clazz.getName(); while (!Object.class.equals(clazz)) { ErrorPage errorPage = context.findErrorPage(name); if (errorPage != null) return (errorPage); clazz = clazz.getSuperclass(); if (clazz == null) break; name = clazz.getName(); } return (null); }
/** * Return the set of defined error pages for all specified error codes and * exception types. */ @Override public ErrorPage[] findErrorPages() { synchronized (exceptionPages) { synchronized (statusPages) { ErrorPage results1[] = new ErrorPage[exceptionPages.size()]; results1 = exceptionPages.values().toArray(results1); ErrorPage results2[] = new ErrorPage[statusPages.size()]; results2 = statusPages.values().toArray(results2); ErrorPage results[] = new ErrorPage[results1.length + results2.length]; for (int i = 0; i < results1.length; i++) results[i] = results1[i]; for (int i = results1.length; i < results.length; i++) results[i] = results2[i - results1.length]; return (results); } } }
/** * Remove the error page for the specified error code or Java language * exception, if it exists; otherwise, no action is taken. * * @param errorPage * The error page definition to be removed */ @Override public void removeErrorPage(ErrorPage errorPage) { String exceptionType = errorPage.getExceptionType(); if (exceptionType != null) { synchronized (exceptionPages) { exceptionPages.remove(exceptionType); } } else { synchronized (statusPages) { if (errorPage.getErrorCode() == 200) { this.okErrorPage = null; } statusPages.remove(Integer.valueOf(errorPage.getErrorCode())); } } fireContainerEvent("removeErrorPage", errorPage); }
/** * Add an error page for the specified error or Java exception. * * @param errorPage The error page definition to be added */ @Override public void addErrorPage(ErrorPage errorPage) { // Validate the input parameters if (errorPage == null) throw new IllegalArgumentException (sm.getString("standardContext.errorPage.required")); String location = errorPage.getLocation(); if ((location != null) && !location.startsWith("/")) { if (isServlet22()) { if(log.isDebugEnabled()) log.debug(sm.getString("standardContext.errorPage.warning", location)); errorPage.setLocation("/" + location); } else { throw new IllegalArgumentException (sm.getString("standardContext.errorPage.error", location)); } } // Add the specified error page to our internal collections String exceptionType = errorPage.getExceptionType(); if (exceptionType != null) { synchronized (exceptionPages) { exceptionPages.put(exceptionType, errorPage); } } else { synchronized (statusPages) { if (errorPage.getErrorCode() == 200) { this.okErrorPage = errorPage; } statusPages.put(Integer.valueOf(errorPage.getErrorCode()), errorPage); } } fireContainerEvent("addErrorPage", errorPage); }
/** * Return the error page entry for the specified HTTP error code, * if any; otherwise return <code>null</code>. * * @param errorCode Error code to look up */ @Override public ErrorPage findErrorPage(int errorCode) { if (errorCode == 200) { return (okErrorPage); } else { return (statusPages.get(Integer.valueOf(errorCode))); } }
/** * Return the error page entry for the specified Java exception type, * if any; otherwise return <code>null</code>. * * @param exceptionType Exception type to look up */ @Override public ErrorPage findErrorPage(String exceptionType) { synchronized (exceptionPages) { return (exceptionPages.get(exceptionType)); } }
/** * Return the context-relative URI of the error page for the specified * HTTP status code, if any; otherwise return <code>null</code>. * * @param status HTTP status code to look up */ @Override public String findStatusPage(int status) { ErrorPage errorPage = statusPages.get(Integer.valueOf(status)); if (errorPage!=null) { return errorPage.getLocation(); } return null; }
@Test public void testErrorPageHandling() throws Exception { // Set up a container Tomcat tomcat = getTomcatInstance(); // No file system docBase required Context ctx = tomcat.addContext("", null); // Add the error page Tomcat.addServlet(ctx, "error", new ErrorServlet()); ctx.addServletMapping("/error", "error"); // Add the error handling page Tomcat.addServlet(ctx, "report", new ReportServlet()); ctx.addServletMapping("/report/*", "report"); // And the handling for 500 responses ErrorPage errorPage500 = new ErrorPage(); errorPage500.setErrorCode(Response.SC_INTERNAL_SERVER_ERROR); errorPage500.setLocation("/report/500"); ctx.addErrorPage(errorPage500); // And the default error handling ErrorPage errorPageDefault = new ErrorPage(); errorPageDefault.setLocation("/report/default"); ctx.addErrorPage(errorPageDefault); tomcat.start(); doTestErrorPageHandling(500, "/500"); doTestErrorPageHandling(501, "/default"); }
@Test(expected=IllegalArgumentException.class) public void testInvalidErrorPage() throws Exception { // Set up a container Tomcat tomcat = getTomcatInstance(); // No file system docBase required Context ctx = tomcat.addContext("", null); // Add a broken error page configuration ErrorPage errorPage500 = new ErrorPage(); errorPage500.setErrorCode("java.lang.Exception"); errorPage500.setLocation("/report/500"); ctx.addErrorPage(errorPage500); }
/** * Add an error page for the specified error or Java exception. * * @param errorPage The error page definition to be added */ public void addErrorPage(ErrorPage errorPage) { // Validate the input parameters if (errorPage == null) throw new IllegalArgumentException (sm.getString("standardContext.errorPage.required")); String location = errorPage.getLocation(); if ((location != null) && !location.startsWith("/")) { if (isServlet22()) { if(log.isDebugEnabled()) log.debug(sm.getString("standardContext.errorPage.warning", location)); errorPage.setLocation("/" + location); } else { throw new IllegalArgumentException (sm.getString("standardContext.errorPage.error", location)); } } // Add the specified error page to our internal collections String exceptionType = errorPage.getExceptionType(); if (exceptionType != null) { synchronized (exceptionPages) { exceptionPages.put(exceptionType, errorPage); } } else { synchronized (statusPages) { if (errorPage.getErrorCode() == 200) { this.okErrorPage = errorPage; } statusPages.put(new Integer(errorPage.getErrorCode()), errorPage); } } fireContainerEvent("addErrorPage", errorPage); }
/** * Return the error page entry for the specified HTTP error code, * if any; otherwise return <code>null</code>. * * @param errorCode Error code to look up */ public ErrorPage findErrorPage(int errorCode) { if (errorCode == 200) { return (okErrorPage); } else { return ((ErrorPage) statusPages.get(new Integer(errorCode))); } }
/** * Return the error page entry for the specified Java exception type, * if any; otherwise return <code>null</code>. * * @param exceptionType Exception type to look up */ public ErrorPage findErrorPage(String exceptionType) { synchronized (exceptionPages) { return ((ErrorPage) exceptionPages.get(exceptionType)); } }
/** * 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 (container.getLogger().isDebugEnabled()) container.getLogger().debug("Processing " + errorPage); request.setPathInfo(errorPage.getLocation()); try { // Reset the response (keeping the real error code and message) response.resetBuffer(true); // Forward control to the specified location ServletContext servletContext = request.getContext().getServletContext(); RequestDispatcher rd = servletContext.getRequestDispatcher(errorPage.getLocation()); rd.forward(request.getRequest(), response.getResponse()); // 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 container.getLogger().error("Exception Processing " + errorPage, t); return (false); } }
/** * 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(); try { // Reset the response if possible (else IllegalStateException) hres.reset(); // 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); } }
/** * Add an error page for the specified error or Java exception. * * @param errorPage The error page definition to be added */ public void addErrorPage(ErrorPage errorPage) { // Validate the input parameters if (errorPage == null) throw new IllegalArgumentException (sm.getString("standardContext.errorPage.required")); String location = errorPage.getLocation(); if ((location != null) && !location.startsWith("/")) { if (isServlet22()) { log(sm.getString("standardContext.errorPage.warning", location)); errorPage.setLocation("/" + location); } else { throw new IllegalArgumentException (sm.getString("standardContext.errorPage.error", location)); } } // Add the specified error page to our internal collections String exceptionType = errorPage.getExceptionType(); if (exceptionType != null) { synchronized (exceptionPages) { exceptionPages.put(exceptionType, errorPage); } } else { synchronized (statusPages) { statusPages.put(new Integer(errorPage.getErrorCode()), errorPage); } } fireContainerEvent("addErrorPage", errorPage); }
/** * Add an error page for the specified error or Java exception. * * @param errorPage * The error page definition to be added */ @Override public void addErrorPage(ErrorPage errorPage) { // Validate the input parameters if (errorPage == null) throw new IllegalArgumentException(sm.getString("standardContext.errorPage.required")); String location = errorPage.getLocation(); if ((location != null) && !location.startsWith("/")) { if (isServlet22()) { if (log.isDebugEnabled()) log.debug(sm.getString("standardContext.errorPage.warning", location)); errorPage.setLocation("/" + location); } else { throw new IllegalArgumentException(sm.getString("standardContext.errorPage.error", location)); } } // Add the specified error page to our internal collections String exceptionType = errorPage.getExceptionType(); if (exceptionType != null) { synchronized (exceptionPages) { exceptionPages.put(exceptionType, errorPage); } } else { synchronized (statusPages) { if (errorPage.getErrorCode() == 200) { this.okErrorPage = errorPage; } statusPages.put(Integer.valueOf(errorPage.getErrorCode()), errorPage); } } fireContainerEvent("addErrorPage", errorPage); }
/** * Return the error page entry for the specified HTTP error code, if any; * otherwise return <code>null</code>. * * @param errorCode * Error code to look up */ @Override public ErrorPage findErrorPage(int errorCode) { if (errorCode == 200) { return (okErrorPage); } else { return (statusPages.get(Integer.valueOf(errorCode))); } }
/** * Return the error page entry for the specified Java exception type, if * any; otherwise return <code>null</code>. * * @param exceptionType * Exception type to look up */ @Override public ErrorPage findErrorPage(String exceptionType) { synchronized (exceptionPages) { return (exceptionPages.get(exceptionType)); } }
/** * Return the context-relative URI of the error page for the specified HTTP * status code, if any; otherwise return <code>null</code>. * * @param status * HTTP status code to look up */ @Override public String findStatusPage(int status) { ErrorPage errorPage = statusPages.get(Integer.valueOf(status)); if (errorPage != null) { return errorPage.getLocation(); } return null; }