main website home
  • About this blog

    This blog features updates, opinions, and technical notes from Caucho engineers about Caucho products, the enterprise Java industry, and PHP. Caucho Technology is the creator of the Resin Application Server and the Quercus PHP in Java engine. A leader in Java performance since 1998, Caucho is a Sun JavaEE licensee with over 9000 customers worldwide.
  • Tags

    ajaxworld bam candi cdi cloud cluster comet configuration deploy devoxx eclipse ejb embedded flash flex google app engine hessian hmtp ioc java ee 6 javaone javazone jms messaging newsletter nyjug osgi php pomegranate quercus resin resin 4.0 REST servlet sfjug silicon valley code camp spring testing training tssjs watchdog webbeans web profile websockets wordpress
  • Meta

    • Register
    • Log in
    • Entries RSS
    • Comments RSS
    • WordPress.org
« Using Resin with Amazon EC2
Using PHP as a Spring MVC View via Quercus »

Resin 4.0 rewrite/dispatch

Because Resin 4.0 can now use Java Injection (JSR-299) for its configuration, we’ve taken advantage of the new syntax to redesign Resin’s rewrite and dispatch capabilities, used for sites migrating from Apache’s mod_rewrite module. The admin documentation is at http://caucho.com/resin/admin/rewrite.xtp and the JavaDoc for the tags is at com.caucho.rewrite (the JavaDoc describes the tags because Resin-rewrite uses Java Injection - JSR-299 for configuration.)

Rewrite matches HTTP URLs with a regular expression and dispatches them to servlets or load-balancing or HTTP proxies or HTTP redirects. PHP applications like MediaWiki and Drupal use rewriting to present pretty URLs to the world, but use /index.php internally.

For example, MediaWiki rewrites a URL like http://wiki.caucho.com/Rewrite to /index.php/Rewrite, but static files like /default.css, /image.gif, and /script.js are passed through as normal. In Resin 4.0, that configuration would have two rules: one for the pass-though files, and one for the index.php rewriting:

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

  <resin:Dispatch regexp="\.(php|js|gif|png|css|html)$"/>

  <resin:Dispatch regexp="^" target="/index.php"/>

</web-app>

The first matches static files and passes them to normal servlet processing. Because Resin’s dispatch is a first-match system, the pass-through matches and any following rules are ignored.

The second matches any other URL and rewrites them with an /index.php prefix. In Resin 4.0 rewriting, the tail of a regexp match is always appended to the target. (If the ‘target’ attribute produces a query string with ‘?’, the tail is joined with ‘&’ to make a valid query.)

Because is configured with Java Injection (JSR-299), the “Dispatch” is a Java class at com.caucho.rewrite.Dispatch and its JavaDoc can provide full documentation for the tag. If you want to create a custom dispatch rule, you just need to extend AbstractTargetDispatchRule and configure it exactly like Resin’s own dispatch rules. Your rules have the same power as Resin’s rules because they’re configured with the same Java Injection system.

Resin 4.0 provides a set of standard dispatch rules:

  • <resin:Dispatch> standard servlet/filter pass through
  • <resin:Redirect> HTTP redirect

  • <resin:Forbidden>
    HTTP forbidden response

  • <resin:Forward>
    servlet RequestDispatcher.forward

  • <resin:LoadBalance>
    Resin clustered load balancing

Conditional Matching

When you need a dispatch match to occur only for some requests, like SSL requests or requests with a certain HTTP header, or even time-based matches, you can use a conditional tag to restrict the match. For example, the following resin-web.xml redirects non-SSL requests:

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

  <resin:Redirect regexp="^" target="https://foo.com">
    <resin:Not>
       <resin:IfSecure/>
    <resin:Not>
  <resin:Redirect>

</web-app>

<resin:IfSecure> is a RequestPredicate which looks at the
servlet request object and returns true if request.isSecure() is true. Because <resin:Not> returns true if its child is false, it will return true for non-SSL requests. In other words, the <resin:Redirect> only executes for non-SSL requests.

Like the dispatch rules, the request predicates use standard Java Injection configuration, so you can easily create and configure new request predicates by implementing RequestPredicate. The JavaDoc for the predicate serves as the documentation for the XML configuration tag, e.g. in Resin’s com.caucho.rewrite.

Basic RequestPredicates

Resin 4.0 provides a set of basic RequestPredicates corresponding to the basic HttpServletRequest methods:

  • <resin:IfAuthType> checks request.getAuthType()
  • <resin:IfCookie> checks for a cookie and an optional value regexp
  • <resin:IfCron> checks if the current time is enabled or disabled
  • <resin:IfFileExists> checks if the getRealPath of the URL matches an actual file.
  • <resin:IfHeader> checks for a HTTP request header
  • <resin:IfNetwork> matches the remote IP address against network strings like 192.168/16
  • <resin:IfMethod> checks the HTTP method
  • <resin:IfQueryParam> checks the HTTP query string
  • <resin:IfSecure> checks if the request uses SSL secure, by request.isSecure()
  • <resin:IfUserInRole> checks if the user is logged-in as the request.isUserInRole()

Combining RequestPredicates

You can also combine conditions by using combining predicates like <resin:And>, <resin:Or>, and <resin:Not>.

  • <resin:And> matches if all the child predicates match.
  • <resin:Or> matches if any of the child predicates match.
  • <resin:Not> matches if the child predicate does not match.
  • <resin:NotAnd> matches if any of the children does not match.
  • <resin:NotOr> matches if none of the children match.

Filters (SetHeader)

Resin’s rewriting can add servlet filters to the request, adding HTTP response headers, or setting request attributes or wrapping with a standard servlet filter. The rewriting filters can be children of <resin:Dispatch> or be top-level tags like <resin:SetHeader>. A typical example might be to set the HTTP Vary tag when using a conditional or setting caching configuration.

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

  <resin:Dispatch regexp="^/admin" target="/secure">
    <resin:IsUserInRole role="admin"/>
    <resin:AddHeader name="Cache-Control" value="no-cache"/>
  </resin:Dispatch>

  <resin:Location regexp="\.png">
    <resin:AddHeader name="Cache-Control" value="max-age=120"/>
  </resin:Location>

</web-app>

You can also instantiate your own standard servlet filters using Java Injection syntax in a RewriteFilter or a DispatchRule. Your Filter must be configurable by Java Injection (JSR-299) syntax, in addition to its usual init-param configuration.

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

  <resin:Dispatch regexp="^/path">
    <foo:MyFilter>
       <foo:myParam>myValue</foo:myParam>
    <foo:MyFilter>
  </resin:Dispatch>

</web-app>

Tags: ioc, resin 4.0, rewrite

This entry was posted on Wednesday, April 8th, 2009 at 9:15 pm and is filed under Engineering. You can follow any responses to this entry through the RSS 2.0 feed. You can leave a response, or trackback from your own site.

2 Responses to “Resin 4.0 rewrite/dispatch”

  1. stbu Says:
    May 29th, 2009 at 1:30 am

    I’m actually using Resin 3.1, but tried a test case on Resin 4.0.
    In 3.1 I was able to use to send a 301 with the new location to the browser. How can this be achieved with 4.0?

    When using then a 302 is used:

    HTTP/1.x 302 Found
    Server: Resin/4.0.0

  2. stbu Says:
    May 29th, 2009 at 1:47 am

    Unfortunately, the tags have been removed instead of escaped for HTML.
    Next try:

    Im actually using Resin 3.1, but tried a test case on Resin 4.0.
    In 3.1 I was able to use <moved-permanently> to send a 301 with the new location to the browser. How can this be achieved with 4.0?

    When using <resin:Redirect> then a 302 is used:

    HTTP/1.x 302 Found
    Server: Resin/4.0.0

    BTW: Is there any possibility to remove query parameters in case of a redirect?
    e.g. when rewriting “^/foo.jsp” to target “/bar.jsp”
    the request too host:port/foo.jsp?p1=val1 the redirect will be host:port/bar.jsp?p1=val1. How can I get just host:port/bar.jsp without query parameters?

    Thanks, Steffen

Leave a Reply

You must be logged in to post a comment.


Caucho Technology is proudly powered by WordPress and Quercus®
Entries (RSS) and Comments (RSS).

  • HOME |
  • CONTACT US |
  • DOCUMENTATION |
  • BLOG |
  • WIKI 4 |
  • WIKI 3 |
  • Resin: Java Application Server
Copyright (c) 1998-2012 Caucho Technology, Inc. All rights reserved.
caucho® , resin® and quercus® are registered trademarks of Caucho Technology, Inc.
resin® is a cloud optimized, java® application server that supports the java ee webprofile ®