Caucho maker of Resin Server | Application Server (Java EE Certified) and Web Server


 

Resin Documentation

home company blog docs 
app server 
 Resin Server | Application Server (Java EE Certified) and Web Server
 

url rewriting and dispatching


Resin comes with powerful and extensible rewrite capabilities that is as powerful as Apache's mod_rewrite.

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 that accepts Java regular expressions. 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

Dispatching can be more complicated than just on a regular expression matching of the URL. It may depend on request attributes. In the example below, Resin will send a 403 Forbidden response if the URL path starts with /secret AND the child condition evaluates to true. In this case, the condition <resin:IfSecure> succeeds if the request is not an SSL request.

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 (<resin:IfUserInRole>), the remote IP (<resin:IfNetwork>), check for SSL (<resin:IfSecure>), and check for activation time (<resin:IfCron>) or if a file exists (<resin:IfFileExists>).

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

Combining Conditions

An action tag can have zero condition tags or at most one. If you want combine multiple conditions, then you'll need to use composite conditions like <resin:And>, <resin:Or>, <resin:Not>, <resin:NotAnd>, and <resin:NotOr>.

Example: send 403 Forbidden if port is 80 and user is not admin
<web-app xmlns="http://caucho.com/ns/resin"
            xmlns:resin="urn:java:com.caucho.resin">

  <resin:Forbidden regexp="^/secret">
    <resin:And>
      <resin:IfLocalPort value="80"/>
      <resin:Not>
        <resin:IfUserInRole role="admin"/>
      </resin:Not>
    </resin:And>
  </resin:Forbidden>
	    
</web-app>

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: set header Foo: bar
<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: dispatching with a custom filter
<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>

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.

Example: 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
Example: resin.xml configuration
<resin xmlns="http://caucho.com/ns/resin"
    xmlns:resin="urn:java:com.caucho.resin">
    
  <cluster ...>
  <host ...>
    ...
    <resin:Redirect regexp="^" target="https://${host.name}">
      <resin:IfSecure value="false"/>
    </resin:Redirect>
    ...
  </host>
</resin>

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.

Example: resin.xml configuration
<resin xmlns="http://caucho.com/ns/resin"
  xmlns:resin="urn:java:com.caucho.resin">

<cluster id="">
<host id="">

  <resin:Forward regexp="^/classroom/physics" target="/physics"/>

Forward based on host name

The desired behaviour is to forward requests internally 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.

Example: resin.xml Configuration
<resin xmlns="http://caucho.com/ns/resin"
    xmlns:resin="urn:java:com.caucho.resin">
    
  <cluster>
      ...
    <resin:Forward regexp="http://gryffindor\.[^/]+" target="/gryffindor/"/>
    <resin:Forward regexp="http://slytherin\.[^/]+" target="/slytherin/"/>
   ...
</cluster>
</resin>
  

Proxy requests to PHP/Ruby using FastCGI

<web-app xmlns="http://caucho.com/ns/resin"
         xmlns:resin="urn:java:com.caucho.resin">

   <resin:FastCgiProxy regexp="\.php$">
     <address>127.0.0.1:12345</address>
   </resin:FastCgiProxy>
   
   <resin:FastCgiProxy regexp="\.rb$">
     <address>127.0.0.1:67890</address>
   </resin:FastCgiProxy>

</web-app>

Tag listing by function

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:MovedPermanently>Send a HTTP redirect to a new URL specified by target.
<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: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:SetRequestCharacterEncoding>Sets the character encoding of the request parameters.
<resin:SetRequestSecure>Marks the request as secure.
<resin:SetVary>Sets the Vary header.
<mypkg:MyFilter>Regular Servlet filters can be used as rewrite filters.

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