Transparently mapping requests from one URL to another (ISAPI filter)

Here is a simple example using an ISAPI filter to show how to make the frontpage of a website be generated by a Java Servlet. It is written in C.

/*
 * Map 'www.isp.com/USER' to 'www.USER.isp.com'
 *
 * This ISAPI filter shows how to transparently map requests for
 * 'http://www.myisp.com/user/page' to
 * 'http://www.user.myisp.com/page'
 *
 * This is designed for ISPs wanting to migrate from legacy hosting systems
 * to Zeus's support for subservers, allowing mass-hosting customers to have
 * their own domain.  This works extremely well with BIND 8.x's support for
 * wildcarded DNS, i.e. you setup a single DNS record for
 * www.*.myisp.com -> * IP address.
 *
 */

/* Include ISAPI definitions and constants */
#include <httpfilt.h>
#include <string.h>

static char* HOSTINGDOMAIN = "hosting.myisp.com";   /* New hosting domain */
static char* HOLDPAGE      = "myisp.net";           /* Where to send bad URLs */

/* This function is called when the filter is loaded by the web server */
BOOL WINAPI
GetFilterVersion( HTTP_FILTER_VERSION *ver )
{
  /*  Set the filter version */
  ver->dwFilterVersion = HTTP_FILTER_REVISION;
  /*  Set a description string for the filter */
  strncpy( ver->lpszFilterDesc, "Map www.isp.com/USER/ to www.USER.isp.com/",
	   SF_MAX_FILTER_DESC_LEN );
  /*  We want to hook onto the pre-processing headers stage */
  ver->dwFlags = SF_NOTIFY_PREPROC_HEADERS;

  return TRUE;
}

/*  This function is called for every HTTP request */
DWORD WINAPI
HttpFilterProc( PHTTP_FILTER_CONTEXT pfc,
		DWORD notificationType,
		LPVOID notificationInfo )
{
  char url[1024];
  char dest[1024+128], *p;
  int i;
  PHTTP_FILTER_PREPROC_HEADERS tbl
    = (PHTTP_FILTER_PREPROC_HEADERS) notificationInfo;

  /*  This is the header we will use to redirect the client */
  memcpy( dest, "Location: http://www.", 21 );
  p = dest + 21;

  /* Retrieve the URL asked for */
  if( tbl->GetHeader( pfc, "url", url, &i ) == TRUE ) {
    /* Set up new destination */
    char* u = url;
    while( *u == '/' )
      u++;                                       /* Strip off leading '/' */
    if( !*u ) {
      /* No username given, send hold-page */
      strcpy( p, HOLDPAGE );
    } else {
      while( *u && *u != '/' ) *p++ = *u++;      /* Copy over user name */
      *p++ = '.';                                /* Add '.' */
      strcpy( p, HOSTINGDOMAIN );                /* Add new hosting domain */
      p += strlen( HOSTINGDOMAIN );
      strcpy( p, u );                            /* Add rest of URL */
    }
  } else {
    /* Couldn't read URL header -- just redirect to ISP front-page */
    strcpy( p, HOLDPAGE );
  }

  /* Redirect to new destination */
  pfc->ServerSupportFunction( pfc, SF_REQ_SEND_RESPONSE_HEADER,
			      "302", (LPDWORD) dest, 0 );
  
  i = 0;
  pfc->WriteClient( pfc, "", &i, 0 );

  /* Instruct web server not to process this request any further */
  return SF_STATUS_REQ_FINISHED;
}
Content Manager [Administrator] 16 December 2005  Permalink  
Download Free Trial

Recent Articles

Other Resources



www.zeus.com