If you would like to submit an article, click the button below.
By: Mete Veli, Sun Aug 10th, 2008
ISAPI using Delphi? Check out ISAPI Filter Component to write ISAPI filters the visual way, in Pascal, that is "The Delphi way". ISAPI is the application programming interface to extend the functionality of IIS, Microsoft Internet Information Server. IIS supports many scripting languages such as ASP, ASP.NET, PHP, JSP. However, for certain tasks that are orthogonal to a specific http request, an ISAPI filter is the best match. ISAPI filters are native DLLs written in a native language. They become part of the IIS server and extend it's functionality in ways that cannot be implemented using ASP.NET or other server side technologies. For an incoming http request, an ISAPI Filter is invoked before ASP.NET, or any other server side programming layer. For outgoing http requests, ISAPI filters are invoked after ASP.NET has completed it's execution. This order of events and scope of control gives the ISAPI filters a special priviledge to literally do whatever they want. ISAPI Filter is the gate keeper. IIS exposes ISAPI via C interface. The developers write ISAPI DLLs, typically in Visual C++ and implement necessary functions for IIS to call. This process becomes tedious in Delphi because the C header files need to be translated to Pascal. The C structures need to be correctly expressed using Pascal semantic while keeping binary compatibility. The ISAPI API is very low level. It works with primitive types such as pointers to structures, pointers to byte buffers, pointers to functions. In the Delphi world, we are used to using Objects, Strings, member functions. TbcISAPIFilter component was developed to bridge the impedance mismatch between the low level IIS concepts and the Delphi Pascal's Object Oriented, Visual, event based approach. Using TbcISAPIFilter, the developer is freed from the details of exporting necessary ISAPI entry points from the DLL. The IIS data structured are wrapped by user friendly objects. Delphi friendly functions are introduced to invoke low level ISAPI functions eliminating hard to debug errors due to null pointers, buffer overruns, and the Pascal String type is used instead of byte array buffers that are not even NULL terminated character arrays. Why would you need an ISAPI filter? For example, you could intercept every request (even to static resources such as images, html, pdf and text files) and for example provide IIS user authentication filter using a database. This may involve using many of the ISAPI Filter events available to the Delphi programmer. It is possible to map one request URL to another, even for static resources. This can be as simple as mapping one physical disk folder to another, or in advanced cases it can provide regular expression based isapi url rewrite functionality (Similar to Apache mod_rewrite). You could modify outgoing data to find and replace text in it. Once you get familiar with the IIS events, then what you can do is almost upto your imagination. ISAPI Filter Component for Delphi provides the following events: OnReadRawData OnPreprocHeaders OnUrlMap OnAuthentication OnAuthComplete (IIS 5.0 and later) OnSendResponse OnSendRawData OnEndOfRequest OnLog OnEndOfNetSession OnAccessDenied OnExtensionTrigger (IIS 5.0 and later) OnUnknownNotification (For future IIS versions in case new versions of the component is late to support them explicitly) OnReadRawData Provides Delphi event to handle SF_NOTIFY_READ_RAW_DATA IIS notification. 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. OnPreprocHeaders 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. OnUrlMap 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. OnAuthentication 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. OnAuthComplete (IIS 5.0 and later) SF_NOTIFY_AUTH_COMPLETE 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. After OnAuthComplete exits, as mentioned in OnReadRawData section, 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. 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. OnSendResponse This event occurs after the request is processed and before headers are sent back to the client. This is triggered by SF_NOTIFY_SEND_RESPONSE notification from IIS. OnSendRawData As the request handler returns data to the client, one or more SF_NOTIFY_SEND_RAW_DATA notifications occur. OnEndOfRequest At the end of each request, the SF_NOTIFY_END_OF_REQUEST notification occurs. OnLog After the HTTP request is complete and just before IIS writes the request to its log, the SF_NOTIFY_LOG notification occurs. OnEndOfNetSession 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. TbcISAPIFilter comes with Delphi ISAPI Filter examples. You can quickly take one, start modifying the DLL code and the Data Module to visually realign for your own needs.