]> WPIA git - gigi.git/blob - lib/jetty/org/eclipse/jetty/servlet/ErrorPageErrorHandler.java
Merge "Update notes about password security"
[gigi.git] / lib / jetty / org / eclipse / jetty / servlet / ErrorPageErrorHandler.java
1 //
2 //  ========================================================================
3 //  Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
4 //  ------------------------------------------------------------------------
5 //  All rights reserved. This program and the accompanying materials
6 //  are made available under the terms of the Eclipse Public License v1.0
7 //  and Apache License v2.0 which accompanies this distribution.
8 //
9 //      The Eclipse Public License is available at
10 //      http://www.eclipse.org/legal/epl-v10.html
11 //
12 //      The Apache License v2.0 is available at
13 //      http://www.opensource.org/licenses/apache2.0.php
14 //
15 //  You may elect to redistribute this code under either of these licenses.
16 //  ========================================================================
17 //
18
19 package org.eclipse.jetty.servlet;
20
21 import java.util.ArrayList;
22 import java.util.HashMap;
23 import java.util.List;
24 import java.util.Map;
25
26 import javax.servlet.ServletContext;
27 import javax.servlet.ServletException;
28 import javax.servlet.http.HttpServletRequest;
29
30 import org.eclipse.jetty.server.Dispatcher;
31 import org.eclipse.jetty.server.handler.ContextHandler;
32 import org.eclipse.jetty.server.handler.ErrorHandler;
33
34 /* ------------------------------------------------------------ */
35 /** Error Page Error Handler
36  *
37  * An ErrorHandler that maps exceptions and status codes to URIs for dispatch using
38  * the internal ERROR style of dispatch.
39  *
40  */
41 public class ErrorPageErrorHandler extends ErrorHandler implements ErrorHandler.ErrorPageMapper
42 {
43     public final static String GLOBAL_ERROR_PAGE = "org.eclipse.jetty.server.error_page.global";
44
45     protected ServletContext _servletContext;
46     private final Map<String,String> _errorPages= new HashMap<String,String>(); // code or exception to URL
47     private final List<ErrorCodeRange> _errorPageList=new ArrayList<ErrorCodeRange>(); // list of ErrorCode by range
48
49     /* ------------------------------------------------------------ */
50     public ErrorPageErrorHandler()
51     {}
52
53     /* ------------------------------------------------------------ */
54     @Override
55     public String getErrorPage(HttpServletRequest request)
56     {
57         String error_page= null;
58
59         Throwable th= (Throwable)request.getAttribute(Dispatcher.ERROR_EXCEPTION);
60
61         // Walk the cause hierarchy
62         while (error_page == null && th != null )
63         {
64             Class<?> exClass=th.getClass();
65             error_page= (String)_errorPages.get(exClass.getName());
66
67             // walk the inheritance hierarchy
68             while (error_page == null)
69             {
70                 exClass= exClass.getSuperclass();
71                 if (exClass==null)
72                     break;
73                 error_page= (String)_errorPages.get(exClass.getName());
74             }
75
76             th=(th instanceof ServletException)?((ServletException)th).getRootCause():null;
77         }
78
79         if (error_page == null)
80         {
81             // look for an exact code match
82             Integer code=(Integer)request.getAttribute(Dispatcher.ERROR_STATUS_CODE);
83             if (code!=null)
84             {
85                 error_page= (String)_errorPages.get(Integer.toString(code));
86
87                 // if still not found
88                 if ((error_page == null) && (_errorPageList != null))
89                 {
90                     // look for an error code range match.
91                     for (int i = 0; i < _errorPageList.size(); i++)
92                     {
93                         ErrorCodeRange errCode = (ErrorCodeRange) _errorPageList.get(i);
94                         if (errCode.isInRange(code))
95                         {
96                             error_page = errCode.getUri();
97                             break;
98                         }
99                     }
100                 }
101             }
102         }
103
104         //try servlet 3.x global error page
105         if (error_page == null)
106             error_page = _errorPages.get(GLOBAL_ERROR_PAGE);
107         
108         return error_page;
109     }
110
111
112     /* ------------------------------------------------------------ */
113     /**
114      * @return Returns the errorPages.
115      */
116     public Map<String,String> getErrorPages()
117     {
118         return _errorPages;
119     }
120
121     /* ------------------------------------------------------------ */
122     /**
123      * @param errorPages The errorPages to set. A map of Exception class name  or error code as a string to URI string
124      */
125     public void setErrorPages(Map<String,String> errorPages)
126     {
127         _errorPages.clear();
128         if (errorPages!=null)
129             _errorPages.putAll(errorPages);
130     }
131
132     /* ------------------------------------------------------------ */
133     /** Add Error Page mapping for an exception class
134      * This method is called as a result of an exception-type element in a web.xml file
135      * or may be called directly
136      * @param exception The exception
137      * @param uri The URI of the error page.
138      */
139     public void addErrorPage(Class<? extends Throwable> exception,String uri)
140     {
141         _errorPages.put(exception.getName(),uri);
142     }
143
144     /* ------------------------------------------------------------ */
145     /** Add Error Page mapping for an exception class
146      * This method is called as a result of an exception-type element in a web.xml file
147      * or may be called directly
148      * @param exceptionClassName The exception
149      * @param uri The URI of the error page.
150      */
151     public void addErrorPage(String exceptionClassName,String uri)
152     {
153         _errorPages.put(exceptionClassName,uri);
154     }
155
156     /* ------------------------------------------------------------ */
157     /** Add Error Page mapping for a status code.
158      * This method is called as a result of an error-code element in a web.xml file
159      * or may be called directly
160      * @param code The HTTP status code to match
161      * @param uri The URI of the error page.
162      */
163     public void addErrorPage(int code,String uri)
164     {
165         _errorPages.put(Integer.toString(code),uri);
166     }
167
168     /* ------------------------------------------------------------ */
169     /** Add Error Page mapping for a status code range.
170      * This method is not available from web.xml and must be called
171      * directly.
172      * @param from The lowest matching status code
173      * @param to The highest matching status code
174      * @param uri The URI of the error page.
175      */
176     public void addErrorPage(int from, int to, String uri)
177     {
178         _errorPageList.add(new ErrorCodeRange(from, to, uri));
179     }
180
181     /* ------------------------------------------------------------ */
182     @Override
183     protected void doStart() throws Exception
184     {
185         super.doStart();
186         _servletContext=ContextHandler.getCurrentContext();
187     }
188
189     /* ------------------------------------------------------------ */
190     /* ------------------------------------------------------------ */
191     private class ErrorCodeRange
192     {
193         private int _from;
194         private int _to;
195         private String _uri;
196
197         ErrorCodeRange(int from, int to, String uri)
198             throws IllegalArgumentException
199         {
200             if (from > to)
201                 throw new IllegalArgumentException("from>to");
202
203             _from = from;
204             _to = to;
205             _uri = uri;
206         }
207
208         boolean isInRange(int value)
209         {
210             if ((value >= _from) && (value <= _to))
211             {
212                 return true;
213             }
214
215             return false;
216         }
217
218         String getUri()
219         {
220             return _uri;
221         }
222
223         @Override
224         public String toString()
225         {
226             return "from: " + _from + ",to: " + _to + ",uri: " + _uri;
227         }
228     }
229 }