001: // ========================================================================
002: // Copyright 1999-2005 Mort Bay Consulting Pty. Ltd.
003: // ------------------------------------------------------------------------
004: // Licensed under the Apache License, Version 2.0 (the "License");
005: // you may not use this file except in compliance with the License.
006: // You may obtain a copy of the License at
007: // http://www.apache.org/licenses/LICENSE-2.0
008: // Unless required by applicable law or agreed to in writing, software
009: // distributed under the License is distributed on an "AS IS" BASIS,
010: // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
011: // See the License for the specific language governing permissions and
012: // limitations under the License.
013: // ========================================================================
014: package org.mortbay.jetty.handler;
015:
016: import java.io.IOException;
017: import java.io.PrintWriter;
018: import java.io.StringWriter;
019: import java.io.Writer;
020: import java.net.URLDecoder;
021:
022: import javax.servlet.http.HttpServletRequest;
023: import javax.servlet.http.HttpServletResponse;
024:
025: import org.mortbay.jetty.HttpConnection;
026: import org.mortbay.jetty.HttpGenerator;
027: import org.mortbay.jetty.MimeTypes;
028: import org.mortbay.util.ByteArrayISO8859Writer;
029: import org.mortbay.util.StringUtil;
030:
031: /* ------------------------------------------------------------ */
032: /** Handler for Error pages
033: * A handler that is registered at the org.mortbay.http.ErrorHandler
034: * context attributed and called by the HttpResponse.sendError method to write a
035: * error page.
036: *
037: * @author Greg Wilkins (gregw)
038: */
039: public class ErrorHandler extends AbstractHandler {
040: boolean _showStacks = true;
041:
042: /* ------------------------------------------------------------ */
043: /*
044: * @see org.mortbay.jetty.Handler#handle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, int)
045: */
046: public void handle(String target, HttpServletRequest request,
047: HttpServletResponse response, int dispatch)
048: throws IOException {
049: HttpConnection.getCurrentConnection().getRequest().setHandled(
050: true);
051: response.setContentType(MimeTypes.TEXT_HTML_8859_1);
052: ByteArrayISO8859Writer writer = new ByteArrayISO8859Writer(4096);
053: HttpConnection connection = HttpConnection
054: .getCurrentConnection();
055: handleErrorPage(request, writer, connection.getResponse()
056: .getStatus(), connection.getResponse().getReason());
057: writer.flush();
058: response.setContentLength(writer.size());
059: writer.writeTo(response.getOutputStream());
060: writer.destroy();
061: }
062:
063: /* ------------------------------------------------------------ */
064: protected void handleErrorPage(HttpServletRequest request,
065: Writer writer, int code, String message) throws IOException {
066: writeErrorPage(request, writer, code, message, _showStacks);
067: }
068:
069: /* ------------------------------------------------------------ */
070: protected void writeErrorPage(HttpServletRequest request,
071: Writer writer, int code, String message, boolean showStacks)
072: throws IOException {
073: if (message == null)
074: message = HttpGenerator.getReason(code);
075: else {
076: message = StringUtil.replace(message, "&", "&");
077: message = StringUtil.replace(message, "<", "<");
078: message = StringUtil.replace(message, ">", ">");
079: }
080:
081: writer.write("<html>\n<head>\n");
082: writeErrorPageHead(request, writer, code, message);
083: writer.write("</head>\n<body>");
084: writeErrorPageBody(request, writer, code, message, showStacks);
085: writer.write("\n</body>\n</html>\n");
086: }
087:
088: /* ------------------------------------------------------------ */
089: protected void writeErrorPageHead(HttpServletRequest request,
090: Writer writer, int code, String message) throws IOException {
091: writer
092: .write("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=ISO-8859-1\"/>\n");
093: writer.write("<title>Error ");
094: writer.write(Integer.toString(code));
095: writer.write(' ');
096: if (message == null)
097: writer.write(message);
098: writer.write("</title>\n");
099: }
100:
101: /* ------------------------------------------------------------ */
102: protected void writeErrorPageBody(HttpServletRequest request,
103: Writer writer, int code, String message, boolean showStacks)
104: throws IOException {
105: String uri = request.getRequestURI();
106: if (uri != null) {
107: uri = StringUtil.replace(uri, "&", "&");
108: uri = StringUtil.replace(uri, "<", "<");
109: uri = StringUtil.replace(uri, ">", ">");
110: }
111:
112: writeErrorPageMessage(request, writer, code, message, uri);
113: if (showStacks)
114: writeErrorPageStacks(request, writer);
115:
116: {
117: }
118:
119: writer
120: .write("<p><i><small><a href=\"http://jetty.mortbay.org/\">Powered by Jetty://</a></small></i></p>");
121: for (int i = 0; i < 20; i++)
122: writer
123: .write("<br/> \n");
124: }
125:
126: /* ------------------------------------------------------------ */
127: protected void writeErrorPageMessage(HttpServletRequest request,
128: Writer writer, int code, String message, String uri)
129: throws IOException {
130: writer.write("<h2>HTTP ERROR: ");
131: writer.write(Integer.toString(code));
132: writer.write("</h2><pre>");
133: writer.write(message);
134: writer.write("</pre>\n<p>RequestURI=");
135: writer.write(uri);
136: writer.write("</p>");
137: }
138:
139: /* ------------------------------------------------------------ */
140: protected void writeErrorPageStacks(HttpServletRequest request,
141: Writer writer) throws IOException {
142: Throwable th = (Throwable) request
143: .getAttribute("javax.servlet.error.exception");
144: while (th != null) {
145: writer.write("<h3>Caused by:</h3><pre>");
146: StringWriter sw = new StringWriter();
147: PrintWriter pw = new PrintWriter(sw);
148: th.printStackTrace(pw);
149: pw.flush();
150: writer.write(sw.getBuffer().toString());
151: writer.write("</pre>\n");
152:
153: th = th.getCause();
154: }
155: }
156:
157: /* ------------------------------------------------------------ */
158: /**
159: * @return True if stack traces are shown in the error pages
160: */
161: public boolean isShowStacks() {
162: return _showStacks;
163: }
164:
165: /* ------------------------------------------------------------ */
166: /**
167: * @param showStacks True if stack traces are shown in the error pages
168: */
169: public void setShowStacks(boolean showStacks) {
170: _showStacks = showStacks;
171: }
172:
173: }
|