ISAPI Reference

Types

The ISAPI specification was originally designed on Windows platforms, and hence a lot of the type and naming conventions may be unfamiliar to Unix programmers.

On Unix platforms we provide a header file wintypes.h that defines several of these types for compatibility with the specification.

typedef int            BOOL;
typedef char*          LPSTR;
typedef const char *   LPCSTR;
typedef void*          LPVOID;
typedef void*          PVOID;
typedef void           VOID;
typedef int*           LPDWORD;
typedef int            DWORD;
typedef char           CHAR;
typedef unsigned char* LPBYTE;
typedef short          WORD;
typedef char           BYTE;
typedef long           LONG;
The LP prefix is an abbreviation for "Long-Pointer" and dates back to the days of 16-bit memory models under MS-DOS!

Extensions

An Extension module MUST export two functions. These functions must contain the WINAPI modifier on Windows platforms. Note that if you are writing a module in C++, you should also use the extern "C" modifier to tell the compiler to use C calling conventions for that function. The two functions an extension must provide are:
BOOL WINAPI GetExtensionVersion( HSE_VERSION_INFO *Ver )
Where the HSE_VERSION_INFO structure is defined as:
typedef struct  _HSE_VERSION_INFO {
   DWORD  dwExtensionVersion;
   CHAR   lpszExtensionDesc[ HSE_MAX_EXT_DLL_NAME_LEN ];
} HSE_VERSION_INFO, *LPHSE_VERSION_INFO;
The dwExtensionVersion number contains the version of the ISAPI specification that the module expects the server to support.

The module should fill in the description buffer with a textual description of the module. The function should return TRUE on success.

The other function the module must export is:

DWORD WINAPI HttpExtensionProc( LPEXTENSION_CONTROL_BLOCK ecb )
The ExtensionControlBlock structure contains data about the connection as well as callback functions allowing the module to get more information and perform various actions.

typedef struct _EXTENSION_CONTROL_BLOCK {
   DWORD     cbSize;                 /* Size of this struct. */
   DWORD     dwVersion;              /* Version info of this spec */
   HCONN     ConnID;                 /* Context number not to be modified! */
   DWORD     dwHttpStatusCode;       /* HTTP Status code */
   
   /* null terminated log info specific to this Extension DLL */
   CHAR lpszLogData[HSE_LOG_BUFFER_LEN];

   LPCSTR    lpszMethod;             /* REQUEST_METHOD */
   LPCSTR    lpszQueryString;        /* QUERY_STRING */
   LPCSTR    lpszPathInfo;           /* PATH_INFO */
   LPCSTR    lpszPathTranslated;     /* PATH_TRANSLATED */

   DWORD     cbTotalBytes;           /* Total bytes indicated from client */
   DWORD     cbAvailable;            /* Available number of bytes */
   LPBYTE    lpbData;                /* Pointer to cbAvailable bytes */
   
   LPCSTR    lpszContentType;        /* Content type of client data */
   
   BOOL (WINAPI * GetServerVariable) ( HCONN       hConn,
				       LPSTR       lpszVariableName,
				       LPVOID      lpvBuffer,
				       LPDWORD     lpdwSizeofBuffer );
   
   BOOL (WINAPI * WriteClient)  ( HCONN      ConnID,
				  LPVOID     Buffer,
				  LPDWORD    lpdwBytes,
				  DWORD      dwReserved );
   
   BOOL (WINAPI * ReadClient)  ( HCONN      ConnID,
				 LPVOID     lpvBuffer,
				 LPDWORD    lpdwSize );
   
   BOOL (WINAPI * ServerSupportFunction)( HCONN      hConn,
					  DWORD      dwHSERRequest,
					  LPVOID     lpvBuffer,
					  LPDWORD    lpdwSize,
					  LPDWORD    lpdwDataType );

} EXTENSION_CONTROL_BLOCK, *LPEXTENSION_CONTROL_BLOCK;

The functions provided by the Extension Control Block are described in detail below.

Modules can optionally export a third function, which gets called when the module is about to be unloaded. This allows the module to free any memory it has allocated, or clear up any background threads.

BOOL  WINAPI   TerminateExtension( DWORD dwFlags );
Where dwFlags is a bitfield consisting of the following values:

ValueMeaning
HSE_TERM_ADVISORY_UNLOAD The server wants to unload the extension. The extension can return TRUE if OK, or FALSE if the server should not unload the extension.
HSE_TERM_MUST_UNLOAD The server is indicating the extension is about to be unloaded, the extension cannot refuse.


BOOL GetServerVariable( HCONN ConnID, LPSTR VariableName, 
                        LPVOID Bufffer, LPDWORD SizeofBuffer )
Arguments:
Conn:
The connection ID as given in the extension control block
VariableName:
A text string giving the name of the HTTP variable requested.
Buffer:
A buffer into which the value of the variable is placed
SizeofBuffer:
This should be the size of the buffer pointer to by Buffer on calling. On return, this will be set to the length of the filled in value, including the zero terminator.
The following variables are supported:

Variable NameDescription
AUTH_TYPE The HTTP authentication method. e.g. "Basic"
CONTENT_LENGTH The length of the request body data on a POST or PUT
CONTENT_TYPE The mime-type of the request body data
COOKIE The client's cookie
DOCUMENT_ARGS The parent document's QUERY_STRING. Identical to QUERY_STRING unless this is a subrequest from a SSI document.
DOCUMENT_PATH_INFO The parent document's PATH_INFO. Identical to PATH_INFO unless this is a subrequest from a SSI document.
DOCUMENT_URI The parent document's URL. Identical to URL unless this is a subrequest from a SSI document.
GATEWAY_INTERFACE The CGI interface version supported by the server
PATH_INFO Additional path information after the script name.
PATH_TRANSLATED The PATH_INFO mapped into a physical filename
QUERY_STRING Information following the '?' in the URL
REQUEST_METHOD The HTTP method, e.g. GET
REMOTE_HOST The remote host name, e.g. foo.bar.com
REMOTE_USER The user name, if authenticated.
HTTP_ACCEPT The accept lines sent by the client.
SERVER_PORT The port the server is running on
SERVER_NAME The IP name of the web server
HTTP_REFERER The referring page, as sent by the browser
HTTP_USER_AGENT The name of the client (browser) software.
REMOTE_ADDR The IP address of the client
SCRIPT_NAME The name of the API extension being run.
SERVER_SOFTWARE The name of the web server software.
SERVER_PROTOCOL The HTTP version supported by the server. e.g. HTTP/1.0
ALL_HTTP All other HTTP request headers. These variables are of the form HTTP_
. The headers consist of a null-terminated string with the individual headers separated by line feeds.
SERVER_PORT_SECURE If the request was over a secure port, this value is set to "1", otherwise "0".
URL The URL.
VSERVER_NAME The administrative name of the virtual server. Zeus specification extension


BOOL (WINAPI * WriteClient)  ( HCONN ConnID, LPVOID Buffer,
                               LPDWORD Bytes, DWORD Reserved );
Write out data to the client.

Arguments:

ConnID
The connection ID as given in the ExtensionControlBlock.
Buffer
A pointer to a buffer containing the data to be written to the client
Bytes
On calling, this should point to an integer representing the number of bytes to be written. On return, it will contain the number of bytes that were read out to the client.
Return Value:
The function returns TRUE if successful, or FALSE if an error occurred.


BOOL (WINAPI * ReadClient)  ( HCONN ConnID, LPVOID Buffer,
                              LPDWORD Size );
Read data from the client.

Arguments:

ConnID
The connection ID as given in the ExtensionControlBlock.
Buffer
A buffer into which the data should be read.
Size
On calling this should be set to the size of Buffer in bytes. On return it will be set to the number of bytes actually read and copies into Buffer.
Return Value:
The function returns TRUE if successful, or FALSE if an error occurred.


BOOL (WINAPI * ServerSupportFunction)( HCONN   ConnID,
                                       DWORD   Request,
                                       LPVOID  Buffer,
                                       LPDWORD Size,
                                       LPDWORD DataType );
Request can be one of the following:
HSE_REQ_SEND_URL_REDIRECT_RESP
Request that the server send a 302 Redirect HTTP response code. The Buffer variable should point to a null-terminated string containing the URL to redirect to. Size should contain the length of that string. The DataType argument is ignored.
HSE_REQ_SEND_URL
Under the Zeus Server, this is identical to HSE_REQ_SEND_URL_REDIRECT_RESP
HSE_REQ_SEND_RESPONSE_HEADER
This sends a complete HTTP server response header including the status, server version, message time, and MIME version. The Buffer variable can contain the HTTP status code and message (such as "200 OK"). The DataType pointer should point to null terminated buffer containing additional headers to send to the client. If Size is non-zero, this will be used to size the DataType string, otherwise, the server expects the string to be null terminated.
HSE_REQ_SEND_RESPONSE_HEADER_EX
This is an improved version of HSE_REQ_SEND_RESPONSE_HEADER. It uses the following datastructure to pass data to ServerSupportFunction(): typedef struct _HSE_SEND_HEADER_EX_INFO { LPCSTR pszStatus; /* HTTP status code; for example "200 OK". */ LPCSTR pszHeader; /* HTTP header */ DWORD cchStatus; /* Number of characters in status code */ DWORD cchHeader; /* Number of characters in header */ BOOL fKeepConn; /* Keep client connection alive ? */ } HSE_SEND_HEADER_EX_INFO, *LPHSE_SEND_HEADER_EX_INFO; You can then pass a pointer to this data structure in lpvBuffer.
HSE_REQ_MAP_URL_TO_PATH
Request that the server map a logical path onto a physical path on the filesystem. The Buffer parameter should point to a buffer that on entry contains the logical path, and on return will contain the physical path. When calling the function, the Size parameter should contain the size of the buffer. On return, it will contain the number of bytes placed in the buffer. The DataType parameter is ignored.
HSE_REQ_GET_FILE_DESCRIPTOR (Zeus specification extension)
Allows the ISAPI extension to get hold of the raw filedescriptor of the client's socket. For example, this might be used to perform an identd lookup on the client. On entry, the Buffer should be a pointry to a DWORD, and on return will contain the file descriptor. The Size parameter should contain the size of the buffer.
HSE_REQ_ALLOC_MEM (Zeus specification extension)
This function allocates memory in a per-connection memory pool. The memory will get freed automatically by the server then the connection is finished.

On entry, Size points to a buffer containing the number of bytes of memory to allocate.
On exit, if the return code is TRUE, Buffer will contain a pointer to the allocated memory, else if the return code is FALSE the memory allocation failed.

For example:

HSE_REQ_TRANSMIT_FILE
Provides a very high-performance mechanism for sending a file (or a portion of a file) to the client, with an optional header or footer. HSE_REQ_TRANSMIT_FILE will send the file directly from the webserver's internal cache, and is the recommended way of sending content back to the client for scenarios requiring high-performance.

The Buffer variable should point to a HSE_TF_INFO object described below. Size and DataType parameters are ignored.

The following information is an extract from the httpext.h headerfile.

/* HSE_TF_INFO defines the type for HTTP SERVER EXTENSION support for ISAPI applications to send files using 'TransmitFile' or its equivalent. A pointer to this object shoudl be used with ServerSupportFunction() for HSE_REQ_TRANSMIT_FILE */ typedef struct _HSE_TF_INFO { /* Callback and context information the calllback function will be called when IO is completed. the context specified will be used during such as callback. These values (if non-NULL) will override the one set by calling ServerSupportFunction() with HSE_REQ_IO_COMPLETION. Note: In Zeus Server, all async IO is completed immediately, no callback routines will be called, callbacks should not be used. Any routine requiring a callback will return failure. Because of this, all data segments passed to write out should be valid for the life time of the connection (e.g. allocated in AllocMem memory). */ PFN_HSE_IO_COMPLETION pfnHseIO; PVOID pContext; /* File handle (or Zeus Extension, pointer to a zero-terminated filename, if dwFlags has HSE_IO_HANDLE_IS_FILENAME is set) */ HANDLE hFile; /* HTTP header and status code These fields are used only if HSE_IO_SEND_HEADERS is present in dwFlags */ LPCSTR pszStatusCode; /* HTTP status code, eg. "200 OK" */ DWORD BytesToWrite; /* special value of "0" means write entire file */ DWORD Offset; /* offset value within the file to start from */ PVOID pHead; /* Head buffer to be sent before file data */ DWORD HeadLength; /* header length */ PVOID pTail; /* Tail buffer to be sent after file data */ DWORD TailLength; /* Tail length */ DWORD dwFlags; /* includes HSE_IO_DISCONNECT_AFTER_SEND ... */ } HSE_TF_INFO, *LPHSE_TF_INFO; /* flags for IO Functions, support for IO Funcs TF means ServerSupportFunction( HSE_REQ_TRANSMIT_FILE ) */ #define HSE_IO_SYNC 0x00000001 // for WriteClient #define HSE_IO_ASYNC 0x00000002 // for WriteClient/TF #define HSE_IO_DISCONNECT_AFTER_SEND 0x00000004 // for TF #define HSE_IO_SEND_HEADERS 0x00000008 // for TF /* Zeus extension, marks Handle as a zero-terminated filename, rather than a filehandle */ #define HSE_IO_HANDLE_IS_FILENAME 0x01000000 // for TF

For most efficient operation:

  1. Use HSE_IO_SEND_HEADERS to send the headers in the same call as the HSE_REQ_TRANSMIT_FILE call.
  2. If you are providing the entire response to this query, and are not going to be doing subsequent calls to WriteClient(), set the HSE_IO_DISCONNECT_AFTER_SEND flag.

    This flag notifies the webserver that is has enough information to generate the entire response, and when coupled with the HSE_IO_SEND_HEADERS flag, it will cause the webserver to automatically insert a 'Content-Length' header in the response and negotiate a HTTP/1.1 keep-alive response with the client.

Sample usage:

/* Sample extension that demonstrates use of HSE_REQ_TRANSMIT_FILE */ #include <string.h> #include <stdio.h> #include "httpext.h" #define Success 0 #define Failure -1 static int run( LPEXTENSION_CONTROL_BLOCK ); // ---------------------------------------------------------- BOOL WINAPI GetExtensionVersion( HSE_VERSION_INFO *pVer ) { pVer->dwExtensionVersion = 1; strncpy( pVer->lpszExtensionDesc, "Transmitfile test", HSE_MAX_EXT_DLL_NAME_LEN ); return 1; } // ---------------------------------------------------------- DWORD WINAPI HttpExtensionProc( LPEXTENSION_CONTROL_BLOCK ecb ) { if( run( ecb ) == Failure ) return HSE_STATUS_ERROR; return HSE_STATUS_SUCCESS_AND_KEEP_CONN; } // ---------------------------------------------------------- static void WriteHeader( LPEXTENSION_CONTROL_BLOCK ecb, const char* a ) { DWORD sz = strlen( a ); ecb->ServerSupportFunction( ecb->ConnID, HSE_REQ_SEND_RESPONSE_HEADER, 0, &sz, (DWORD*)a ); } // ---------------------------------------------------------- static void Output( LPEXTENSION_CONTROL_BLOCK ecb, const char* a ) { DWORD l = strlen( a ); ecb->WriteClient( ecb->ConnID, (void*)a, &l, 0 ); } // ---------------------------------------------------------- static int run( LPEXTENSION_CONTROL_BLOCK ecb ) { static int headerlen = 0; static int trailerlen = 0; static const char* header = "This is my header\n"; static const char* trailer = "This is my trailer\n"; const char* filename = "/etc/passwd"; HSE_TF_INFO tf; // one-time initalisation if( headerlen == 0 ) headerlen = strlen( header ); if( trailerlen == 0 ) trailerlen = strlen( trailer ); tf.pfnHseIO = 0; /* these must be 0 for Zeus */ tf.pContext = 0; tf.hFile = (HANDLE)filename; tf.pszStatusCode = "200 OK\nContent-Type: text/plain\nFoo: bar"; tf.BytesToWrite = 0; /* write all of file - could specify a portion of */ tf.Offset = 0; /* the file to send here */ tf.pHead = (PVOID)header; tf.HeadLength = headerlen; tf.pTail = (PVOID)trailer; tf.TailLength = trailerlen; // Because we are not going to be sending any more data after this, // we set HSE_IO_DISCONNECT_AFTER_SEND to let the webserver know, and // because we are also generating headers, we can use this information // to insert a Content-Length & hence use HTTP KeepAlive for better // performance. tf.dwFlags = HSE_IO_SEND_HEADERS | HSE_IO_DISCONNECT_AFTER_SEND | HSE_IO_HANDLE_IS_FILENAME; if( ecb->ServerSupportFunction( ecb->ConnID, HSE_REQ_TRANSMIT_FILE, &tf, 0, 0 ) == TRUE ) return Success; // Failed for some reason! Drop back to less efficent code WriteHeader( ecb, "Content-Type: text/html" ); Output( ecb, "Transmitfile failed" ); return Success; }
Return Value:
The function returns TRUE if successful, or FALSE if an error occurred.


Filters

ISAPI filters can be used to add a wide range of functionality to the web server. Hooking into the server, to do tasks such as logging, access control or altering the raw data that is sent by the server. Filter modules must export two functions.
BOOL WINAPI GetFilterVersion( HTTP_FILTER_VERSION *pVer ); 
Where HTTP_FILTER_VERSION is defined as:

typedef struct _HTTP_FILTER_VERSION
{
    DWORD     dwServerFilterVersion;
    DWORD     dwFilterVersion;
    CHAR      lpszFilterDesc[SF_MAX_FILTER_DESC_LEN+1];
    DWORD     dwFlags;
} HTTP_FILTER_VERSION, *PHTTP_FILTER_VERSION;

The GetFilterVersion function should set the dwFilterVersion to the version of the Filter specification that the filter supports. This version is defined in the header file as HSE_FILTER_REVISION.

The lpszFilterDesc should be filled in with a textual description of the filter.

The filter should set dwFlags to a combination of the following flags.

SF_NOTIFY_SECURE_PORT
Notify application only for sessions over a secure port.
SF_NOTIFY_NONSECURE_PORT
Notify application only for sessions over a non-secure port.
SF_NOTIFY_READ_RAW_DATA
Allow the application to see the raw data. The data returned will contain both headers and data.
SF_NOTIFY_PREPROC_HEADERS
The server has preprocessed the headers.
SF_NOTIFY_AUTHENTICATION
The server is authenticating the client.
SF_NOTIFY_URL_MAP
The server is mapping a logical URL to a physical path.
SF_NOTIFY_SEND_RAW_DATA
The server is sending raw data back to the client.
SF_NOTIFY_LOG
The server is writing information to the server log.
SF_NOTIFY_END_OF_NET_SESSION
The session with the client is ending.
SF_NOTIFY_ACCESS_DENIED
Allows an ISAPI Filter to be notified any time the server is about to return a "401 Access Denied". This lets the Filter analyse the failure and return a custom message.
SF_NOTIFY_ORDER_HIGH
Load the filter at a high priority. High priority filters will get called before lower priority ones on the same hook.
SF_NOTIFY_ORDER_MEDIUM
Load the filter at a medium priority
SF_NOTIFY_ORDER_LOW
Load the filter at a low priority.
Additionally, filters must provide an HttpFilterProc function. This function will get called when one of the events that the filter asked to be notified on occurs. The full type of the function is:
DWORD WINAPI HttpFilterProc( PHTTP_FILTER_CONTEXT pfc,
                             DWORD notificationType,
                             LPVOID notificationInfo );
The notificationInfo parameter points to a data structure which is specific to the type of notification the server is receiving. The table below shows the type of this argument for each notificationType.

Notification Type Notification Info
SF_NOTIFY_READ_RAW_DATA HTTP_FILTER_RAW_DATA
SF_NOTIFY_SEND_RAW_DATA HTTP_FILTER_RAW_DATA
SF_NOTIFY_PREPROC_HEADERS HTTP_FILTER_PREPROC_HEADERS
SF_NOTIFY_AUTHENTICATION HTTP_FILTER_AUTHENT
SF_NOTIFY_URL_MAP HTTP_FILTER_URL_MAP
SF_NOTIFY_LOG HTTP_FILTER_LOG
SF_NOTIFY_ACCESS_DENIED HTTP_FILTER_ACCESS_DENIED

The first argument to the HttpFilterProc is of pointer to an HTTP_FILTER_CONTEXT structure. This structure is defined as:

typedef struct _HTTP_FILTER_CONTEXT
{
   DWORD    cbSize;          /* the size of this structure */
   DWORD    Revision;        /* the revision number of this structure */
   PVOID    ServerContext;   /* reserved for server use */
   DWORD    ulReserved;      /* reserved for server use */
   BOOL     fIsSecurePort;   /* True if the connection is on a secure port */
   PVOID    pFilterContext;  /* a pointer to information the filter wants
                                to associate with the request */

   BOOL     (WINAPI * GetServerVariable) (struct _HTTP_FILTER_CONTEXT * pfc,
					  LPSTR      lpszVariableName,
					  LPVOID     lpvBuffer,
					  LPDWORD    lpdwSize);    
   BOOL (WINAPI * AddResponseHeaders)    (struct _HTTP_FILTER_CONTEXT * pfc,
 				         LPSTR    lpszHeaders,
				         DWORD    dwReserved);     
   BOOL (WINAPI * WriteClient)           (struct _HTTP_FILTER_CONTEXT * pfc,
				         LPVOID     Buffer,
                                         LPDWORD    lpdwBytes,
                                         DWORD      dwReserved);     
   VOID* (WINAPI * AllocMem)             (struct _HTTP_FILTER_CONTEXT * pfc,
			                 DWORD      cbSize,
			                 DWORD      dwReserved);    
   BOOL (WINAPI * ServerSupportFunction) (struct _HTTP_FILTER_CONTEXT * pfc,
					 DWORD   sfReq,
					 LPVOID pData,
					 LPDWORD ul1,
					 LPDWORD ul2);     
} HTTP_FILTER_CONTEXT, *PHTTP_FILTER_CONTEXT;

The functions provided by this structure are described below.


BOOL WINAPI GetServerVariable( HTTP_FILTER_CONTEXT *pfc,
                               LPSTR VariableName, LPVOID Buffer,
                               LPDWORD Size )
This function behaves identically the function of the same name in the ExtensionControlBlock described above.


BOOL WINAPI AddResponseHeaders ( HTTP_FILTER_CONTEXT *pfc,
                              	 LPSTR Headers, 
                                 DWORD Reserved );
Add extra HTTP headers to be sent to the client.

Arguments:

pfc
The pFilterContext taken from the HTTP_FILTER_CONTEXT structure so that the server knows which connection is involved.
Headers
This should be a null terminated-string containing the HTTP headers to be added to the table of headers that will get sent to the client.
Return Value:
The function returns TRUE on success, or FALSE if an error occurred.


BOOL WINAPI WriteClient ( HTTP_FILTER_CONTEXT *pfc,
                           LPVOID Buffer, LPDWORD Bytes,
                           DWORD  Reserved );
Write data to the client.

Arguments:

pfc
The pFilterContext taken from the HTTP_FILTER_CONTEXT structure so that the server knows which connection is involve.d
Buffer
Bytes


VOID* WINAPI AllocMem( HTTP_FILTER_CONTEXT *pfc, DWORD size,
                       DWORD Reserved );
This function allocates memory in a per-connection memory pool. The memory will get freed automatically by the server when the connection is finished.

Filters should do all their memory allocation through this call, as directly calling malloc() or new() may interfere with the memory server's management.

Arguments:

pfc
The pFilterContext taken from the HTTP_FILTER_CONTEXT structure so that the server knows which connection is involved.
size
The number of bytes to allocate
Return Value:
Returns a pointer to the allocated buffer, or zero on failure.


BOOL WINAPI ServerSupportFunction( HTTP_FILTER_CONTEXT *pfc,
                                   DWORD   Request,
                                   LPVOID  Data,
                                   LPDWORD ul1, LPDWORD ul2 );
The Request argument sets the function to be performed. Supported values are:
SF_REQ_SEND_RESPONSE_HEADER
This sends a complete HTTP server response header including the status, server version, message time, and MIME version. Data should be set to the HTTP status response (e.g. "200 OK") or can be left null. The ul1 argument should point to a null terminated string buffer containing additional headers to be sent to the client.
SF_REQ_ADD_HEADERS_ON_DENIAL
not supported
SF_REQ_SET_NEXT_READ_SIZE
not supported
SF_REQ_GET_FILE_DESCRIPTOR (Zeus specification extension)
Allows the ISAPI filter to get hold of the raw filedescriptor of the client's socket. For example, this might be used to perform an identd lookup on the client. On entry, the Data pointer should point to a DWORD, and on return will contain the file descriptor. The ul1 parameter should be a pointer to an integer containing the size of the Data buffer.


typedef struct _HTTP_FILTER_ACCESS_DENIED
{
   const CHAR * pszURL;           /* Requesting URL */
   const CHAR * pszPhysicalPath;  /* Physical path of resource */
   DWORD        dwReason;         /* Bitfield of SF_DENIED flags */
} HTTP_FILTER_ACCESS_DENIED, *PHTTP_FILTER_ACCESS_DENIED;
The Zeus Server will always set the dwReason bitfield to zero. The pszURL and pszPhysicalPath values indicate the the resource that access was denied to.


typedef struct _HTTP_FILTER_AUTHENT
{
    CHAR *    pszUser;
    DWORD     cbUserBuff;
    CHAR *    pszPassword;
    DWORD     cbPasswordBuff;
} HTTP_FILTER_AUTHENT, *PHTTP_FILTER_AUTHENT;
User
A pointer to a string containing the user name for this request. An empty string indicates an anonymous user. The filter can replace the pointer to point to a different string, or alter the contents of the buffer.
cbUserBuff
The size of the buffer pointed to by pszUser. This is guaranteed to be at least SF_MAX_USERNAME.
pszPassword
A pointer to a string containing the password for this request. This buffer can be altered, or the pointer altered to point to a different string.
cbPasswordBuff
The size of the buffer pointed to by pszPassword. This is guaranteed to be at least SF_MAX_PASSWORD.


typedef struct _HTTP_FILTER_LOG
{
    const CHAR *    pszClientHostName;
    const CHAR *    pszClientUserName;
    const CHAR *    pszServerName;
    const CHAR *    pszOperation;
    const CHAR *    pszTarget;
    const CHAR *    pszParameters;
    DWORD           dwHttpStatus;
    DWORD           dwWin32Status;
} HTTP_FILTER_LOG, *PHTTP_FILTER_LOG;
The filter can alter the value of the pointer (but not the buffer) of the pszTarget, pszOperation and pszClientUserName values.

The dwWin32Status will always be set to zero with the Zeus Server.


typedef struct _HTTP_FILTER_PREPROC_HEADERS
{
   BOOL    (WINAPI * GetHeader) (struct _HTTP_FILTER_CONTEXT *    pfc,
				 LPSTR    lpszName,
				 LPVOID   lpvBuffer,
				 LPDWORD  lpdwSize);     
   BOOL    (WINAPI * SetHeader) (struct _HTTP_FILTER_CONTEXT *    pfc,
				 LPSTR    lpszName,
				 LPSTR    lpszValue);      
   BOOL    (WINAPI * AddHeader) (struct _HTTP_FILTER_CONTEXT *    pfc,
				 LPSTR    lpszName,
				 LPSTR    lpszValue);      
   DWORD    dwReserved;     
} HTTP_FILTER_PREPROC_HEADERS, *PHTTP_FILTER_PREPROC_HEADERS;

BOOL WINAPI GetHeader( HTTP_FILTER_CONTEXT *pfc,
                       LPSTR Name, LPVOID Buffer, LPDWORD Size )
Gets the current value of a header in the client's HTTP request.
Name
A null terminated string, giving the name of the header to retrieve.
Buffer
A buffer which is filled in with the value of the named header.
Size
On calling, this should be the size of Buffer in bytes. On return it will be the length of the value in buffer (including the null terminator).


BOOL WINAPI SetHeader( HTTP_FILTER_CONTEXT *pfc,
                       LPSTR Name, LPSTR Value, LPDWORD Size )
BOOL WINAPI AddHeader( HTTP_FILTER_CONTEXT *pfc,
                       LPSTR Name, LPVOID Value );
These two allow the filter to modify header lines in the client's request.

SetHeader & AddHeader are very similar, differing only in their behaviour when the header in question already exists. With SetHeader, the previous header value will be replaced; with AddHeader the new value will be merged with the old value.

For example, if the client's input looks like:

Then a SetHeader of "Cookie" & "X=Y" manipulates the request to produce: Whereas an AddHeader of "Cookie" & "X=Y" manipulates the request to look produce:

Name and Value should both be null terminated strings; with the extension that if Value is a NULL pointer, then both SetHeader & AddHeader will delete the header in question.

All three functions return TRUE on success, or FALSE if an error occurred.


typedef struct _HTTP_FILTER_RAW_DATA
{
    PVOID pvInData;
    DWORD cbInData;
    DWORD cbInBuffer;
    DWORD dwReserved;
} HTTP_FILTER_RAW_DATA, *PHTTP_FILTER_RAW_DATA;
pvInData
A pointer to the raw data.
cbInData
The number of bytes of data pointed to by pvInData
cbInBuffer
The size of the buffer pointed to by pvInData The filter can overwrite the buffer, or alter the pvInData and cbInData values to alter the raw data that is being sent.


typedef struct _HTTP_FILTER_URL_MAP
{
    const CHAR *    pszURL;
    CHAR *          pszPhysicalPath;
    DWORD           cbPathBuff;
} HTTP_FILTER_URL_MAP, *PHTTP_FILTER_URL_MAP;
pszURL
The URL the user requested. This is a null terminated string.
pszPhysicalPath
The filesystem path that file mapped onto. The filter can overwrite this buffer, or alter what the pointer points to.
cbPathBuff
The size of the buffer pointed to by pszURL.