ISAPI filters provide you with a versatile tool for extending IIS functionality to meet your special requirements. There are some important issues you should consider in developing your filter. The following notes provide some general guidelines summarizing these issues.
When IIS receives POST data from the client, it only reads as much as it needs to get the headers. After all of the other pre-request handler notifications are called, the server reads up to 48K more of the POST data, and then handles the request. If you need to process POST data, you should do so in an ISAPI extension, an ASP application, or with other methods that do not affect performance.
When changing the pszPhysicalPath member in the HTTP_FILTER_URL_MAP structure, you should not change the type of the file. For example, if the original path was to a static file, such as an .htm file, do not change the path to an .asp file. The request will still be handled as a static file and the effect will be that the raw .asp file is returned to the client. If you need to make this type of redirection, you should modify the URL in SF_NOTIFY_PREPROC_HEADERS.
You only call the SF_NOTIFY_AUTHENTICATE event notification when a network session is created. You can make requests over an existing session, but for these, this notification will not be called. You should not rely on this code to deny access for any reason; denial will not happen, and a security hole will result. If you need to do such processing on a per request basis, you should implement the code in an SF_NOTIFY_PREPROC_HEADERS handler. The only reliable action you can take in during SF_NOTIFY_AUTHENTICATE is to assign specific values to pszUser and pszPassword.
You use ISAPI filters to modify IIS behavior and, because of this, you can potentially call them many times for each request that is made to the server. In most cases, an ISAPI filter should only return data to the client when it handles an exception case (when the request is denied, for example).
If you need to do extended processing and do not wish to expose a URL to the client that reveals the nature of the component that will be handling the request, create a handler for SF_NOTIFY_PREPROC_HEADERS. Within that handler, modify the requested URL to point to an ISAPI extension to do the work. For example, if you would like to create a proxy to dispatch the request to another server, create an ISAPI extension to communicate with the proxy. Then, use the pre-processing headers filter to change the URL so that it points to the extension you created. If you need to, pass any special information (such as the original URL in the above example) to the extension through the query string.
You should register most of your filters for the end of session event, as it is a good time to perform resource maintenance, such as recycling buffers. For performance reasons, most filters keep a pool of filter buffers and only allocate or free them when the pool becomes empty or too large to save on the overhead of the memory management. The end of session event is also an opportune time to recycle any buffers that were used by a client request.
You can use the Allocmem callback function with the HTTP_FILTER_CONTEXT structure to allocate memory. The memory that is allocated will automatically be freed when the communication with the client is terminated. Managing memory in this way can have a negative impact on performance, since Allocmem results in a heap allocation. It may be preferable to create your own memory pool and only adjust the pool as necessary. This will reduce the overhead caused by allocating and de-allocating memory.
You should only register your filters to be notified of those events that it needs for processing. Some filter notifications are very expensive in terms of CPU resources and I/O throughput, and can have a significant effect on the speed and scalability of IIS.
If you create a filter that registers for the SF_NOTIFY_READ_RAW_DATA event, you should limit this filter's scope so that it only applies to those applications where it is critical to read the raw data. Implementing a filter that reads raw data introduces some additional complexities. An example of a filter that reads raw data is provided in the \Inetpub\iissamples\sdk\isapi\filters directory. See the Cookie Conversion Filter in the ISAPI Examples section of Developer Samples for more information.
Filters that register for the SF_NOTIFY_READ_RAW_DATA or SF_NOTIFY_SEND_RAW_DATA events must be applied at the Web Service level. They can not be applied to an individual Web Site. For more information on applying filters see Installing ISAPI Filters in Configuring Applications.
You can add an ISAPI filter programmatically using the IIS Admin Objects. Filters can be added to either the WWW service or to an individual Web site. To add a filter you must first create an IIsFilters object. IIsFilters is a container object that you can populate with IIsFilter objects.
For example, the following script would add an IIsFilters object to the WWW service. Note that a Filters object is created for the WWW service when IIS is installed. For an individual Web site you may need to create this object before you can use it.
Dim FiltersObj
Dim LoadOrder
Set FiltersObj = GetObject("IIS://LocalHost/W3SVC/Filters")
LoadOrder = FiltersObj.FilterLoadOrder
If LoadOrder = "" Then
LoadOrder = LoadOrder & ","
End If
LoadOrder = LoadOrder & "myFilter"
FiltersObj.FilterLoadOrder = LoadOrder
FiltersObj.SetInfo
Once you have established the IIsFilters container object, you can add your IIsFilter object and set its properties.
For example, the following script adds a new IIsFilter, myFilter, and sets the path and description.
Dim FilterObj
Dim FilterName
FilterName = "myFilter"
FilterPath = "C:\iisfilts\myfilter.dll"
FilterDesc = "This is my filter"
Set FilterObj = FiltersObj.Create("IIsFilter", FilterName)
FilterObj.FilterPath = FilterPath
FilterObj.FilterDescription = FilterDesc
FilterObj.SetInfo
For a working example of an administrative script that adds a filter, see Additional Admin Script Examples in the Developer Samples. For more information on the Admin Objects see IIS Admin Objects.