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 }