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:
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.
|