KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > catalina > valves > RequestFilterValve


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17
18
19 package org.apache.catalina.valves;
20
21
22 import java.io.IOException JavaDoc;
23 import java.util.ArrayList JavaDoc;
24 import java.util.regex.Pattern JavaDoc;
25 import java.util.regex.PatternSyntaxException JavaDoc;
26
27 import javax.servlet.ServletException JavaDoc;
28 import javax.servlet.http.HttpServletResponse JavaDoc;
29
30 import org.apache.catalina.connector.Request;
31 import org.apache.catalina.connector.Response;
32 import org.apache.catalina.util.StringManager;
33
34 /**
35  * Implementation of a Valve that performs filtering based on comparing the
36  * appropriate request property (selected based on which subclass you choose
37  * to configure into your Container's pipeline) against a set of regular
38  * expressions configured for this Valve.
39  * <p>
40  * This valve is configured by setting the <code>allow</code> and/or
41  * <code>deny</code> properties to a comma-delimited list of regular
42  * expressions (in the syntax supported by the jakarta-regexp library) to
43  * which the appropriate request property will be compared. Evaluation
44  * proceeds as follows:
45  * <ul>
46  * <li>The subclass extracts the request property to be filtered, and
47  * calls the common <code>process()</code> method.
48  * <li>If there are any deny expressions configured, the property will
49  * be compared to each such expression. If a match is found, this
50  * request will be rejected with a "Forbidden" HTTP response.</li>
51  * <li>If there are any allow expressions configured, the property will
52  * be compared to each such expression. If a match is found, this
53  * request will be allowed to pass through to the next Valve in the
54  * current pipeline.</li>
55  * <li>If one or more deny expressions was specified but no allow expressions,
56  * allow this request to pass through (because none of the deny
57  * expressions matched it).
58  * <li>The request will be rejected with a "Forbidden" HTTP response.</li>
59  * </ul>
60  * <p>
61  * This Valve may be attached to any Container, depending on the granularity
62  * of the filtering you wish to perform.
63  *
64  * @author Craig R. McClanahan
65  * @version $Revision: 467222 $ $Date: 2006-10-24 05:17:11 +0200 (mar., 24 oct. 2006) $
66  */

67
68 public abstract class RequestFilterValve
69     extends ValveBase {
70
71
72     // ----------------------------------------------------- Class Variables
73

74
75     /**
76      * The descriptive information related to this implementation.
77      */

78     private static final String JavaDoc info =
79         "org.apache.catalina.valves.RequestFilterValve/1.0";
80
81
82     /**
83      * The StringManager for this package.
84      */

85     protected static StringManager sm =
86         StringManager.getManager(Constants.Package);
87
88
89     // ----------------------------------------------------- Instance Variables
90

91
92     /**
93      * The comma-delimited set of <code>allow</code> expressions.
94      */

95     protected String JavaDoc allow = null;
96
97
98     /**
99      * The set of <code>allow</code> regular expressions we will evaluate.
100      */

101     protected Pattern JavaDoc allows[] = new Pattern JavaDoc[0];
102
103
104     /**
105      * The set of <code>deny</code> regular expressions we will evaluate.
106      */

107     protected Pattern JavaDoc denies[] = new Pattern JavaDoc[0];
108
109
110     /**
111      * The comma-delimited set of <code>deny</code> expressions.
112      */

113     protected String JavaDoc deny = null;
114
115
116     // ------------------------------------------------------------- Properties
117

118
119     /**
120      * Return a comma-delimited set of the <code>allow</code> expressions
121      * configured for this Valve, if any; otherwise, return <code>null</code>.
122      */

123     public String JavaDoc getAllow() {
124
125         return (this.allow);
126
127     }
128
129
130     /**
131      * Set the comma-delimited set of the <code>allow</code> expressions
132      * configured for this Valve, if any.
133      *
134      * @param allow The new set of allow expressions
135      */

136     public void setAllow(String JavaDoc allow) {
137
138         this.allow = allow;
139         allows = precalculate(allow);
140
141     }
142
143
144     /**
145      * Return a comma-delimited set of the <code>deny</code> expressions
146      * configured for this Valve, if any; otherwise, return <code>null</code>.
147      */

148     public String JavaDoc getDeny() {
149
150         return (this.deny);
151
152     }
153
154
155     /**
156      * Set the comma-delimited set of the <code>deny</code> expressions
157      * configured for this Valve, if any.
158      *
159      * @param deny The new set of deny expressions
160      */

161     public void setDeny(String JavaDoc deny) {
162
163         this.deny = deny;
164         denies = precalculate(deny);
165
166     }
167
168
169     /**
170      * Return descriptive information about this Valve implementation.
171      */

172     public String JavaDoc getInfo() {
173
174         return (info);
175
176     }
177
178
179     // --------------------------------------------------------- Public Methods
180

181
182     /**
183      * Extract the desired request property, and pass it (along with the
184      * specified request and response objects) to the protected
185      * <code>process()</code> method to perform the actual filtering.
186      * This method must be implemented by a concrete subclass.
187      *
188      * @param request The servlet request to be processed
189      * @param response The servlet response to be created
190      *
191      * @exception IOException if an input/output error occurs
192      * @exception ServletException if a servlet error occurs
193      */

194     public abstract void invoke(Request request, Response JavaDoc response)
195         throws IOException JavaDoc, ServletException JavaDoc;
196
197
198     // ------------------------------------------------------ Protected Methods
199

200
201     /**
202      * Return an array of regular expression objects initialized from the
203      * specified argument, which must be <code>null</code> or a comma-delimited
204      * list of regular expression patterns.
205      *
206      * @param list The comma-separated list of patterns
207      *
208      * @exception IllegalArgumentException if one of the patterns has
209      * invalid syntax
210      */

211     protected Pattern JavaDoc[] precalculate(String JavaDoc list) {
212
213         if (list == null)
214             return (new Pattern JavaDoc[0]);
215         list = list.trim();
216         if (list.length() < 1)
217             return (new Pattern JavaDoc[0]);
218         list += ",";
219
220         ArrayList JavaDoc reList = new ArrayList JavaDoc();
221         while (list.length() > 0) {
222             int comma = list.indexOf(',');
223             if (comma < 0)
224                 break;
225             String JavaDoc pattern = list.substring(0, comma).trim();
226             try {
227                 reList.add(Pattern.compile(pattern));
228             } catch (PatternSyntaxException JavaDoc e) {
229                 IllegalArgumentException JavaDoc iae = new IllegalArgumentException JavaDoc
230                     (sm.getString("requestFilterValve.syntax", pattern));
231                 iae.initCause(e);
232                 throw iae;
233             }
234             list = list.substring(comma + 1);
235         }
236
237         Pattern JavaDoc reArray[] = new Pattern JavaDoc[reList.size()];
238         return ((Pattern JavaDoc[]) reList.toArray(reArray));
239
240     }
241
242
243     /**
244      * Perform the filtering that has been configured for this Valve, matching
245      * against the specified request property.
246      *
247      * @param property The request property on which to filter
248      * @param request The servlet request to be processed
249      * @param response The servlet response to be processed
250      *
251      * @exception IOException if an input/output error occurs
252      * @exception ServletException if a servlet error occurs
253      */

254     protected void process(String JavaDoc property,
255                            Request request, Response JavaDoc response)
256         throws IOException JavaDoc, ServletException JavaDoc {
257
258         // Check the deny patterns, if any
259
for (int i = 0; i < denies.length; i++) {
260             if (denies[i].matcher(property).matches()) {
261                 response.sendError(HttpServletResponse.SC_FORBIDDEN);
262                 return;
263             }
264         }
265
266         // Check the allow patterns, if any
267
for (int i = 0; i < allows.length; i++) {
268             if (allows[i].matcher(property).matches()) {
269                 getNext().invoke(request, response);
270                 return;
271             }
272         }
273
274         // Allow if denies specified but not allows
275
if ((denies.length > 0) && (allows.length == 0)) {
276             getNext().invoke(request, response);
277             return;
278         }
279
280         // Deny this request
281
response.sendError(HttpServletResponse.SC_FORBIDDEN);
282
283     }
284
285
286 }
287
Popular Tags