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 Bookmark with del.icio.us Post this article to Digg Post this article to reddit Post this article to Facebook Tweet this article  

Recently...

Other Resources