HttpRedirectFilter

HttpRedirectFilter is a servlet which implements javax.servlet.Filter interface. It inspects the URL of a HTTP request and either forwards the request to a different location, or redirects the user agent to a new URL. It can be used as a general redirector on a servlet container such as Apache Tomcat.

Introduction

What do I mean by 'HTTP redirect'? See, every resource on the web has an unique identifier called URL. This identifier represents the location of the resource. When resource is moved to a new location, the URL changes. However, the old URL should remain valid, at least for a time. Other web-sites, search engine databases, even manuals for certain products contain the old URL. We want a smooth change, so we continue to serve the resource through the old URL, along with the new, in order to prevent all the links from breaking at once.

User agents (browsers) are informed about the change in the URL through HTTP status codes. When an user agent requests a resource which has been moved, the server can do one of the following:

Forward: The server reads the resource from the new location and delivers it to the user agent. The user agent will never know this has happened. The change in the URL is internal to the server and the new URL isn't known to the public.

Redirect temporarily: The server returns the 302 status code to the user agent indicating that the resource is temporarily available at a new URL, which is returned in the response header Location. It is up to the user agent to issue a new HTTP request using the new URL and that is what most browsers do. The saved links, such as bookmarks, should however keep pointing to the old URL because the URL change is considered temporary.

Redirect permanently: The server returns a 301 status code to the user agent indicating that the resource has permanently moved to a new URL, which is returned in the response header Location. It is up to the user agent to issue a new HTTP request using the new URL. Most browsers do exactly this. The saved links, such as bookmarks, should be modified to point to the new URL, as the old one is expected to stop working in the future.

Pristine Tomcat, as distributed by Apache, does not offer any means to do the above. If you want Tomcat to redirect, you must program this functionality in Java. HttpRedirectFilter is the result of such an attempt.

Installing The Filter

RedirectFilter version 2.x requires Java runtime environment version 1.6.0 or above. If your Java runtime ticks in a lower version, forget it and use HttpRedirectFilter 1.x instead.

The filter is distributed in a single JAR which should be placed in the web application's WEB-INF/lib directory. The JAR archive can be found here. It contains the source code, binaries and a sample configuration file.

The web application descriptor file must be modified, so that the container starts employing the filter. You can tell the container that the new filter exists by declaring it in your WEB-INF/web.xml file. The filter declaration must pass at least one parameter to the filter, namely the path to its configuration file, relative to the root of the web application. Here is an example:

For version 2.x:
<filter>
 <filter-name>HttpRedirectFilter</filter-name>
 <filter-class>com.zlatkovic.servlet.RedirectFilter</filter-class>
 <init-param>
  <param-name>configFile</param-name>
  <param-value>/WEB-INF/redirect-filter.xml</param-value>
 </init-param>
 <init-param>
  <param-name>reloadConfig</param-name>
  <param-value>false</param-value>
 </init-param>
 <init-param>
  <param-name>logRedirects</param-name>
  <param-value>false</param-value>
 </init-param>
</filter>

For version 1.x:
<filter>
 <filter-name>HttpRedirectFilter</filter-name>
 <filter-class>com.zlatkovic.HttpRedirectFilter</filter-class>
 <init-param>
  <param-name>configFile</param-name>
  <param-value>/WEB-INF/httpredirectfilter.xml</param-value>
 </init-param>
 <init-param>
  <param-name>reloadConfig</param-name>
  <param-value>false</param-value>
 </init-param>
 <init-param>
  <param-name>logRedirects</param-name>
  <param-value>false</param-value>
 </init-param>
</filter>

To tell the container to let this filter process every request, the following filter mapping must be added to WEB-INF/web.xml as well:

<filter-mapping>
 <filter-name>HttpRedirectFilter</filter-name>
 <url-pattern>/*</url-pattern>
</filter-mapping>

The filter should now be installed and operational. It will however do nothing until it has been configured.

Configuring The Filter

The configuration file you must create and place it where the configFile filter parameter from the previous section points to. This is a XML file and the document type in the current version is:

For version 2.x:
<!DOCTYPE redirect-filter PUBLIC
 "-//zlatkovic.com//DTD RedirectFilter 2.0//EN"
 "http://www.zlatkovic.com/dtd/redirect-filter-2.0.dtd">

For version 1.x:
<!DOCTYPE http-redirect-filter PUBLIC
 "-//zlatkovic.com//DTD HttpRedirectFilter 1.2//EN"
 "http://www.zlatkovic.com/dtd/httpredirectfilter-12.dtd">

You can take a glance at the DTD mentioned above for full details about the syntax. The comments in there will tell you which elements are allowed and which attributes they can have. The filter won't validate the configuration file, so you can omit the document type declaration from the configuration file.

Basically, the root element is called redirect-filter (http-redirect-filter for versions 1.x) and there are two instructions you might place within it. Here is an example of both:

For version 2.x:
<redirect-filter>
 <forward match="^/someplace$" target="/otherplace"/>
 <redirect match="^/someplace$" target="/otherplace"/>
</redirect-filter>

For version 1.x:
<http-redirect-filter>
 <forward match="^/someplace$" target="/otherplace"/>
 <redirect match="^/someplace$" target="/otherplace"/>
</http-redirect-filter>

Both instructions will match a request URL against a regular expression found in the match attribute. If it matches, the forward instruction will serve the resource from the URL specified in the target attribute, while the redirect instruction will return the target URL back to the user agent along with the 302 status code.

The redirect instruction can have a permanent attribute which returns the 301 status code instead:

<redirect match="^/someplace$" target="/otherplace"
  permanent="yes"/>

Both instructions support regular expression matching groups, which can be inserted into the target URL. For example, the following instruction

<redirect match="^/someplace(.*)$" target="/otherplace$1"/>

will replace the $1 in the target URL by whatever matched the first (.*) in the regular expression. Similarily, a $2 would be replaced by whatever matched the second (.*), and so on.

There is an attribute entire-url which causes the whole URL the client specified to be checked against the regular expression in the match attribute. The whole URL will be constructed to include the protocol, the host and any request parameters. For example, if the client sends the following request

GET /someplace?a=b&c=d HTTP/1.1
Host: localhost

the filter will normally check the string /someplace against the regular expression in the match attribute. If the attribute entire-url is set, it will check the string http://localhost/someplace?a=b&c=d instead. This allows you to pass the request parameters on to the target by using the regular expression matching groups. However, this will only work if the client uses the HTTP GET method. If the client uses any other method, the attribute entire-url will be ignored for practical reasons.

The redirection rules can be restricted to a specific network interface of your server and/or to a specific IP address of the client. Here is an example:

<redirect match="^/someplace$" target="/otherplace"
  local-address="192.168.34.56"
  remote-address="10.12.23.34/255.0.0.0"/>

If the attribute local-address is set to the IP address of your server, the redirection will occur only if the HTTP request came to the network card with that IP address. This is, of course, only useful if your server has more than one network interface. The remote-address attribute can be set to a specific subnet and if so done, the redirection will only occur if the HTTP request came from that subnet. This allow you to redirect to a different place, depending on who visits your site.

If the init parameter reloadConfig in your WEB-INF/web.xml file is set to true, then you can instruct the filter to reload its configuration file without restarting the web application. For this, assuming you server is running on localhost, you can use your browser to call the following URL:

For version 2.x:
http://localhost/redirect-filter?c=reload

For version 1.x:
http://localhost/http-redirect-filter?c=reload

If the configuration was successfully reloaded, the filter will tell you so. If something goes amiss, the filter will throw an exception. If the init parameter reloadConfig is set to false, or not specified at all, the above request URL will be treated just like any other. This is useful while in development, to test different configurations without having to restart the web application all the time. I suggest keeping this off in production, unless you like having people all over the world reloading your filter configuration all the time.

If the init parameter logRedirects in your WEB-INF/web.xml file is set to true, then the filter will log all redirections via a servlet-specific log channel. If the init parameter logRedirects is set to false, or not specified at all, the filter will log the mere act of loading the redirection rules but not the actual redirections. This is useful for debugging your configuration. It isn't of much use in production.

Support

This thing is so small and simple that you shouldn't need any support with it. If you have something you cannot keep, I'll be hearing. See the contact information for info about the means that I have for receiving inquiries.

Contributors

For help, suggestions and patches to this software, I would like to express my sincerest thanks to the following people:

  • Luke Gilbert
  • Paul Nardone

Thanks, folks, I am in your debt for all times that may come. Without you, I would never be able to present this the way it is.

Licence

HttpRedirectFilter is free. It is distributed under the terms of the zlatkovic.com Public Licence which you can read here. The terms of use for this website may be of interest too.

Contents:
Introduction
Installing The Filter
Configuring The Filter
Support
Contributors
Licence
Download:
Source and binary (HTTP)
Source and binary (FTP)
© 2000-2007 Igor Zlatković. All rights reserved. Last modification: Tue, 16 Oct 2007 01:30:00 GMT+02:00
Comments? Questions? Please tell us about it.