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