Apache mod_rewrite: How to use a Java RewriteMap?

This example shows how to use a Java program as a RewriteMap in Apache Httpd server.

Prerequisites on the server box:

  1. Apache HTTPD 2.2x.
  2. JDK/JRE.

What does the program do ?

Allows all URLs of form “*/secure/” to go ahead, and reject others.

Java Program

Java program for the above is pretty simple – like the one displayed below.


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;

public class SimpleApacheMap
{
static String SECURED_URL = "/secured/";
static String SECUREDASSETS_FOLDER = "/assets/";
static String REJECT = "/rejected/";
BufferedReader inputReader;
OutputStreamWriter outputWriter;
boolean processed;

private void startMapper() throws IOException
{
String inputToken;
inputReader = new BufferedReader( new InputStreamReader(System.in));
outputWriter = new OutputStreamWriter(System.out);
while(true)
{
inputToken = inputReader.readLine();
if(inputToken!=null && inputToken.indexOf(SECURED_URL)>0)
{
outputWriter.write(inputToken.replace(SECURED_URL, SECUREDASSETS_FOLDER));
}else
{
outputWriter.write(REJECT);
}
outputWriter.flush();
}
}

public static void main(String s[]) throws Exception
{
new SimpleApacheMap().startMapper();
}
}

Jar file

Compile this program, create a jar file (java-apache-map.jar) from the compiled classes. (creating a jar simplifies the call to this program, especially so when complex mapping involving more dependency classes are done.) Add a manifest file pointing to the main class to make this jar runnable.

Paste this jar file in the “bin” folder in Apache root folder.

Create a file “map.sub.lock” in the bin folder. We will provide this file to Apache for using as a synchronization lock on our map program.

Edits in Httpd.conf

In the file httpd.conf, add the following lines –


#Define rewriteMap program and set a synchronization lock
RewriteMap forwardURL "prg:\"C:/Program Files/Java/jdk1.6.0_01/bin/java.exe\" -jar \"C:/Program Files/Apache Software Foundation/Apache2.2/bin/java-apache-map.jar\""
RewriteLock  bin/map.sub.lock

Note that we have to give the complete path to java.exe as well as the jar file having the map program. “forwardURL” is the name of our map so created.

Now append these line httpd.conf:


# Rewrite according to map output.
RewriteRule (.*) ${forwardURL:%1} [C]
RewriteRule (.*)/rejected/(.*) - [F]

The first line tells apache to replace all URLs with the value returned from the map. (the whole URL is passed to the map). The [C] flag makes sure that the next rewrite rule is executed too.
The second rewrite rule checks if the map had returned a URL having the text “/rejected/” in between- in which case a “Forbidden” message is sent back to the browser.

Restart Apache – The rewrites should be working fine now.

Additional tips on using a java map program –

  1. Any debug message can be printed to System.err stream. These messages would appear in [Apache-root]/logs/errors.log.
  2. The program is started as a daemon on server startup, and executes till shutdown/any critical error.
  3. As the program has life time of the server, instance variables defined in the map program has application life time too.
  4. Complex rewrite rules involving multiple requests can be easily implemented by giving a different prefix (to the key passed to the map) for each type of requests.

Eg. A login request could pass a key like login_<sessionId>, a logout request would similarly pass logout_<seesionId>, and the mapper program can update a database (using JDBC) the time taken by each session, or count active sessions, or act as an application-context etc etc.

Leave a Reply

Your email address will not be published. Required fields are marked *

*

* Copy This Password *

* Type Or Paste Password Here *

46,675 Spam Comments Blocked so far by Spam Free Wordpress

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>