ISAPI Filter Event Notifications

ISAPI filters are loaded into the IIS process when the Web service is started, and stay in memory until it shuts down.

Once loaded, IIS calls the GetFilterVersion Function function, passing a pointer to an HTTP_FILTER_VERSION Structure (IIS) structure. In the HTTP_FILTER_VERSION Structure (IIS) structure, you can specify which event notifications the filter is interested in, and the priority of the filter when IIS sends notifications.

When an event occurs, IIS calls the HttpFilterProc Function method of the interested filters, passing a pointer to the HTTP_FILTER_CONTEXT Structure (IIS) structure which contains information about the event, the type of notification, and a pointer to a specific ISAPI Filter Structures that gives access to relevant ISAPI Filter Callback Functions.

Filter Notification Order

ISAPI filters can be configured only at the global level or the Web site level. If more than one ISAPI filter is registered for a given event, IIS notifies the filters that the event occurred, in the following order:

  • Global filters are notified before site-level filters.

  • If priorities are specified, high priority filters are notified first, then medium, then low.

  • If more than one ISAPI filter is declared the same general priority level, IIS uses the order in which the filters appear in the FilterLoadOrder property to resolve the tie.

Filter Event Order

In general, the events that occur during the processing of a typical Internet Information Services (IIS) request and response are regular and predictable. The following list outlines the most common ordering of events.

SF_NOTIFY_READ_RAW_DATA

(HttpFilterProc Function is passed a pointer to HTTP_FILTER_RAW_DATA Structure (IIS))

When a client sends a request, one or more SF_NOTIFY_READ_RAW_DATA notifications occur. Data is read until the client has sent all of the HTTP headers associated with the request.

SF_NOTIFY_PREPROC_HEADERS

(HttpFilterProc Function is passed a pointer to HTTP_FILTER_PREPROC_HEADERS Structure (IIS))

A single SF_NOTIFY_PREPROC_HEADERS notification occurs for each request. This notification indicates that the server has completed preprocessing of the headers associated with the request, but has not yet begun to process the information in the headers.

SF_NOTIFY_URL_MAP

(HttpFilterProc Function is passed a pointer to HTTP_FILTER_URL_MAP Structure (IIS))

An SF_NOTIFY_URL_MAP notification occurs whenever the server is converting a URL to a physical path. This notification occurs at least once after the preprocessed header's notification for the request, and might occur many additional times during processing of the associated request.

SF_NOTIFY_AUTHENTICATION

(HttpFilterProc Function is passed a pointer to HTTP_FILTER_AUTHENT Structure (IIS))

An SF_NOTIFY_AUTHENTICATION notification occurs just before IIS attempts to authenticate the client. This notification occurs for every new connection (including anonymous requests), and every time the client sends enabled user credentials for the target URL, in the form of an authorization header, to be authorized by the server. The AuthPersistence property setting in the metabase directly affects this filter. Note that not all requests are guaranteed to trigger an authentication notification. This notification only fires for anonymous requests and requests with an authorization header that specifies Basic authentication.

SF_NOTIFY_AUTH_COMPLETE

(HttpFilterProc Function is passed a pointer to HTTP_FILTER_AUTH_COMPLETE_INFO Structure (IIS))

This notification, new to IIS 5.0, offers functionality similar to that of SF_NOTIFY_PREPROC_HEADERS. Specifically, it allows viewing and modification of the method, URL, version, or headers sent from the client. The key difference between this notification and preprocessed headers is that this notification occurs after the client's identity has been negotiated with the client. Because of the notification's timing, the AUTH_USER server variable can be used to reliably obtain the identity of the user. Also, functionality is provided to retrieve a copy of the token that IIS impersonates when processing the request.

SF_NOTIFY_READ_RAW_DATA

(HttpFilterProc Function is passed a pointer to HTTP_FILTER_RAW_DATA Structure (IIS))

  1. As mentioned in step 1, if the client has more data to send, one or more SF_NOTIFY_READ_RAW_DATA notifications occur at this point. Each one indicates that IIS has read another chunk whose size equals either the value of the UploadReadAheadSize metabase property (usually 48 KB), or the remaining number of bytes available (if the chunk is the last one).

Because many factors can force IIS to adopt a different chunking scheme, additional raw read events are not always completely predictable. Therefore, ISAPI filters should not rely on the exact behavior described above.

Note

At this point, IIS begins processing the substance of the request. This can be done by an ISAPI extension, a CGI application, a script engine such as ASP or PERL, or by IIS itself for static files.

SF_NOTIFY_SEND_RESPONSE

(HttpFilterProc Function is passed a pointer to HTTP_FILTER_SEND_RESPONSE Structure)

This event occurs after the request is processed and before headers are sent back to the client.

SF_NOTIFY_SEND_RAW_DATA

As the request handler returns data to the client, one or more SF_NOTIFY_SEND_RAW_DATA notifications occur.

SF_NOTIFY_END_OF_REQUEST

  1. At the end of each request, the SF_NOTIFY_END_OF_REQUEST notification occurs.

SF_NOTIFY_LOG

(HttpFilterProc Function is passed a pointer to HTTP_FILTER_LOG Structure (IIS))

After the HTTP request is complete and just before IIS writes the request to its log, the SF_NOTIFY_LOG notification occurs.

SF_NOTIFY_END_OF_NET_SESSION

When the connection between the client and the server is closed, the SF_NOTIFY_END_OF_NET_SESSION notification occurs. If a Keep-Alive connection has been negotiated, it is possible for many HTTP requests to occur before this notification.

Exceptions to the Event Sequence

The preceding sequence is accurate enough for most purposes. However, it must be understood that there are often factors that can change the order of events. IIS or ISAPI filters can interrupt or modify the sequence of event notifications.

Caution

Due to the complex and dynamic event model IIS uses, it is important that developers not rely on the exact sequence described above. An ISAPI filter must handle the occurrence of events in nonstandard order without failing and, more importantly, without causing IIS to fail.

Nonstandard event notification order can occur in any of the following situations:

  • A filter returns SF_STATUS_REQ_FINISHED if it does not want the request to continue processing after a particular notification. In a typical example, a filter that is authenticating a user sends an "access denied" response to the client and closes the connection. Once the sequence of events reaches step 7, in which the request is processed by the handler, SF_STATUS_REQ_FINISHED should not be returned because it cannot abort the handler once it takes over.

  • If a 401 response is sent to the client, the SF_NOTIFY_ACCESS_DENIED event notification occurs. With this notification, the order of events changes. The next event is usually SF_NOTIFY_END_OF_REQUEST.

  • If integrated Windows authentication (also called NTLM authentication) is being negotiated, three requests and responses typically take place between the client and the server. If, on the second request, IIS responds to the client with a challenge, the SF_NOTIFY_END_OF_REQUEST notification does not occur. All other notifications on the second request and response occur as expected, however. For this reason, this notification should not be relied on as a signal to free memory allocated elsewhere in the filter, unless it is certain that integrated Windows authentication is not being used.

  • The SF_NOTIFY_URL_MAP event notification can occur multiple times on a single request, occasionally with an empty string for the pszURL member. One known cause of this is a call to ServerSupportFunction with HSE_REQ_MAP_URL_TO_PATH.

  • The SF_REQ_DISABLE_NOTIFICATIONSServerSupportFunction can be used to disable all further notifications for the duration of the current request, if the filter has completed all processing for the request.

  • For filters that participate in the SF_NOTIFY_SEND_RAW_DATA event notifications, priority ratings (high, medium, and low) are temporarily reversed for the duration of the notification. This reversal allows higher-priority filters, such as encryption filters, to process the data after other raw data filters operate on the unprocessed data, and just before it is sent to the client browser. Priority ratings do not change for SF_NOTIFY_READ_RAW_DATA event notifications.