by Daniel F. Wygant
During normal business operations, files and data in different formats are often created and updated. Tremendous amounts of
information are stored in files and databaseslike gold waiting to be mined by your business. Just trying to manage access can be a daunting task. Part and parcel of managing information is dealing with a wide variety of viewers, editors, and other
applications for dealing with the massive information stored. Filtering this information on-the-fly for display through a Web browser such as Internet Explorer solves both the access problem and the viewer problem.
Microsoft supplies sample code in the ActiveX SDK for an ActiveX ISAPI filter that does just that. It converts documents (Word, Excel, Text) to HTML documents when a hyperlink for the document is selected. The converted HTML document is then displayed
in the browser.
ActiveX ISAPI filter technology offers several different types of filtering; some are listed briefly here:
This chapter discusses how businesses can benefit from ActiveX ISAPI filter technology and gives a broader understanding of what the various filters can be used for. A sample URL-mapping filter, with source code, is presented
to illustrate how this new ActiveX technology works. The example walks you through creating a filter with the VC 4.1 MFC ISAPI Filter Wizard and briefly examines the MFC subclass produced. The chapter winds up with a few application ideas for using ActiveX
ISAPI filters.
There are innumerable possibilities for using this technology. This is illustrated in Figure 12.1, which shows a Windows NT Server being accessed through the Web. A "black-box" ISAPI filter stands between the Internet Information Server and
the data on the NT Server providing "mystery" value add-ons.
Figure 12.1. A "black-box" ISAPI filter transforming data on-the-fly.
To begin with, this new API is a very powerful, yet fast and easy, way to enhance your HTTP server's capabilities and security. With ActiveX ISAPI filters, you can provide
new schemes for finding the data on the server, for custom logging of HTTP requests, for data encryption and compression, and for data conversion or preprocessing. The sample code developed for this chapter gives you an example of a URL Map ISAPI filter
that modifies the URL requested by changing the directory name.
Using a Dynamic Load Library (DLL) to process your HTTP requests is not only powerful, but
also quite a bit faster than using the Common Gateway Interface (CGI). With CGI, your HTTP server must invoke a separate process for every request, which may overload your server. However, with DLLs the only overhead is starting a new thread, which is very
fast and inexpensiveboth for processing and memory-wisecompared to starting a new CGI process.
Overall, the ActiveX ISAPI filters are much more powerful and efficient tools than the CGI type currently in use.
Creating new applications with the filter capabilities is easy, and retrofitting existing applications with filters isn't difficult. The payback in filter efficiency will clearly improve your business, and the new capabilities of
these filters will put your business organization ahead of the Internet technology curve. In addition, Visual C++ 4.1 (VC 4.1) has MFC classes for ISAPI filters and an MFC
ISAPI Extension Wizard that builds an initial class framework for an ISAPI filter using these MFC classes. The result of using MFC to build an ISAPI filter is a small ISAPI filter program (DLL), which
is extremely easy to modify and extend to help efficiently manage your business's vast storage of information on its intranet and its connection to the Internet.
As for actual business uses, start with a simple example: Say you would like to move your data, but there are links all over the Internet to data on your server. One easy solution is to provide an ISAPI filter to map URLs (Uniform Resource Locators) to point to the new location. Once the filter is installed and the server's IIS is restarted, any URLs requesting data in the old location can be
mapped to the new location. This will save you the time of finding and rewriting all your HTML files, not to mention the problems finding and notifying any external Internet sites of the location change. Figure 12.2 illustrates the URL mapping process.
Figure 12.2. ISAPI filter URL mapping process.
Another very powerful use, mentioned in the introduction, is data conversion or data preprocessing. You can essentially rewrite requested data
on the fly. For example, you might have a particular set of files in a particular format that you want to make available in HTML format. Unfortunately, you don't have the resources to keep the HTML versions current or to manually perform the conversion to HTML format.
This is an excellent time to consider writing an ISAPI filter that processes URL Map events. The URL Map event occurs on your HTTP server any
time it's requested to process a URL. When a URL Map event occurs, the HTTP server calls each ISAPI filter that had indicated an interest in URL Map events during initialization. Your ISAPI filter is called to process the URL Map event/request and, in this
example, checks the file extension and directory name. If the file extension or directory name match the one(s) your filter wants to deal with, it converts the file to another formatfor example, HTML. The path to the document-converted-to-HTML file
is then returned in place of the input path to the original document. This, then, is an example of a URL mapping. The surfer/user requests the document and gets the document in an HTML format; the URL is mapped to an HTML file, which has been converted
from the document originally requested. See Figure 12.3 for a diagram of this data-conversion process.
Figure 12.3. ISAPI filter URL Map file-conversion process.
Other types of business uses for ISAPI filters are data
encryption or compression for transmitting data in a custom format that only specific client browsers can interpret. For example, say you ran a stock-options business and had a set of clients that paid for high-speed access to sensitive market research
information. You could allow access through a client-server architecture by passing the data back to the clients in a browsable or hyperlinked format.
An ISAPI filter can be used to transform the data before sending it to the client's browser. The client's browser would have to decrypt or decompress the data for display on the client side. In this way, your data is secured by encrypting the data
before tranfer; by compressing the data, it can be transferred at higher speeds over the network. This is illustrated in Figure 12.4.
Figure 12.4. Data encryption and compression on the fly.
You can create an ISAPI filter for a customized tracing mechanism of HTTP requests that pass through your HTTP server. You could then
use the information this filter reports to make decisions affecting capabilities and security of your business intranet and its connection the Internet. This alone is a good reason for creating an ISAPI filterto offer a custom security scheme beyond
what your current HTTP server can offer.
For instance, you may have certain files that only upper-level management should have access to, such as employee salaries or employee profiles. These files could be made accessible through the Web exclusively to upper-level management. You could write
an ISAPI filter that would perform an authentication check before allowing access to the files.
When these files are accessed, your ISAPI filter would get an Authentication event. At this time, the filter would check the IDs against a database of the current upper-level management (since it changes so frequently). If the requester's ID is valid,
then allow access; if not, he or she would get a "gentle" reminder in HTML format that this is (now) forbidden territory.
Your business can also use an ISAPI filter to modify certain documents for presentations. A filter could be used to change a file's data before the HTTP server
passes it to the client's browser for display, or one could be written to convert any document references into HTML URL references. For example, assume a text file (FileStore\filelist.txt) is requested containing the following two lines:
Third Quarter 1996 Business Plan c:\INetSrv\WWWRoot\FileStor\BusinessPlan3rdQ96.doc
A filter could be written to process the text file into an HTML file when it receives an URL Map event for the FileStore directory. For the sake of illustration, say the filter takes the second line and makes a hyperlink from it with the textual
description on the first line being the URL's highlighted text, as follows:
<A HREF="FileStor\BusinessPlan3rdQ96.doc.htm">Third Quarter 1996 Business Plan</a><p>
This could certainly produce a nice business presentation, especially if you had the CVTDOC example, mentioned in the introduction, which takes *.doc.htm URL Maps and converts the *.doc file into an *.htm file (HTML). You could then click and get a
Word-like display of the *.doc file in HTML. Figure 12.5 shows two screen shots illustrating the difference in appearance that converting the text file to HTML can make.
Figure 12.5. Simple text file versus converting to HTML.
The IIS HTTP server calls ISAPI filters for different types of HTTP-related requests. These are refered to
as events and the process can be thought of as an event notification paradigmthe event notification paradigm for ActiveX ISAPI filters. The events sent to filter DLLs are specified by each individual DLL during initialization of IIS. When an
IIS service is started, the DLLs listed in a special place in the registry get loaded. As each filter is loaded, an initialization routine (GetFilterVersion()) is called for each filter to return information; part of this information is which types of
events it wants to be notified of. When IIS generates such events, it send them to the filter DLLs that had expressed an interest in them. Your ISAPI filter DLL is listed in the registry in the following key
"HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\W3Svc\Parameters\"
under the value
"Filter DLLs"
The DLLs are separated by commas. The order in which filters are notified is based on priority: high, medium, or low. If there are two or more filters listed with the same priority, the order of notification is based on where the DLLs sit, left to
right, as they are listed in this registry value. Once the DLL is initialized, you get notifiedor calledfor the events specified to IIS during Server startup.
An "event" is triggered in IIS when a browser, such as Internet Explorer, Netscape, or Mosaic, tries to activate a hyperlink (URL) to your Windows NT Server's HTTP server. When your
HTTP server, IIS, is contacted with a URL, the IIS HTTP server calls each of the ISAPI filters for a variety of events. The events a particular filter is notified for are specified to IIS by a call to the filter during IIS startup. The initialization and
event notification paradigm is illustrated in Figure 12.6. The list following that explains the meanings of the notification flags, which are returned to IIS by the filter in a bitmask during initialization.
Figure 12.6. Event notification paradigm for ISAPI filters.
This example shows you the basics of creating an ISAPI filter with Visual C++ 4.1 Microsoft Foundation Classes and walks you through using the VC++ 4.1 ISAPI
Extension Wizard. For this simple example, you'll create a filter that maps URLs, which allows you to move data around on your Windows NT Server without having to modify the HTML files to point to the new location.
You'll also create a dynamic link library that's notified when a user selects a hyperlink from a browser, such as Internet Explorer. Your DLL will then filter the URL selected, modifying the file path if it contains the directory that has been moved.
Microsoft offers a set of C++ classes for creating ISAPI filters in Visual C++ 4.1, as well as an ISAPI Extension Wizard. To begin,
bring up VC++, choose File | New (or press Ctrl+N), and select the Project Workspace option from the New dialog box to open the New Project Workspace dialog box. Select ISAPI Extension Wizard, enter
the name UrlMaper, and click the Create button to start the ISAPI Extension Wizard. Check the "Generate a Filter object" checkbox and uncheck the "Generate a Server Extension object" checkbox.
Figure 12.7 shows what the Wizard looks like after these selections have been made to the first page.
Figure 12.7. ISAPI Extension WizardStep 1 of 2.
Now click the Next button, which opens the ISAPI Extension WizardStep 2 of 2 dialog box. Select the "URL mapping requests" checkbox and deselect the
"End of connection" checkbox. (See Figure 12.8.)
Figure 12.8. ISAPI Extension WizardStep 2 of 2.
Now click the Finish button to bring up the New Project Information dialog box, then click the OK button to complete the Wizardry. Figure 12.9 show VC++ 4.1 after this step. The initial filter,
without any additional code, is ready to compile and debug.
Figure 12.9. The UrlMapper project after using the ISAPI Extension Wizard.
Since the ISAPI Extension Wizard did most of the work for you, all that's left to do is implement the call-back routine for URL mapping.
The wizard-created class, CUrlMaperFilter, is subclassed from CHttpFilter. As you can see from Figure 12.10, the only method you have to implement is the CUrlMaperFilter::OnUrlMap(). Figure 12.10 shows the view after double-clicking on the OnUrlMap() method from the ClassView. You are positioned at the beginning of the OnUrlMap() method.
Figure 12.10. ClassView of the UrlMapper class CUrlMaperFilter.
To implement the OnUrlMap() method, add the following code:
CString URLPath; int index=0; // index of your old directory in the path // copy into a CString for simple search URLPath = pMapInfo->pszPhysicalPath; // Find the start of the "\\OldDir\\" string index = URLPath.Find ( "\\OldDir\\" ); // If the directory name was found; replace it if (-1 != index) { // Get the left half of the directory path CString newDir = URLPath.Left( index ); // Add the new directory newDir += "\\NewDir\\"; // Add the right half of the directory path newDir += URLPath.Mid ( index + strlen ( "\\OldDir\\" ) ); // copy the new directory path back into the input path strcpy ( pMapInfo->pszPhysicalPath, (LPCTSTR)newDir ); }
This code looks for the directory \OldDir\ and, if found, replaces it with the \NewDir\ directory. Note the paths are the same size. If the path passed to this method in the PHTTP_FILTER_URL_MAP
structure had ended up being longer than cbPathBuff, you would allocated a new chunk of memory for pszPhysicalPath and deallocated it in the OnEndOfNetSession() method. This reallocation scheme is substantially more difficult to manage and
will not be addressed in this example.
To debug this filter, choose Build | Debug | Go (or press F5) from the VC++ menu bar. It's probably a good idea to set a break in the CUrlMaperFilter::OnUrlMap()
method and perhaps in the CUrlMaperFilter::GetFilterVersion() method, as well. During the initialization, you should get a call to the CUrlMaperFilter::GetFilterVersion() method. If you don't, then you probably entered the wrong path under the Filter DLLs
value or did not stop all three IIS publishing services before you started.
Note that the ISAPI Extension Wizard put the following lines of code in the CUrlMaperFilter::GetFilterVersion() method:
// Set the flags we are interested in pVer->dwFlags |= SF_NOTIFY_ORDER_LOW | SF_NOTIFY_SECURE_PORT | SF_NOTIFY_NONSECURE_PORT | SF_NOTIFY_URL_MAP;
This code sets the notification priority to low, indicates you want to deal with both secure and non-secure ports, and, most important, tells the server to notify
your DLL for URL Map events. Since you've indicated that you want to be notified of URL Map events, you set a break in the CUrlMaperFilter::OnUrlMap() method. To cause IIS to call this method so you can generate a break, you must bring up a browser such as
Internet Explorer and enter or select a hyperlink with a URL for your machine. The following is an example of HTML code that will cause the IIS server to call your filter for an URL Map event:
<a href="http://yourservername/OldDir/FileStore/filelist.txt"> The Biz</a>
Figure 12.11 shows this HTML code displayed in Internet Explorer.
Figure 12.11. HTML reference displayed in Internet Explorer.
When you get called for this URL Map event, the code in the CUrlMaperFilter::OnUrlMap() method will change the path from
c:\INetSrv\WWWRoot\OldDir\FileStore\filelist.txt
to
c:\INetSrv\WWWRoot\NewDir\FileStore\filelist.txt
As pointed out in the introduction, data conversion is one of the more powerful capabilities provided by ActiveX ISAPI Filters. This section explores a few more possible implementation ideas for filters and discusses
extending the sample ISAPI filter to preprocess data as well.
First, take a look at one of the filters provided as sample code in VC++ 4.1. The example from which I got the idea for the URL Map sample code is the MFCUCASE example in the directory c:\msdev\samples\mfc\internet\mfcucase.
This example receives URL Map and Send Raw Data events. The code in its OnUrlMap() method looks for URLs with \UC in the directory path, which triggers it to change everything to uppercase in the OnSendRawData() method. The OnUrlMap() method removes
the \UC from the path so the browser can find the file; the \UC in the path is just an indicator that the text should be turned into uppercase. The following is a sample URL:
http://yourservername/FileStore/UC/FileList.htm
The actual file is in the c:\INetSrv\WWWRoot\FileStore\FileList.htm file. Suppose the file FileList.htm has the following lines in it:
<title>Upper Case Test</title> <p><p><H3><HEAD><B>This code should appear in uppercase</B></HEAD></H3><p><p> <A HREF="FileStor\BusinessPlan3rdQ96.doc.htm"> Third Quarter 1996 Business Plan</a><p>
Figure 12.12 shows what this will look like before and after selecting the hyperlink. Notice that the title, the header, and all the text, including the hyperlink, whose path is shown at the bottom, are in uppercase letters.
Figure 12.12. Before and after selecting the sample \UC hyperlink.
Although there are currently some very powerful tools for the Web, the ActiveX ISAPI filters bring the Web closer to business applications. The Web is constantly evolving, providing new challenges to businesses who use it or actually live on it. With
the capabilities of the filters and other ActiveX technologies, application programmersand the people who increase their productivity by using their applicationsare the beneficiaries.
You will see the other half of the ISAPI story in the next chapter. Chapter 13, "Developing Web Applications Using ISAPI Extensions," explains how to write an ISAPI extension DLL that processes CGI. You'll even learn how to find information
about avocados on the Internet!