Caucho Technology
  • resin 4.0
  • url rewriting and dispatching


    When you need to rewrite an external URL to a more convenient internal format, like rewriting to *.php files, you can use Resin's rewrite capabilities. Because Resin's rewrite is patterned after Apache's mod_rewrite, you can translate older mod_rewrite rules to Resin's rewrite tags.

    Samples

    MediaWiki rewrites

    PHP frameworks like MediaWiki often rewrite the public URLs to a server URL based on a PHP file, but pass through known file types like .jpg, .js, and .css file for normal webserver processing. The <resin:Dispatch> tag matches a URL with a regular expression, and optionally rewrites the URL. MediaWiki uses two: one to match the known files, and one to rewrite to a .php file.

    Example: MediaWiki /Main_Page to /index.php/Main_Page
    <web-app xmlns="http://caucho.com/ns/resin"
                xmlns:resin="urn:java:com.caucho.resin">
    
      <resin:Dispatch regexp="\.(php|jpg|html|txt|gif|png|js|css)"/>
      
      <resin:Dispatch regexp="^" target="/index.php"/>
    	    
    </web-app>
    

    Because the first matching rewrite rule stops processing, a URL like "/default.css" would match the first Dispatch and be processed like a normal URL. But a URL like "/foo" doesn't match the first tag, so falls through to the second, where it is rewritten to "/index.php/foo".

    Other PHP packages like Drupal use the same kind of rewriting:

    Example: Drupal node/1924
    <web-app xmlns="http://caucho.com/ns/resin"
                xmlns:resin="urn:java:com.caucho.resin">
    
      <resin:Dispatch regexp="\.(php|jpg|html|txt|gif|png|js|css)"/>
      
      <resin:Dispatch regexp="^/" target="/index.php?q="/>
    	    
    </web-app>
    
    Example: Wordpress Rewriting
    <web-app xmlns="http://caucho.com/ns/resin"
                xmlns:resin="urn:java:com.caucho.resin">
    
      <resin:Dispatch>
        <resin:IfFileExists/>
      </resin:Dispatch>
    
      <resin:Forward regexp="^" target='/index.php'/>
    
    </web-app>
    

    Redirects

    Example: redirecting old pages
    <web-app xmlns="http://caucho.com/ns/resin"
                xmlns:resin="urn:java:com.caucho.resin">
    
      <resin:Redirect regexp="^/old-page.html" target="/new-page.html"/>
      <resin:Redirect regexp="^/old/" target="/new/"/>
    	    
    </web-app>
    

    Overview

    Dispatch rules
    NAMEDESCRIPTION
    <resin:Dispatch>Normal servlet dispatching with optional target rewriting.
    <resin:FastCgiProxy>Proxies the request to a backend server using FastCGI as a proxy protocol.
    <resin:Forbidden>Send a HTTP forbidden response.
    <resin:Forward>Forwards to the new URL using RequestDispatcher.forward with the target URL.
    <resin:HttpProxy>Proxies the request to a backend server using HTTP as a proxy protocol.
    <resin:LoadBalance>Load balance to a cluster of backend Resin servers.
    <resin:Redirect>Send a HTTP redirect to a new URL specified by target.
    <resin:SendError>Send a HTTP error response.
    AbstractTargetDispatchRuleBase class for custom dispatch rules.
    Basic conditions
    NAMEDESCRIPTION
    <resin:IfAuthType>Checks for the authentication type, request.getAuthType().
    <resin:IfCookie>Checks for the presence of a named HTTP cookie from request.getCookies().
    <resin:IfCron>Matches if the current time is in an active range configured by cron-style times.
    <resin:IfFileExists>Matches if the URL corresponds to an actual file.
    <resin:IfHeader>Tests for a HTTP header and value match.
    <resin:IfLocale>Tests for a Locale match from the HTTP request.
    <resin:IfLocalPort>Compares the local port of the request, request.getLocalPort().
    <resin:IfMethod>Compares the HTTP method, request.getMethod().
    <resin:IfNetwork>Compares the remote IP address to a network pattern like 192.168/16.
    <resin:IfQueryParam>Tests for a HTTP query parameger, request.getParameter().
    <resin:IfRemoteAddr>Tests against the remote IP address, request.getRemoteAddr().
    <resin:IfRemoteUser>Tests against the remote user, request.getRemoteUser().
    <resin:IfSecure>True for SSL requests, i.e. if request.isSecure() is true.
    <resin:IfUserInRole>Tests is the user is in the servlet security role.
    RequestPredicateInterface for custom request predicates.
    Combining conditions
    NAMEDESCRIPTION
    <resin:And>Matches if all children match.
    <resin:Or>Matches if any children match.
    <resin:Not>Matches if the child does not match.
    <resin:NotAnd>Matches if any child does not match.
    <resin:NotOr>Matches if all the children do not match.
    Rewrite filters
    NAMEDESCRIPTION
    <resin:SetHeader>Sets a response header.
    <resin:SetRequestSecure>Marks the request as secure.
    <mypkg:MyFilter>Servlet filters.

    Dispatch Rules

    Resin's dispatching is based on a list of dispatch rules configured in the resin-web.xml or the resin.xml configuration files. Each rule has a regular expression matching request URLs. The first dispatch rule that matches takes control of the request. For example, a <resin:Redirect> sends a HTTP redirect, and a <resin:Dispatch> dispatches the request as normal.

    Each matching rule can rewrite the URL using a target attribute. The target uses regexp replacement syntax like Perl's rewrite or sed. The following rule flips the first two segments around, so /foo/bar would become /bar/foo.

    Example: redirect flipping
    <web-app xmlns="http://caucho.com/ns/resin"
                xmlns:resin="urn:java:com.caucho.resin">
    
      <resin:Redirect regexp="^/([^/]+)/([^/]+)" target="/$2/$1"/>
    	    
    </web-app>
    

    Conditions

    Some dispatches might depend on request attributes like the security attribute. The <resin:IfSecure> tag checks if the request is an SSL request, i.e. if request.isSecure() is true. For non-SSL requests, the following <resin:Forbidden> applies.

    The rewrite conditions can all be used as security conditions, e.g. for <resin:Allow> or <resin:Deny>.

    Example: dispatch on header
    <web-app xmlns="http://caucho.com/ns/resin"
                xmlns:resin="urn:java:com.caucho.resin">
    
      <resin:Forbidden regexp="^/secret">
        <resin:IfSecure value="false"/>
      </resin:Forbidden>
    	    
    </web-app>
    

    Basic Conditions

    Basic conditions check the request and return true if the condition matches. Conditions can check on authentication (IsUserInRole), the remote IP (IfNetwork), check for SSL (IfSecure), and check for activation time (IfCron) or if a file exists (IfFileExists).

    Combining Conditions

    Conditions can be combined using <resin:And>, <resin:Not>, etc. tags.

    Filter Actions

    The rewrite capability can also add standard predefined filters to modify the output, e.g. setting a response header. Filters can use conditions as restrictions, just like the dispatch rules.

    Example: SetHeader
    <web-app xmlns="http://caucho.com/ns/resin"
                xmlns:resin="urn:java:com.caucho.resin">
    
      <resin:SetHeader regexp="^/secret" name="Foo" value="bar"/>
    	    
    </web-app>
    

    Servlet Filters

    Standard servlet filters can also be invoked as an action to the Dispatch target. Your filter is created using Java Injection syntax and will be applied if the Dispatch rule matches.

    Example: SetHeader
    <web-app xmlns="http://caucho.com/ns/resin"
                xmlns:resin="urn:java:com.caucho.resin">
    
      <resin:Dispatch regexp="^/test">
        <mypkg:MyFilter xmlns:my="urn:java:com.foo.mypkg">
          <mypkg:my-param>my-value</mypkg:my-param>
        </mypkg:MyFilter>
      </resin:Dispatch>
    	    
    </web-app>
    

    <and>

    child of when, unless

    Contains one or more conditions and evaluates to true if all of the contained conditions evaluate to true, false if any of the contained conditions does not evaluate to true.

    auth-type

    child of when, unless

    Evaluates to true if the authorization mechanism used in the request is the given value. The comparison is always case insensitive.

    If the auth-type is not "none", or if the auth-type of the request is not "none", a Cache-Control header containing "private" is added to the response.

    auth-typeBASIC, CLIENT-CERT, DIGEST, FORM, or NONErequired
    send-varySend a Vary header containing "Cookie" as part of the responsetrue

    cookie

    child of when, unless

    Evaluates to true if the value of a cookie with a given name matches a regular expression regexp, false if it does not or if the cookie does not exist.

    The Vary header of the response is updated to include "Cookie", which indicates to the browser and any intervening proxy cache that the response varies based on the submitted value of cookies.

    cookieName of the cookierequired
    regexpThe regular expression to matchoptional
    send-varySend a Vary header containing "Cookie" as part of the responsetrue

    disable-at

    Cron syntax for specifying a time or times that that the rule should be disabled. In conjunction, enable-at and disable-at provide a means for scheduling the enablement of a rule.

    <dispatch>

    child of rewrite-dispatch, match

    If <dispatch> matches the current URL, the rest of the items in the enclosing rewrite-dispatch are not considered and the request passes immediately to normal servlet evaluation. <dispatch> is often used to specify URLs which should be handled normally before a more general pattern which modifies the URL.

    For example, the following pattern uses <dispatch> to handle images and *.php files normally, but forward's all other requests to /index.php.

    Mediawiki dispatch in resin-web.xml
    <web-app xmlns="http://caucho.com/ns/resin">
    
     <rewrite-dispatch>
       <dispatch regexp="\.(php|gif|css|jpg|png)"/>
       <forward regexp="^" target="/index.php"/>
     </rewrite-dispatch>
    
    </web-app>
    
    disable-atA cron syntax time specification for triggering disablement of the rulenone
    enable-atA cron syntax time specification for triggering enablement of the rulenone
    enabledFalse to start with the rule initially disabledtrue
    nameA name to use for registering a JMX mbean with type=RewriteRuledo not register an mbean
    regexpA regexp that must match the URLoptional
    whenA condition which must evaluate to trueoptional
    unlessA condition which must not evaluate to trueoptional

    dispatch-type

    The dispatch-type lets you configure rewrite-dispatch for REQUEST, FORWARD, or INCLUDE. By default, the rewrite-dispatch is REQUEST.

    Example: FORWARD dispatch
    <web-app xmlns="http://caucho.com/ns/resin">
    
      <rewrite-dispatch>
        <dispatch-type>FORWARD</dispatch-type>
    
        <forward regexp="/foo" target="/bar.jsp"/>
      </rewrite-dispatch>
    
    </web-app>
    

    enable-at

    Cron syntax for specifying a time or times that that the rule should be enabled, see <disable-at/>.

    enabled

    Set's the initial state of the rule, default is true. In conjunction with name, an initial enabled value of "false" is valuable for rules which are to be turned on and turned off at runtime.

    <forbidden>

    child of rewrite-dispatch, match

    <forbidden> sents a 403 forbidden message to the browser for a matching URL.

    Forbidding a directory
    <web-app xmlns="http://caucho.com/ns/resin">
    
     <rewrite-dispatch>
       <forbidden regexp="^/protected"/>
     </rewrite-dispatch>
    
    </web-app>
    
    disable-atA cron syntax time specification for triggering disablement of the rulenone
    enable-atA cron syntax time specification for triggering enablement of the rulenone
    enabledFalse to start with the rule initially disabledtrue
    nameA name to use for registering a JMX mbean with type=RewriteRuledo not register an mbean
    regexpA regexp that must match the URLoptional
    whenA condition which must evaluate to trueoptional
    unlessA condition which must not evaluate to trueoptional

    <forward>

    child of rewrite-dispatch, match

    <forward> rewrites the current URL, forwarding it to the target using the servlet forward() call. Because <forward> is internal, it will have better performance than a <redirect> when the target URL is on the same server, the browser will not know that the underlying resource has moved.

    Forwarding to a new URL
    <web-app xmlns="http://caucho.com/ns/resin">
    
     <rewrite-dispatch>
       <forward regexp="^/old" target="/new"/>
     </rewrite-dispatch>
    
    </web-app>
    
    disable-atA cron syntax time specification for triggering disablement of the rulenone
    enable-atA cron syntax time specification for triggering enablement of the rulenone
    enabledFalse to start with the rule initially disabledtrue
    nameA name to use for registering a JMX mbean with type=RewriteRuledo not register an mbean
    regexpA regexp that must match the URLoptional
    targetThe target of the the forewardrequired
    whenA condition which must evaluate to trueoptional
    unlessA condition which must not evaluate to trueoptional

    header

    child of when, unless

    Evaluates to true if the value of a header with a given name matches a regular expression regexp, false if it does not or if the header does not exist.

    The Vary header of the response is updated to include the header name which indicates to the browser and any intervening proxy cache that the response varies based on the submitted value of the header.

    headerName of the headerrequired
    regexpThe regular expression to matchoptional
    send-varySend a Vary header containing the header name as part of the responsetrue

    <gone>

    child of rewrite-dispatch, match

    <gone> sents a 410 gone response to the browser for a matching URL.

    Hiding a directory
    <web-app xmlns="http://caucho.com/ns/resin">
    
     <rewrite-dispatch>
       <gone regexp="^/protected"/>
     </rewrite-dispatch>
    
    </web-app>
    
    disable-atA cron syntax time specification for triggering disablement of the rulenone
    enable-atA cron syntax time specification for triggering enablement of the rulenone
    enabledFalse to start with the rule initially disabledtrue
    nameA name to use for registering a JMX mbean with type=RewriteRuledo not register an mbean
    regexpA regexp that must match the URLoptional
    whenA condition which must evaluate to trueoptional
    unlessA condition which must not evaluate to trueoptional

    <import>

    child of rewrite-dispatch, match

    <import> loads rules from an external xml file.

    Importing rules from an external file
    <web-app xmlns="http://caucho.com/ns/resin"
             xmlns:resin="http://caucho.com/ns/resin/core">
    
      <rewrite-dispatch>
        <import path='/WEB-INF/rewrite-maintenance.xml' enabled="false"/>
        <import path='/WEB-INF/rewrite-rules.xml'/>
      </rewrite-dispatch>
    
    </web-app>
    
    An external file containing rules
    <rewrite-dispatch xmlns="http://caucho.com/ns/resin"
                      xmlns:resin="http://caucho.com/ns/resin/core">
    
       <dispatch regexp="\.(css|gif|jpg|pdf|png)"/>
    
       <forward regexp=".*" target="/maintenance.html"/>
    
    </rewrite-dispatch>
    

    Changes to the external file are checked for at a frequency determined by dependency-check-interval or when the update() operation of the mbean is invoked. If an error occurs when loading the modified file, the contents of the old file are used until the errors are corrected or the server is restarted. The log file will contain details for the error, and the RedeployError property of the mbean wil contain a description of the error.

    Each <import> registers an mbean of type RewriteImport, with a full a name like "resin:Host=default,WebApp=/,name=Foo,type=RewriteRule" and an interface of com.caucho.management.server.RewriteImportMXBean. It provides the update(), start() and stop() operations. The update() operations forces an immediate check for modifications to the external file.

    disable-atA cron syntax time specification for triggering disablement of the rulenone
    dependency-check-intervalThe frequency with which to check the external file for changesThe dependency-check-interval of the environment
    enable-atA cron syntax time specification for triggering enablement of the rulenone
    enabledFalse to start with the rule initially disabledtrue
    nameA name to use for registering a JMX mbean with type=RewriteImportthe value of path
    optionalIf false, do not require that the path existstrue
    pathA path to an external xml filerequired

    <load-balance>

    child of rewrite-dispatch, match

    <load-balance> forwards requests from a web-tier server to a cluster of app-tier servers for load-balancing. Load balancing provides scalability by splitting load among many application servers and increases reliability by avoiding servers which are upgrading or restarting.

    In the following example, the web-tier load-balances all traffic to a cluster of backend application servers. Because the web-tier has a proxy cache, static pages and cached pages will be served directory from the web-tier.

    <load-balance> requires Resin Professional.

    Load balancing to an app-tier
    <resin xmlns="http://caucho.com/ns/resin">
    
      <cluster id="app-tier">
        <server id="app-a" address="192.168.3.1">
        <server id="app-b" address="192.168.3.2">
        ...
      </cluster>
    
      <cluster id="web-tier">
        <server id="web-a" address="192.168.2.1">
          <http port="80"/>
        </server>
    
        <cache/>
    
        <host id="">
          <web-app id="/">
    
            <rewrite-dispatch>
              <load-balance regexp="" cluster="app-tier"/>
            </rewrite-dispatch>
    
          </web-app>
        </host>
    
    </resin>
    
    clusterThe cluster that gets the matching requestsrequired
    disable-atA cron syntax time specification for triggering disablement of the rulenone
    enable-atA cron syntax time specification for triggering enablement of the rulenone
    enabledFalse to start with the rule initially disabledtrue
    nameA name to use for registering a JMX mbean with type=RewriteRuledo not register an mbean
    regexpA regexp that must match the URLoptional
    sticky-sessionsWhether or not sessions should be stickytrue
    strategyThe load balancing strategy, `round-robin' or `least-connection'least-connection
    whenA condition which must evaluate to trueoptional
    unlessA condition which must not evaluate to trueoptional

    locale

    child of when, unless

    Evaluates to true if the value of the Locale matches a regular expression, false if it does not. The comparison is always case insensitive.

    The Locale is a normalization of the value of the Accept-Language header. For example "fr" remains "fr" and "FR-CA" becomes "fr_CA". If the request does not include the Accept-Language header then the Locale is the default Locale for the server.

    <web-app xmlns="http://caucho.com/ns/resin"
             xmlns:resin="http://caucho.com/ns/resin/core">
    
      <rewrite-dispatch>
        <forward regexp='^/' target='/fr/'>
          <when locale="^fr"/>
        </forward>
    
        <forward regexp='^/' target='/en/'/>
      </rewrite-dispatch>
    </web-app>
    
    localeRegular expression to matchrequired
    send-varySend a Vary header containing "Accept-Language" as part of the responsetrue

    local-port

    child of when, unless

    Evaluates to true if the value of the request's local port is the specified value, false if it does not. The local port is the port that Resin has bound to and has used to receive the request.

    local-portThe local port to match.required

    method

    child of when, unless

    Evaluates to true if the http method used in the request is the given value. The comparison is always case insensitive. Common methods include HEAD, GET, POST, DELETE, OPTIONS, PUT, and TRACE, although a method by any name may be used by a client.

    methodThe method to match.required

    <match>

    child of rewrite-dispatch, match

    <match> provides a way to group more specific rules based on the url. The contents of the <match> are any rule, and they are considered only if the regexp of the <match> is satsified and the match is enabled.

    Judicious use of <match> will provide better performance in situations where there are many rules and some of them contain when or if conditions.

    <match> also provides a convenient way to group a set of rules that can be enabled or disabled using an mbean. If the name attribute is specified for the <match> then an mbean with a name like resin:Host=default,WebApp=/,name=name,type=RewriteRule is registered and the start() and stop() operations are available.

    The documentation for <rewrite-dispatch> provides a table of all rules. In addition to the rules that can be contained within <match>, the following configuration tags are available.

    disable-atA cron syntax time specification for triggering disablement of the rulenone
    enable-atA cron syntax time specification for triggering enablement of the rulenone
    enabledFalse to start with the rule initially disabledtrue
    nameA name to use for registering a JMX mbean with type=RewriteRuledo not register an mbean
    regexpA regexp that must match the URLoptional
    whenA condition which must evaluate to trueoptional
    unlessA condition which must not evaluate to trueoptional

    <moved-permanently>

    child of rewrite-dispatch, match

    <moved-permanently> sends a HTTP 301 moved permanently response to the browser, indicating that the resource has moved.

    The following example causes all requests to the "old.com" host to be immediately redirected to "new.com". The urls will be maintained, so for example a request to http://old.com/hello/world.html?foo=bar will get redirected to http://new.com/hello/world.html?foo=bar.

    Forwarding to a new virtual host
      <host id="old.com">
        <web-app id="/">
          <rewrite-dispatch>
            <moved-permanently regexp="^/(.*)$"
                               target="http://new.com/$1"/>
          </rewrite-dispatch>
        </web-app>
      </host>
    
    disable-atA cron syntax time specification for triggering disablement of the rulenone
    enable-atA cron syntax time specification for triggering enablement of the rulenone
    enabledFalse to start with the rule initially disabledtrue
    nameA name to use for registering a JMX mbean with type=RewriteRuledo not register an mbean
    regexpA regexp that must match the URLoptional
    whenA condition which must evaluate to trueoptional
    unlessA condition which must not evaluate to trueoptional

    name

    A rule can be given a name, which causes a JMX mbean to be registered. The mbean has a name like "resin:Host=default,WebApp=/,name=Foo,type=RewriteRule" and an interface of com.caucho.management.server.RewriteRuleMXBean. It provides the start() and stop() operations.

    <not>

    child of when, unless

    Contains one or more conditions and evaluates to true only if none of the contained conditions evaluate to true, false if any of the contained conditions evaluate to true.

    <not-found>

    child of rewrite-dispatch, match

    <not-found> sents a 404 not found to the browser for a matching URL.

    Hiding a directory
    <web-app xmlns="http://caucho.com/ns/resin">
    
     <rewrite-dispatch>
       <not-found regexp="^/protected"/>
     </rewrite-dispatch>
    
    </web-app>
    
    disable-atA cron syntax time specification for triggering disablement of the rulenone
    enable-atA cron syntax time specification for triggering enablement of the rulenone
    enabledFalse to start with the rule initially disabledtrue
    nameA name to use for registering a JMX mbean with type=RewriteRuledo not register an mbean
    regexpA regexp that must match the URLoptional
    whenA condition which must evaluate to trueoptional
    unlessA condition which must not evaluate to trueoptional

    <or>

    child of when, unless

    Contains one or more conditions and evaluates to true if any of the contained conditions evaluate to true, false only if all of the contained conditions evaluate to false.

    <proxy>

    The <proxy> tag proxies HTTP requests to a backend service like <load-balance> proxies requests to a backend Resin service. Frameworks like Ruby can sit behind a Resin instance and deliver requests through the proxy tag.

    proxy attribute
    ATTRIBUTEDESCRIPTIONDEFAULT
    addresstarget IP and port like 192.168.1.10:8080
    targetreplaced URL if the URL should be rewritten

    query-param

    child of when, unless

    Evaluates to true if the value of a query parameter with a given name matches a regular expression regexp, false if it does not or if the parameter does not exist.

    Form parameters submitted in the body of a POST are not available for the comparison performed by query-param.

    query-paramName of the parameterrequired
    regexpThe regular expression to matchoptional

    <redirect>

    child of rewrite-dispatch, match

    <redirect> sends a HTTP 302 redirect response to the browser, indicating that the resource has moved.

    Forwarding to a new virtual host
    <web-app xmlns="http://caucho.com/ns/resin">
    
      <rewrite-dispatch>
        <redirect regexp="^/(foo)" target="http://$1.bar.com"/>
      </rewrite-dispatch>
    
    </web-app>
    
    Redirecting all http:// requests to https://
      <host ... >
         <rewrite-dispatch>
            <redirect regexp="^" target="https://${host.name}">
              <when secure="false"/>
            </redirect>
          </rewrite-dispatch>
          ...
       </host>
    
    disable-atA cron syntax time specification for triggering disablement of the rulenone
    enable-atA cron syntax time specification for triggering enablement of the rulenone
    enabledFalse to start with the rule initially disabledtrue
    nameA name to use for registering a JMX mbean with type=RewriteRuledo not register an mbean
    regexpA regexp that must match the URLoptional
    whenA condition which must evaluate to trueoptional
    unlessA condition which must not evaluate to trueoptional

    <regexp>

    The regular expression in a regexp tag or attribute is a standard Java regular expression.

    To make the regexp case insensitive, you can use the (?i:...) syntax:

    case-insensitive match
    <web-app xmlns="http://caucho.com/ns/resin"
             xmlns:resin="http://caucho.com/ns/resin/core">
      <rewrite-dispatch>
        <forbidden regexp='(?i:^/foo)'/>
      </rewrite-dispatch>
    </web-app>
    

    remote-addr

    child of when, unless

    Evaluates to true if the remote address of the client matches the specified ip address.

    A Cache-Control header containing "private" is added to the response.

    Forbidding admin access to clients outside of the local network
    <web-app xmlns="http://caucho.com/ns/resin"
             xmlns:resin="http://caucho.com/ns/resin/core">
      <rewrite-dispatch>
        <forbidden regexp='^/foo'>
          <unless remote-addr="192.168.2.1/24"/>
        </forbidden>
    
      </rewrite-dispatch>
    </web-app>
    
    remote-addrAn IP address, optionally followed by a / and a number of bits to match.required

    remote-user

    child of when, unless

    Evaluates to true if the user is authenticated and has the specified name.

    If there is a current user, a Cache-Control header containing "private" is added to the response.

    remote-userA user name.required
    send-varySend a Vary header containing "Cookie" as part of the responsetrue

    <rewrite>

    child of rewrite-dispatch, match

    <rewrite> rewrites the current URL, continuing processing of the <rewrite-dispatch> tags. <rewrite> can be used as an intermediate rewriting stage for more complicated patterns.

    <rewrite-real-path>

    child of web-app

    <rewrite-real-path> configures an alias for the getRealPath() call, i.e. an enhancement to the <path-mapping> tag. It provides a virtual directory mapping that allows url patterns in the web application to have a local path anywhere on the physical filesystem.

    The source path is a URL, the target path is a real filesystem path.

    /images located outside of /var/www
    <web-app xmlns="http://caucho.com/ns/resin">
    
      <rewrite-real-path>
        <real-path regexp="^/images" target="/usr/local/share/images"/>
      </rewrite-real-path>
    
    Managing versions of software bundles
    <web-app xmlns="http://caucho.com/ns/resin">
    
      <rewrite-real-path>
        <real-path regexp="^/" target="WEB-INF/SugarCE-Full-5.0.0a"/>
      </rewrite-real-path>
    

    Merge paths

    A merge path is a collection of paths, similar to a classpath. It allows the specification of multiple paths that are merged together and presented to the application as if it was one unified path. Merge paths are specified with a syntax of "merge:(path1[;path2[;pathN]])". If a file is in path1 it overrides a file with the same name in path2, if a file is not in path1 then the file will be matched to path2.

    Merge paths are useful for specifying customization directories that allow for the insertion of files that replace the usual file that is shipped with a web application.

    Merge path: replacing some images with custom images
    <web-app xmlns="http://caucho.com/ns/resin">
    
      <rewrite-real-path>
        <real-path regexp="^/images" target="merge:(custom-images;images)"/>
      </rewrite-real-path>
    
    Merge path: managing the versioning and customization of a php application
    <web-app xmlns="http://caucho.com/ns/resin">
    
      <rewrite-real-path>
        <real-path regexp="^/" target="merge:(WEB-INF/SugarCE-local;WEB-INF/SugarCE-Full-5.0.0a)"/>
      </rewrite-real-path>
    

    <rewrite-dispatch>

    child of server, host, web-app

    <rewrite-dispatch> evaluates the child tags in order. The first matching tag dispatches the request. If no children match, the request uses the standard servlet handling.

    The child tags rewrite and dispatch based on regexp patterns.

    Mediawiki dispatch in resin-web.xml
    <web-app xmlns="http://caucho.com/ns/resin">
    
     <rewrite-dispatch>
       <dispatch regexp="\.(php|gif|css|jpg|png)"/>
       <forward regexp="^" target="/index.php"/>
     </rewrite-dispatch>
    
    </web-app>
    
    <dispatch>Dispatch the request immediately and do not process any more rules
    <forbidden>Send a 403 Forbidden response to browser and do not process any more rules
    <forward>Rewrite the URL and internally forward the request without processing any more rules
    <forbidden>Send a 410 Gone response to the browser and do not process any more rules
    <import>Import rules from an external file
    <load-balance>Forward requests to another instance or instances of Resin and do not process any more rules
    <match>Group more specific rules
    <moved-permanently>Send a 310 Moved Permanently response to the browser and do not process any more rules
    <redirect>Send a 302 Moved response to the browser and do not process any more rules
    <rewrite>Rewrite the current URL and continue processing rules
    <set>Set a property of the request or response and continue processing rules

    secure

    child of when, unless

    <secure> specifies a condition for the ssl status of the request. If secure is true, then the request must be using ssl for the rule to match. If secure is false, then the request must not be using ssl for the rule to match. If secure is not specified, the ssl status of the request is not considered when testing if the rule matches.

    secure example
    <web-app xmlns="http://caucho.com/ns/resin">
      <rewrite-dispatch>
        <redirect regexp='^/foo' target='/secure'>
          <when secure='true'/>
        </redirect>
    
        <redirect regexp='^/foo' target='/insecure'>
          <when secure='false'/>
        </redirect>
    
        <redirect regexp='^/bar' target='/public'/>
      </rewrite-dispatch>
    </web-app>
    
    http://localhost:8080/foo/index.html
      --> redirect to /insecure/index.html
    
    https://localhost:8080/foo/index.html
      --> redirect to /secure/index.html
    
    http://localhost:8080/bar/index.html
      --> redirect to /public/index.html
    
    https://localhost:8080/bar/index.html
      --> redirect to /public/index.html
    

    server-name

    child of when, unless

    Evaluates to true if the value of the request's server name matches the specified regexp, false if it does not. The comparison is always case insensitive. The server name is the name that the client has used to connect to the server and may not be the name of the actual server that is hosting Resin.

    Most potential problems that can be solved by server-name are more efficiently solved using virtual hosts and the host-alias tag.

    server-nameA regular expression to match.required

    server-port

    child of when, unless

    Evaluates to true if the value of the request's server port is the specified value, false if it does not. The server port is the port that the client has used to connect to the server and may not be the actual port that Resin is bound to.

    server-portThe server port to match.required

    <set>

    child of rewrite-dispatch, match

    <set> is used to set properties of the request or response before continuing on to the next rule. The properties are maintained after the rewriting is complete, for example a request that becomes secure because of <set> will continue to be regarded as secure when the request eventually reaches a jsp or servlet.

    Making the request secure in response to a header from a hardware load balancer
    <web-app xmlns="http://caucho.com/ns/resin">
    
      <rewrite-dispatch>
        <set request-secure="true">
          <when header="X-SSL-cipher"/>
        </set>
    
        <forward regexp="^/checkout" target="https://hogwarts.com/checkout">
          <when secure="false"/>
        </forward>
    
      </rewrite-dispatch>
    
    </web-app>
    
    disable-atA cron syntax time specification for triggering disablement of the rulenone
    enable-atA cron syntax time specification for triggering enablement of the rulenone
    enabledFalse to start with the rule initially disabledtrue
    nameA name to use for registering a JMX mbean with type=RewriteRuledo not register an mbean
    regexpA regexp that must match the URLoptional
    request-character-encodingSets the character encoding of the request, used for parsing POST data, request.setCharacterEncoding(value)none
    request-secureSets the value of request.isSecure()none
    response-character-encodingSets the value of the character encoding sent for the response with response.setCharacterEncoding(value). If a Content-Type is not set either with a set rule, or by some other process involved in servicing the request, this has no effect.none
    response-content-typeSets the value of the content type sent for the response. If the final destination is a file with a corresponding mime-mapping, the mime-mapping will override the content-type set herenone
    whenA condition which must evaluate to trueoptional
    unlessA condition which must not evaluate to trueoptional

    <unless>

    Contains a condition that further refines the match of the enclosing tag beyond the information provided by the url. If the condition does not evaluate to true, then the enclosing tag is applied.

    See <when> for a description of possible conditions.

    user-in-role

    child of when, unless

    Evaluates to true if the user is authenticated and in the specified role. The special role of '*' means any role.

    If the current user is any role, a Cache-Control header containing "private" is added to the response.

    user-in-roleA role name.required
    send-varySend a Vary header containing "Cookie" as part of the responsetrue

    <when>

    Contains a condition that further refines the match of the enclosing tag beyond the information provided by the url. If the condition evaluates to true, then the enclosing tag is applied.

    <and>A subgroup of conditions that must all pass
    auth-typeEvaluates to true if the authorization mechanism used in the request is the given value
    cookieEvaluates to true if a cookie exists and matches an optional regexp
    headerEvaluates to true if a request header exists and matches an optional regexp
    localeEvaluates to true if the request locale matches the specified value
    local-portEvaluates to true if the local port is the specified value (the local port is the actual port that Resin is using)
    methodEvaluates to true if the http method used for the request is the specified value
    <not>A subgroup of conditions, none of which may pass
    <or>A subgroup of conditions, any of which may pass
    query-paramEvaluates to true if a query parameter exists and matches an optional regexp
    regexpUsed in conjunction with cookie, header, and query-param
    remote-addrEvaluates to true if the remote address of the client matches the specified ip address
    remote-userEvaluates to true if the user is authenticated and has the specified name
    secureEvaluates to true if the ssl status of the request is equal to the specified value of true or false
    server-nameEvaluates to true if the server name used by the client matches the specified value
    server-portEvaluates to true if the port used by the client equals the specified value
    user-in-roleEvaluates to true if the user is authenticated and in the specified role

    Logging and Debugging

    Logging for the name com.caucho.server.rewrite at the "finer" level reveals successful matches. At the "finest" level both successful and unsuccessful matches are logged.

    Logging example
    <logger name="com.caucho.server.rewrite" level="finest"/>
    
    [1998/05/08 02:51:31.000] forward ^/foo: '/baz/test.jsp'  no match
    [1998/05/08 02:51:31.000] forward ^/bar: '/baz/test.jsp'  no match
    [1998/05/08 02:51:31.000] forward ^/baz: '/baz/test.jsp'  -->  '/hogwarts/test.jsp'
    

    Examples

    Redirect http:// requests to https:// requests

    The desired behaviour is to redirect plain connections to SSL connections.

    Desired behaviour
        http://anything.com/anything.html
          redirect => https://anything.com/anything.html
      
    Configuration
        <host ...>
          ...
          <rewrite-dispatch>
            <redirect regexp="^" target="https://${host.name}">
              <when secure="false"/>
            </redirect>
          </rewrite-dispatch>
          ...
        </host>
      

    Make an alias for a web-app

    The desired behaviour is to make it so that a web-app will match more than one url pattern. For example, a web-app is deployed in webapps/physics and available at http://hostname/physics/, the desired behaviour is to allow a request to http://hostname/classroom/physics to end up at the /physics web-app.

    Desired behaviour
        http://hostname/classroom/physics
          forward => http://hostname/physics 
    
        http://hostname/classroom/physics/anything
          forward => http://hostname/physics/anything
      

    The rewrite-dispatch tag is used at the <host> level. If it was placed in a <web-app> then it would be too late to forward to a different web-app because Resin would have already resolved the web-app.

    Configuration
        <host>
          <rewrite-dispatch>
            <forward regexp="^/classroom/physics" target="/physics"/>
          </rewrite-dispatch>
           ...
      

    Forward based on host name

    The desired behaviour is to internally forward requests based on the host name.

    Desired behaviour
        http://gryffindor.hogwarts.com/anything.html
          forward => /gryffindor/*
    
        http://slytherin.hogwarts.com/anything.html
          forward => /slytherin/anything.html
    
        http://hogwarts.com/anything.html
          forward => /anything.html
      

    The rewrite-dispatch tag is used at the <cluster> level. If it was placed in the <host> or the <web-app> then it would be too late to forward to a different host because Resin would have already resolved the host.

    Configuration
        <cluster>
          ...
          <rewrite-dispatch>
            <forward regexp="http://gryffindor\.[^/]+" target="/gryffindor/"/>
            <forward regexp="http://slytherin\.[^/]+" target="/slytherin/"/>
          </rewrite-dispatch>
          ...
        </cluster>
      

    Copyright © 1998-2010 Caucho Technology, Inc. All rights reserved.
    Resin ® is a registered trademark, and Quercustm, Ambertm, and Hessiantm are trademarks of Caucho Technology.