Re-mapping requests to / in ISAPI


As has already been shown in the introduction, ISAPI is a very powerful interface to the web server internals. In the following example, we provide some example code which shows how to provide a 'rewrite' facility for incoming URLs, in this case, mapping requests to '/' to another directory. This may be useful when using a Java Servlet for the top-level page, so that images can still be served from under /.

This is done by using an ISAPI filter, and attaching to the SF_NOTIFY_PREPROC_HEADERS callback event, as seen in the GetFilterVersion() function which is called on filter initialisation. Once registered, the main HttpFilterProc() function will be called for every incoming URL.

The GetHeader() function will retrieve the requested URL, and it is compared to '/'; if a match occurs, the header can be rewritten by calling SetHeader(). This simple 35 line program shows how easy it is to implement rewriting functionality, and since it runs as compiled code, it is the most efficient way to do so, placing very minimal overheads on the server.

/*!
 * Example 'mod_rewrite' functionality.
 *
 * This module shows how to make the frontpage of a web site be generated
 * by a Java Servlet.  
 * 
 * Normally Java Servlets are mounted under a URL prefix, such as '/jserv'.
 * However this means it is not directly possible to mount Java Servlets
 * directly under '/', since then a request for any url, such as
 * /images/bar.gif would get mapped onto a Java Servlet.
 *
 * This ISAPI filter rewrites requests for the frontpage '/' onto a Java
 * servlet mounted under '/jserv'. This means that requests for '/' 
 * transparently get mapped onto '/jserv/frontpage'.
 */

#include <httpfilt.h>
#include <string.h>


/*!
 * ISAPI run-time callback
 */

DWORD WINAPI 
HttpFilterProc( PHTTP_FILTER_CONTEXT pfc,
      DWORD notificationType,
      LPVOID notificationInfo )
{
   char url[1024];
   int i;
   PHTTP_FILTER_PREPROC_HEADERS tbl = notificationInfo;

   /* Retrieve the url asked for */
   if( tbl->GetHeader( pfc, "url", url, &i ) == TRUE &&
       !strcmp( url, "/" )) {
      /* It is a request for '/', 
       * Transparently rewrite this to '/jserv/SimpleServlet' */
      tbl->SetHeader( pfc, "url", "/jserv/SimpleServlet" );
   }

   return SF_STATUS_REQ_NEXT_NOTIFICATION;
}


/*!
 * ISAPI intialisation entry point
 */

BOOL WINAPI
GetFilterVersion( HTTP_FILTER_VERSION *ver )
{
   ver->dwFilterVersion = HTTP_FILTER_REVISION;
   strncpy( ver->lpszFilterDesc, "mod_rewrite example",
         SF_MAX_FILTER_DESC_LEN );
   /* We want to hook onto the pre-processing headers stage */
   ver->dwFlags = SF_NOTIFY_PREPROC_HEADERS;

   return TRUE;
}