View Javadoc

1   // ========================================================================
2   // Copyright (c) 1999-2009 Mort Bay Consulting Pty. Ltd.
3   // ------------------------------------------------------------------------
4   // All rights reserved. This program and the accompanying materials
5   // are made available under the terms of the Eclipse Public License v1.0
6   // and Apache License v2.0 which accompanies this distribution.
7   // The Eclipse Public License is available at 
8   // http://www.eclipse.org/legal/epl-v10.html
9   // The Apache License v2.0 is available at
10  // http://www.opensource.org/licenses/apache2.0.php
11  // You may elect to redistribute this code under either of these licenses. 
12  // ========================================================================
13  package org.eclipse.jetty.server.handler;
14  import java.io.IOException;
15  import java.io.PrintWriter;
16  import java.io.StringWriter;
17  import java.io.Writer;
18  
19  import javax.servlet.http.HttpServletRequest;
20  import javax.servlet.http.HttpServletResponse;
21  
22  import org.eclipse.jetty.http.HttpHeaders;
23  import org.eclipse.jetty.http.HttpMethods;
24  import org.eclipse.jetty.http.HttpStatus;
25  import org.eclipse.jetty.http.MimeTypes;
26  import org.eclipse.jetty.http.HttpStatus.Code;
27  import org.eclipse.jetty.server.HttpConnection;
28  import org.eclipse.jetty.server.Request;
29  import org.eclipse.jetty.util.ByteArrayISO8859Writer;
30  import org.eclipse.jetty.util.StringUtil;
31  
32  
33  /* ------------------------------------------------------------ */
34  /** Handler for Error pages
35   * A handler that is registered at the org.eclipse.http.ErrorHandler
36   * context attributed and called by the HttpResponse.sendError method to write a
37   * error page.
38   * 
39   * 
40   */
41  public class ErrorHandler extends AbstractHandler
42  {
43      boolean _showStacks=true;
44      
45      /* ------------------------------------------------------------ */
46      /* 
47       * @see org.eclipse.jetty.server.server.Handler#handle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, int)
48       */
49      public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException
50      {
51          HttpConnection connection = HttpConnection.getCurrentConnection();
52          connection.getRequest().setHandled(true);
53          String method = request.getMethod();
54          if(!method.equals(HttpMethods.GET) && !method.equals(HttpMethods.POST) && !method.equals(HttpMethods.HEAD))
55              return;
56          response.setContentType(MimeTypes.TEXT_HTML_8859_1);        
57          response.setHeader(HttpHeaders.CACHE_CONTROL, "must-revalidate,no-cache,no-store");
58          ByteArrayISO8859Writer writer= new ByteArrayISO8859Writer(4096);
59          handleErrorPage(request, writer, connection.getResponse().getStatus(), connection.getResponse().getReason());
60          writer.flush();
61          response.setContentLength(writer.size());
62          writer.writeTo(response.getOutputStream());
63          writer.destroy();
64      }
65  
66      /* ------------------------------------------------------------ */
67      protected void handleErrorPage(HttpServletRequest request, Writer writer, int code, String message)
68          throws IOException
69      {
70          writeErrorPage(request, writer, code, message, _showStacks);
71      }
72      
73      /* ------------------------------------------------------------ */
74      protected void writeErrorPage(HttpServletRequest request, Writer writer, int code, String message, boolean showStacks)
75          throws IOException
76      {
77          if (message == null)
78              message=HttpStatus.getMessage(code);
79  
80          writer.write("<html>\n<head>\n");
81          writeErrorPageHead(request,writer,code,message);
82          writer.write("</head>\n<body>");
83          writeErrorPageBody(request,writer,code,message,showStacks);
84          writer.write("\n</body>\n</html>\n");
85      }
86  
87      /* ------------------------------------------------------------ */
88      protected void writeErrorPageHead(HttpServletRequest request, Writer writer, int code, String message)
89          throws IOException
90      {
91          writer.write("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=ISO-8859-1\"/>\n");
92          writer.write("<title>Error ");
93          writer.write(Integer.toString(code));
94          writer.write(' ');
95          if (message!=null)
96              writer.write(deScript(message));
97          writer.write("</title>\n");    
98      }
99  
100     /* ------------------------------------------------------------ */
101     protected void writeErrorPageBody(HttpServletRequest request, Writer writer, int code, String message, boolean showStacks)
102         throws IOException
103     {
104         String uri= request.getRequestURI();
105         
106         writeErrorPageMessage(request,writer,code,message,uri);
107         if (showStacks)
108             writeErrorPageStacks(request,writer);
109         writer.write("<hr /><i><small>Powered by Jetty://</small></i>");
110         for (int i= 0; i < 20; i++)
111             writer.write("<br/>                                                \n");
112     }
113 
114     /* ------------------------------------------------------------ */
115     protected void writeErrorPageMessage(HttpServletRequest request, Writer writer, int code, String message,String uri)
116     throws IOException
117     {
118         writer.write("<h2>HTTP ERROR ");
119         writer.write(Integer.toString(code));
120         writer.write("</h2>\n<p>Problem accessing ");
121         writer.write(deScript(uri));
122         writer.write(". Reason:\n<pre>    ");
123         writer.write(deScript(message));
124         writer.write("</pre></p>");
125     }
126 
127     /* ------------------------------------------------------------ */
128     protected void writeErrorPageStacks(HttpServletRequest request, Writer writer)
129         throws IOException
130     {
131         Throwable th = (Throwable)request.getAttribute("javax.servlet.error.exception");
132         while(th!=null)
133         {
134             writer.write("<h3>Caused by:</h3><pre>");
135             StringWriter sw = new StringWriter();
136             PrintWriter pw = new PrintWriter(sw);
137             th.printStackTrace(pw);
138             pw.flush();
139             writer.write(deScript(sw.getBuffer().toString()));
140             writer.write("</pre>\n");
141 
142             th =th.getCause();
143         }
144     }
145         
146 
147     /* ------------------------------------------------------------ */
148     /**
149      * @return True if stack traces are shown in the error pages
150      */
151     public boolean isShowStacks()
152     {
153         return _showStacks;
154     }
155 
156     /* ------------------------------------------------------------ */
157     /**
158      * @param showStacks True if stack traces are shown in the error pages
159      */
160     public void setShowStacks(boolean showStacks)
161     {
162         _showStacks = showStacks;
163     }
164 
165     /* ------------------------------------------------------------ */
166     protected String deScript(String string)
167     {
168         if (string==null)
169             return null;
170         string=StringUtil.replace(string, "&", "&amp;");
171         string=StringUtil.replace(string, "<", "&lt;");
172         string=StringUtil.replace(string, ">", "&gt;");
173         return string;
174     }
175 }