org.eclipse.jetty.rewrite.handler.RewriteHandler Maven / Gradle / Ivy
Show all versions of driver-cql-shaded Show documentation
//
// ========================================================================
// Copyright (c) 1995-2021 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under the
// terms of the Eclipse Public License v. 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0
// which is available at https://www.apache.org/licenses/LICENSE-2.0.
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//
package org.eclipse.jetty.rewrite.handler;
import java.io.IOException;
import java.util.Arrays;
import java.util.EnumSet;
import jakarta.servlet.DispatcherType;
import jakarta.servlet.ServletException;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.handler.HandlerWrapper;
/**
* Rewrite handler is responsible for managing the rules. Its capabilities
* is not only limited for URL rewrites such as RewritePatternRule or RewriteRegexRule.
* There is also handling for cookies, headers, redirection, setting status or error codes
* whenever the rule finds a match.
*
*
The rules can be matched by the either: pattern matching of @{@link org.eclipse.jetty.http.pathmap.ServletPathSpec}
* (eg {@link PatternRule}), regular expressions (eg {@link RegexRule}) or certain conditions set
* (eg {@link MsieSslRule} - the requests must be in SSL mode).
*
*
The rules can be grouped into rule containers (class {@link RuleContainer}), and will only
* be applied if the request matches the conditions for their container
* (e.g., by virtual host name)
*
*
The list of predefined rules is:
*
* - {@link CookiePatternRule} - adds a new cookie in response.
* - {@link HeaderPatternRule} - adds/modifies the HTTP headers in response.
* - {@link RedirectPatternRule} - sets the redirect location.
* - {@link ResponsePatternRule} - sets the status/error codes.
* - {@link RewritePatternRule} - rewrites the requested URI.
* - {@link RewriteRegexRule} - rewrites the requested URI using regular expression for pattern matching.
* - {@link MsieSslRule} - disables the keep alive on SSL for IE5 and IE6.
* - {@link ForwardedSchemeHeaderRule} - set the scheme according to the headers present.
* - {@link VirtualHostRuleContainer} - checks whether the request matches one of a set of virtual host names.
*
*
*
* Here is a typical jetty.xml configuration would be:
*
* <New id="RewriteHandler" class="org.eclipse.jetty.rewrite.handler.RewriteHandler">
* <Set name="rules">
* <Array type="org.eclipse.jetty.rewrite.handler.Rule">
*
* <Item>
* <New id="rewrite" class="org.eclipse.jetty.rewrite.handler.RewritePatternRule">
* <Set name="pattern">/*</Set>
* <Set name="replacement">/test</Set>
* </New>
* </Item>
*
* <Item>
* <New id="response" class="org.eclipse.jetty.rewrite.handler.ResponsePatternRule">
* <Set name="pattern">/session/</Set>
* <Set name="code">400</Set>
* <Set name="reason">Setting error code 400</Set>
* </New>
* </Item>
*
* <Item>
* <New id="header" class="org.eclipse.jetty.rewrite.handler.HeaderPatternRule">
* <Set name="pattern">*.jsp</Set>
* <Set name="name">server</Set>
* <Set name="value">dexter webserver</Set>
* </New>
* </Item>
*
* <Item>
* <New id="header" class="org.eclipse.jetty.rewrite.handler.HeaderPatternRule">
* <Set name="pattern">*.jsp</Set>
* <Set name="name">title</Set>
* <Set name="value">driven header purpose</Set>
* </New>
* </Item>
*
* <Item>
* <New id="redirect" class="org.eclipse.jetty.rewrite.handler.RedirectPatternRule">
* <Set name="pattern">/test/dispatch</Set>
* <Set name="location">http://jetty.eclipse.org</Set>
* </New>
* </Item>
*
* <Item>
* <New id="regexRewrite" class="org.eclipse.jetty.rewrite.handler.RewriteRegexRule">
* <Set name="regex">/test-jaas/$</Set>
* <Set name="replacement">/demo</Set>
* </New>
* </Item>
*
* <Item>
* <New id="forwardedHttps" class="org.eclipse.jetty.rewrite.handler.ForwardedSchemeHeaderRule">
* <Set name="header">X-Forwarded-Scheme</Set>
* <Set name="headerValue">https</Set>
* <Set name="scheme">https</Set>
* </New>
* </Item>
*
* <Item>
* <New id="virtualHost" class="org.eclipse.jetty.rewrite.handler.VirtualHostRuleContainer">
*
* <Set name="virtualHosts">
* <Array type="java.lang.String">
* <Item>eclipse.com</Item>
* <Item>www.eclipse.com</Item>
* <Item>eclipse.org</Item>
* <Item>www.eclipse.org</Item>
* </Array>
* </Set>
*
* <Call name="addRule">
* <Arg>
* <New class="org.eclipse.jetty.rewrite.handler.CookiePatternRule">
* <Set name="pattern">/*</Set>
* <Set name="name">CookiePatternRule</Set>
* <Set name="value">1</Set>
* </New>
* </Arg>
* </Call>
*
* </New>
* </Item>
*
* </Array>
* </Set>
* </New>
*
* <Set name="handler">
* <Ref id="RewriteHandler"/>
* <Set name="handler">
* <New id="Handlers" class="org.eclipse.jetty.server.handler.HandlerCollection">
* <Set name="handlers">
* <Array type="org.eclipse.jetty.server.Handler">
* <Item>
* <New id="Contexts" class="org.eclipse.jetty.server.handler.ContextHandlerCollection"/>
* </Item>
* <Item>
* <New id="DefaultHandler" class="org.eclipse.jetty.server.handler.DefaultHandler"/>
* </Item>
* </Array>
* </Set>
* </New>
* </Set>
* </Ref>
* </Set>
*
*/
public class RewriteHandler extends HandlerWrapper
{
private RuleContainer _rules;
private EnumSet _dispatchTypes = EnumSet.of(DispatcherType.REQUEST, DispatcherType.ASYNC);
public RewriteHandler()
{
_rules = new RuleContainer();
addBean(_rules);
}
/**
* Returns the list of rules.
*
* @return an array of {@link Rule}.
*/
public Rule[] getRules()
{
return _rules.getRules();
}
/**
* Assigns the rules to process.
*
* @param rules an array of {@link Rule}.
*/
public void setRules(Rule[] rules)
{
_rules.setRules(rules);
}
/**
* Assigns the rules to process.
*
* @param rules a {@link RuleContainer} containing other rules to process
*/
public void setRuleContainer(RuleContainer rules)
{
updateBean(_rules, rules);
_rules = rules;
}
public RuleContainer getRuleContainer()
{
return _rules;
}
/**
* Add a Rule
*
* @param rule The rule to add to the end of the rules array
*/
public void addRule(Rule rule)
{
_rules.addRule(rule);
}
/**
* @return the rewriteRequestURI If true, this handler will rewrite the value
* returned by {@link HttpServletRequest#getRequestURI()}.
*/
public boolean isRewriteRequestURI()
{
return _rules.isRewriteRequestURI();
}
/**
* @param rewriteRequestURI true if this handler will rewrite the value
* returned by {@link HttpServletRequest#getRequestURI()}.
*/
public void setRewriteRequestURI(boolean rewriteRequestURI)
{
_rules.setRewriteRequestURI(rewriteRequestURI);
}
/**
* @return true if this handler will rewrite the value
* returned by {@link HttpServletRequest#getPathInfo()}.
*/
public boolean isRewritePathInfo()
{
return _rules.isRewritePathInfo();
}
/**
* @param rewritePathInfo true if this handler will rewrite the value
* returned by {@link HttpServletRequest#getPathInfo()}.
*/
public void setRewritePathInfo(boolean rewritePathInfo)
{
_rules.setRewritePathInfo(rewritePathInfo);
}
/**
* @return the originalPathAttribte. If non null, this string will be used
* as the attribute name to store the original request path.
*/
public String getOriginalPathAttribute()
{
return _rules.getOriginalPathAttribute();
}
/**
* @param originalPathAttribute If non null, this string will be used
* as the attribute name to store the original request path.
*/
public void setOriginalPathAttribute(String originalPathAttribute)
{
_rules.setOriginalPathAttribute(originalPathAttribute);
}
public EnumSet getDispatcherTypes()
{
return _dispatchTypes;
}
public void setDispatcherTypes(EnumSet types)
{
_dispatchTypes = EnumSet.copyOf(types);
}
public void setDispatcherTypes(DispatcherType... types)
{
_dispatchTypes = EnumSet.copyOf(Arrays.asList(types));
}
@Override
public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException
{
if (isStarted())
{
if (_dispatchTypes.contains(baseRequest.getDispatcherType()))
{
String returned = _rules.matchAndApply(target, request, response);
target = (returned == null) ? target : returned;
}
if (!baseRequest.isHandled())
super.handle(target, baseRequest, request, response);
}
}
}