Multi-language web site support (ISAPI filter)

Here is a simple example using an ISAPI filter to enable multi-language support. It is written in C.

/*
 * Multi-language support
 *
 * This ISAPI filter reads the 'Accept-Language:' HTTP header and tries
 * to serve a file in the corresponding language.
 * e.g. if language is 'fr', 'index.html' maps to 'index.fr.html'
 *
 */

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

/* This function is called when the filter is loaded by the web server */
BOOL WINAPI
GetFilterVersion( HTTP_FILTER_VERSION *pVer )
{
  /*  Set the filter version */
  pVer->dwFilterVersion = HTTP_FILTER_REVISION;
  /*  Set a description for the filter */
  strncpy( pVer->lpszFilterDesc, "Language Negotiation Filter",
	   SF_MAX_FILTER_DESC_LEN );
  /*  Ask to be notified when the URL has been mapped to a path name */
  pVer->dwFlags = SF_NOTIFY_SECURE_PORT |
    SF_NOTIFY_NONSECURE_PORT |
    SF_NOTIFY_URL_MAP;
  return TRUE;
}

#define PREAMBLE_LENGTH 22 /* length of "HTTP_ACCEPT_LANGUAGE" */

/*  This function is called for every HTTP request */
DWORD WINAPI
HttpFilterProc( PHTTP_FILTER_CONTEXT pfc,
		DWORD notificationType,
		VOID *pvNotification )
{
  HTTP_FILTER_URL_MAP *map = (HTTP_FILTER_URL_MAP *) pvNotification;
  char *lang, *nfile;
  char buffer[4096];
  int size = sizeof(buffer);

  /* Retrieve all available HTTP headers */
  pfc->GetServerVariable(pfc, "ALL_HTTP", buffer, &size);
  /* Find the 'Accept-Language:' header */
  lang = strstr(buffer, "HTTP_ACCEPT_LANGUAGE");

  if ( lang ) {
    /* We found the header */
    char *p;
    lang += PREAMBLE_LENGTH;      /* Skip "Accept Language: " */
    for(p=lang; isalpha(*p); p++) /* Skip letters */
      ;
    *p = '\0';                    /* Terminate after first language */

    /* Now look for a file with that language in the name */
    nfile = pfc->AllocMem( pfc,
			   1 + strlen( lang ) +
			   strlen( map->pszPhysicalPath ),
			   0 );
    p = strchr( map->pszPhysicalPath, '.' );

    if( p && nfile ) {
      /* Build up the new filename */
      struct stat st;
      int c = p - map->pszPhysicalPath + 1;
      memcpy( nfile, map->pszPhysicalPath, c);
      strcpy( nfile + c, lang );
      c += strlen( lang );
      strcpy( nfile + c, p );
      /* If the file exists, use it! */
      if( !stat( nfile, &st ) ) map->pszPhysicalPath = nfile;
    }
  }
  
  return SF_STATUS_REQ_NEXT_NOTIFICATION;
}
Content Manager [Administrator] 16 December 2005  Permalink  
Download Free Trial

Recent Articles

Other Resources



www.zeus.com