View Javadoc

1   // ========================================================================
2   // Copyright 1999-2005 Mort Bay Consulting Pty. Ltd.
3   // ------------------------------------------------------------------------
4   // Licensed under the Apache License, Version 2.0 (the "License");
5   // you may not use this file except in compliance with the License.
6   // You may obtain a copy of the License at 
7   // http://www.apache.org/licenses/LICENSE-2.0
8   // Unless required by applicable law or agreed to in writing, software
9   // distributed under the License is distributed on an "AS IS" BASIS,
10  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11  // See the License for the specific language governing permissions and
12  // limitations under the License.
13  // ========================================================================
14  package org.mortbay.jetty.handler;
15  import java.io.IOException;
16  import java.io.PrintWriter;
17  import java.io.StringWriter;
18  import java.io.Writer;
19  
20  import javax.servlet.http.HttpServletRequest;
21  import javax.servlet.http.HttpServletResponse;
22  
23  import org.mortbay.jetty.HttpConnection;
24  import org.mortbay.jetty.HttpGenerator;
25  import org.mortbay.jetty.HttpHeaders;
26  import org.mortbay.jetty.HttpMethods;
27  import org.mortbay.jetty.MimeTypes;
28  import org.mortbay.util.ByteArrayISO8859Writer;
29  import org.mortbay.util.StringUtil;
30  
31  
32  /* ------------------------------------------------------------ */
33  /** Handler for Error pages
34   * A handler that is registered at the org.mortbay.http.ErrorHandler
35   * context attributed and called by the HttpResponse.sendError method to write a
36   * error page.
37   * 
38   * @author Greg Wilkins (gregw)
39   */
40  public class ErrorHandler extends AbstractHandler
41  {
42      boolean _showStacks=true;
43      
44      /* ------------------------------------------------------------ */
45      /* 
46       * @see org.mortbay.jetty.Handler#handle(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, int)
47       */
48      public void handle(String target, HttpServletRequest request, HttpServletResponse response, int dispatch) throws IOException
49      {
50          HttpConnection connection = HttpConnection.getCurrentConnection();
51          connection.getRequest().setHandled(true);
52          String method = request.getMethod();
53          if(!method.equals(HttpMethods.GET) && !method.equals(HttpMethods.POST) && !method.equals(HttpMethods.HEAD))
54              return;
55          response.setContentType(MimeTypes.TEXT_HTML_8859_1);        
56          response.setHeader(HttpHeaders.CACHE_CONTROL, "must-revalidate,no-cache,no-store");
57          ByteArrayISO8859Writer writer= new ByteArrayISO8859Writer(4096);
58          handleErrorPage(request, writer, connection.getResponse().getStatus(), connection.getResponse().getReason());
59          writer.flush();
60          response.setContentLength(writer.size());
61          writer.writeTo(response.getOutputStream());
62          writer.destroy();
63      }
64  
65      /* ------------------------------------------------------------ */
66      protected void handleErrorPage(HttpServletRequest request, Writer writer, int code, String message)
67          throws IOException
68      {
69          writeErrorPage(request, writer, code, message, _showStacks);
70      }
71      
72      /* ------------------------------------------------------------ */
73      protected void writeErrorPage(HttpServletRequest request, Writer writer, int code, String message, boolean showStacks)
74          throws IOException
75      {
76          if (message == null)
77              message=HttpGenerator.getReason(code);
78  
79          writer.write("<html>\n<head>\n");
80          writeErrorPageHead(request,writer,code,message);
81          writer.write("</head>\n<body>");
82          writeErrorPageBody(request,writer,code,message,showStacks);
83          writer.write("\n</body>\n</html>\n");
84      }
85  
86      /* ------------------------------------------------------------ */
87      protected void writeErrorPageHead(HttpServletRequest request, Writer writer, int code, String message)
88          throws IOException
89      {
90          writer.write("<meta http-equiv=\"Content-Type\" content=\"text/html; charset=ISO-8859-1\"/>\n");
91          writer.write("<title>Error ");
92          writer.write(Integer.toString(code));
93          writer.write(' ');
94          write(writer,message);
95          writer.write("</title>\n");    
96      }
97  
98      /* ------------------------------------------------------------ */
99      protected void writeErrorPageBody(HttpServletRequest request, Writer writer, int code, String message, boolean showStacks)
100         throws IOException
101     {
102         String uri= request.getRequestURI();
103         
104         writeErrorPageMessage(request,writer,code,message,uri);
105         if (showStacks)
106             writeErrorPageStacks(request,writer);
107         writer.write("<hr /><i><small>Powered by Jetty://</small></i>");
108         for (int i= 0; i < 20; i++)
109             writer.write("<br/>                                                \n");
110     }
111 
112     /* ------------------------------------------------------------ */
113     protected void writeErrorPageMessage(HttpServletRequest request, Writer writer, int code, String message,String uri)
114     throws IOException
115     {
116         writer.write("<h2>HTTP ERROR ");
117         writer.write(Integer.toString(code));
118         writer.write("</h2>\n<p>Problem accessing ");
119         write(writer,uri);
120         writer.write(". Reason:\n<pre>    ");
121         write(writer,message);
122         writer.write("</pre></p>");
123     }
124 
125     /* ------------------------------------------------------------ */
126     protected void writeErrorPageStacks(HttpServletRequest request, Writer writer)
127         throws IOException
128     {
129         Throwable th = (Throwable)request.getAttribute("javax.servlet.error.exception");
130         while(th!=null)
131         {
132             writer.write("<h3>Caused by:</h3><pre>");
133             StringWriter sw = new StringWriter();
134             PrintWriter pw = new PrintWriter(sw);
135             th.printStackTrace(pw);
136             pw.flush();
137             write(writer,sw.getBuffer().toString());
138             writer.write("</pre>\n");
139 
140             th =th.getCause();
141         }
142     }
143         
144 
145     /* ------------------------------------------------------------ */
146     /**
147      * @return True if stack traces are shown in the error pages
148      */
149     public boolean isShowStacks()
150     {
151         return _showStacks;
152     }
153 
154     /* ------------------------------------------------------------ */
155     /**
156      * @param showStacks True if stack traces are shown in the error pages
157      */
158     public void setShowStacks(boolean showStacks)
159     {
160         _showStacks = showStacks;
161     }
162 
163     /* ------------------------------------------------------------ */
164     protected void write(Writer writer,String string)
165         throws IOException
166     {
167         if (string==null)
168             return;
169         
170         for (int i=0;i<string.length();i++)
171         {
172             char c=string.charAt(i);
173             
174             switch(c)
175             {
176                 case '&' :
177                     writer.write("&amp;");
178                     break;
179                 case '<' :
180                     writer.write("&lt;");
181                     break;
182                 case '>' :
183                     writer.write("&gt;");
184                     break;
185                     
186                 default:
187                     if (Character.isISOControl(c) && !Character.isWhitespace(c))
188                         writer.write('?');
189                     else 
190                         writer.write(c);
191             }          
192         }
193     }
194 }