1 // ========================================================================
2 // $Id$
3 // Copyright (c) 2004-2009 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 // The Eclipse Public License is available at
9 // http://www.eclipse.org/legal/epl-v10.html
10 // The Apache License v2.0 is available at
11 // http://www.opensource.org/licenses/apache2.0.php
12 // You may elect to redistribute this code under either of these licenses.
13 // ========================================================================
14 package org.eclipse.jetty.rewrite.handler;
15
16 import java.io.IOException;
17
18 import javax.servlet.ServletException;
19 import javax.servlet.http.HttpServletRequest;
20 import javax.servlet.http.HttpServletResponse;
21
22 import org.eclipse.jetty.http.PathMap;
23 import org.eclipse.jetty.server.Request;
24 import org.eclipse.jetty.server.handler.HandlerWrapper;
25
26 /* ------------------------------------------------------------ */
27 /**
28 *<p> Rewrite handler is responsible for managing the rules. Its capabilities
29 * is not only limited for url rewrites such as RewritePatternRule or RewriteRegexRule.
30 * There is also handling for cookies, headers, redirection, setting status or error codes
31 * whenever the rule finds a match.
32 *
33 * <p> The rules can be matched by the ff. options: pattern matching of PathMap
34 * (class PatternRule), regular expressions (class RegexRule) or certain conditions set
35 * (e.g. MsieSslRule - the requests must be in SSL mode).
36 *
37 * Here are the list of rules:
38 * <ul>
39 * <li> CookiePatternRule - adds a new cookie in response. </li>
40 * <li> HeaderPatternRule - adds/modifies the HTTP headers in response. </li>
41 * <li> RedirectPatternRule - sets the redirect location. </li>
42 * <li> ResponsePatternRule - sets the status/error codes. </li>
43 * <li> RewritePatternRule - rewrites the requested URI. </li>
44 * <li> RewriteRegexRule - rewrites the requested URI using regular expression for pattern matching. </li>
45 * <li> MsieSslRule - disables the keep alive on SSL for IE5 and IE6. </li>
46 * <li> LegacyRule - the old version of rewrite. </li>
47 * <li> ForwardedSchemeHeaderRule - set the scheme according to the headers present. </li>
48 * </ul>
49 *
50 * <p> The rules can be grouped into rule containers (class RuleContainerRule), and will only
51 * be applied if the request matches the conditions for their container
52 * (e.g., by virtual host name)
53 *
54 * Here are a list of rule containers:
55 * <ul>
56 * <li> VirtualHostRuleContainerRule - checks whether the request matches one of a set of virtual host names.</li>
57 * </ul>
58 *
59 * Here is a typical jetty.xml configuration would be: <pre>
60 *
61 * <Set name="handler">
62 * <New id="Handlers" class="org.eclipse.jetty.rewrite.handler.RewriteHandler">
63 * <Set name="rules">
64 * <Array type="org.eclipse.jetty.rewrite.handler.Rule">
65 *
66 * <Item>
67 * <New id="rewrite" class="org.eclipse.jetty.rewrite.handler.RewritePatternRule">
68 * <Set name="pattern">/*</Set>
69 * <Set name="replacement">/test</Set>
70 * </New>
71 * </Item>
72 *
73 * <Item>
74 * <New id="response" class="org.eclipse.jetty.rewrite.handler.ResponsePatternRule">
75 * <Set name="pattern">/session/</Set>
76 * <Set name="code">400</Set>
77 * <Set name="reason">Setting error code 400</Set>
78 * </New>
79 * </Item>
80 *
81 * <Item>
82 * <New id="header" class="org.eclipse.jetty.rewrite.handler.HeaderPatternRule">
83 * <Set name="pattern">*.jsp</Set>
84 * <Set name="name">server</Set>
85 * <Set name="value">dexter webserver</Set>
86 * </New>
87 * </Item>
88 *
89 * <Item>
90 * <New id="header" class="org.eclipse.jetty.rewrite.handler.HeaderPatternRule">
91 * <Set name="pattern">*.jsp</Set>
92 * <Set name="name">title</Set>
93 * <Set name="value">driven header purpose</Set>
94 * </New>
95 * </Item>
96 *
97 * <Item>
98 * <New id="redirect" class="org.eclipse.jetty.rewrite.handler.RedirectPatternRule">
99 * <Set name="pattern">/test/dispatch</Set>
100 * <Set name="location">http://jetty.eclipse.org</Set>
101 * </New>
102 * </Item>
103 *
104 * <Item>
105 * <New id="regexRewrite" class="org.eclipse.jetty.rewrite.handler.RewriteRegexRule">
106 * <Set name="regex">/test-jaas/$</Set>
107 * <Set name="replacement">/demo</Set>
108 * </New>
109 * </Item>
110 *
111 * <Item>
112 * <New id="forwardedHttps" class="org.eclipse.jetty.rewrite.handler.ForwardedSchemeHeaderRule">
113 * <Set name="header">X-Forwarded-Scheme</Set>
114 * <Set name="headerValue">https</Set>
115 * <Set name="scheme">https</Set>
116 * </New>
117 * </Item>
118 *
119 * <Item>
120 * <New id="virtualHost" class="org.eclipse.jetty.rewrite.handler.VirtualHostRuleContainer">
121 *
122 * <Set name="virtualHosts">
123 * <Array type="java.lang.String">
124 * <Item>eclipse.com</Item>
125 * <Item>www.eclipse.com</Item>
126 * <Item>eclipse.org</Item>
127 * <Item>www.eclipse.org</Item>
128 * </Array>
129 * </Set>
130 *
131 * <Call name="addRule">
132 * <Arg>
133 * <New class="org.eclipse.jetty.rewrite.handler.CookiePatternRule">
134 * <Set name="pattern">/*</Set>
135 * <Set name="name">CookiePatternRule</Set>
136 * <Set name="value">1</Set>
137 * </New>
138 * </Arg>
139 * </Call>
140 *
141 * </New>
142 * </ Item>
143 *
144 * </Array>
145 * </Set>
146 *
147 * <Set name="handler">
148 * <New id="Handlers" class="org.eclipse.jetty.server.handler.HandlerCollection">
149 * <Set name="handlers">
150 * <Array type="org.eclipse.jetty.server.Handler">
151 * <Item>
152 * <New id="Contexts" class="org.eclipse.jetty.server.handler.ContextHandlerCollection"/>
153 * </Item>
154 * <Item>
155 * <New id="DefaultHandler" class="org.eclipse.jetty.server.handler.DefaultHandler"/>
156 * </Item>
157 * <Item>
158 * <New id="RequestLog" class="org.eclipse.jetty.server.handler.RequestLogHandler"/>
159 * </Item>
160 * </Array>
161 * </Set>
162 * </New>
163 * </Set>
164 *
165 * </New>
166 * </Set>
167 * </pre>
168 *
169 */
170 public class RewriteHandler extends HandlerWrapper
171 {
172
173 private RuleContainer _rules;
174
175 /* ------------------------------------------------------------ */
176 public RewriteHandler()
177 {
178 _rules = new RuleContainer();
179 }
180
181 /* ------------------------------------------------------------ */
182 /**
183 * To enable configuration from jetty.xml on rewriteRequestURI, rewritePathInfo and
184 * originalPathAttribute
185 *
186 * @param legacyRule old style rewrite rule
187 */
188 public void setLegacyRule(LegacyRule legacyRule)
189 {
190 _rules.setLegacyRule(legacyRule);
191 }
192
193 /* ------------------------------------------------------------ */
194 /**
195 * Returns the list of rules.
196 * @return an array of {@link Rule}.
197 */
198 public Rule[] getRules()
199 {
200 return _rules.getRules();
201 }
202
203 /* ------------------------------------------------------------ */
204 /**
205 * Assigns the rules to process.
206 * @param rules an array of {@link Rule}.
207 */
208 public void setRules(Rule[] rules)
209 {
210 _rules.setRules(rules);
211 }
212
213 /*------------------------------------------------------------ */
214 /**
215 * Assigns the rules to process.
216 * @param rules a {@link RuleContainer} containing other rules to process
217 */
218 public void setRules(RuleContainer rules)
219 {
220 _rules = rules;
221 }
222
223 /* ------------------------------------------------------------ */
224 /**
225 * Add a Rule
226 * @param rule The rule to add to the end of the rules array
227 */
228 public void addRule(Rule rule)
229 {
230 _rules.addRule(rule);
231 }
232
233
234 /* ------------------------------------------------------------ */
235 /**
236 * @return the rewriteRequestURI If true, this handler will rewrite the value
237 * returned by {@link HttpServletRequest#getRequestURI()}.
238 */
239 public boolean isRewriteRequestURI()
240 {
241 return _rules.isRewriteRequestURI();
242 }
243
244 /* ------------------------------------------------------------ */
245 /**
246 * @param rewriteRequestURI true if this handler will rewrite the value
247 * returned by {@link HttpServletRequest#getRequestURI()}.
248 */
249 public void setRewriteRequestURI(boolean rewriteRequestURI)
250 {
251 _rules.setRewriteRequestURI(rewriteRequestURI);
252 }
253
254 /* ------------------------------------------------------------ */
255 /**
256 * @return true if this handler will rewrite the value
257 * returned by {@link HttpServletRequest#getPathInfo()}.
258 */
259 public boolean isRewritePathInfo()
260 {
261 return _rules.isRewritePathInfo();
262 }
263
264 /* ------------------------------------------------------------ */
265 /**
266 * @param rewritePathInfo true if this handler will rewrite the value
267 * returned by {@link HttpServletRequest#getPathInfo()}.
268 */
269 public void setRewritePathInfo(boolean rewritePathInfo)
270 {
271 _rules.setRewritePathInfo(rewritePathInfo);
272 }
273
274 /* ------------------------------------------------------------ */
275 /**
276 * @return the originalPathAttribte. If non null, this string will be used
277 * as the attribute name to store the original request path.
278 */
279 public String getOriginalPathAttribute()
280 {
281 return _rules.getOriginalPathAttribute();
282 }
283
284 /* ------------------------------------------------------------ */
285 /**
286 * @param originalPathAttribte If non null, this string will be used
287 * as the attribute name to store the original request path.
288 */
289 public void setOriginalPathAttribute(String originalPathAttribute)
290 {
291 _rules.setOriginalPathAttribute(originalPathAttribute);
292 }
293
294
295 /* ------------------------------------------------------------ */
296 /**
297 * @deprecated
298 */
299 public PathMap getRewrite()
300 {
301 return _rules.getRewrite();
302 }
303
304 /* ------------------------------------------------------------ */
305 /**
306 * @deprecated
307 */
308 public void setRewrite(PathMap rewrite)
309 {
310 _rules.setRewrite(rewrite);
311 }
312
313 /* ------------------------------------------------------------ */
314 /**
315 * @deprecated
316 */
317 public void addRewriteRule(String pattern, String prefix)
318 {
319 _rules.addRewriteRule(pattern,prefix);
320 }
321
322 /* ------------------------------------------------------------ */
323 /* (non-Javadoc)
324 * @see org.eclipse.jetty.server.handler.HandlerWrapper#handle(java.lang.String, javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse, int)
325 */
326 public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
327 {
328 if (isStarted())
329 {
330 String returned = _rules.matchAndApply(target, request, response);
331 target = (returned == null) ? target : returned;
332
333 if (!_rules.isHandled())
334 {
335 super.handle(target, baseRequest, request, response);
336 }
337 }
338 }
339
340 }