|  | Click Here!

Search the site:
EXPERT SEARCH

| Programming Languages
| Databases
| Security
| Web Services
| Network Services
| Middleware
| Components
| Operating Systems
| User Interfaces
| Groupware & Collaboration
| Content Management
| Productivity Applications
| Hardware
| Fun & Games

EarthWeb sites
Crossnodes
Datamation
Developer.com
DICE
EarthWeb.com
EarthWeb Direct
ERP Hub
Gamelan
GoCertify.com
HTMLGoodies
Intranet Journal
IT Knowledge
IT Library
JavaGoodies
JARS
JavaScripts.com
open source IT
RoadCoders
Y2K Info

- 12 — Controlling the Internet Information Server Through ActiveX ISAPI Filters

- ActiveX ISAPI Filter Technology

- ActiveX and Business
- Event Notification Paradigm
- URL-Mapping ActiveX ISAPI Filter

- Creating a Filter with VC++ 4.1 ISAPI Extension Wizard
- Implementing the Example
- Testing the Filter

- Implementation Ideas: How to Use This Technology
- Conclusion
- What's Next

#
12 — Controlling the Internet Information Server Through ActiveX ISAPI Filters

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 databases—like 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.

TIP
The CVTDOC ISAPI filter sample and a Word document describing how to use it are available in the ActiveX SDK in the INetSDK\samples\Isapi\CvtDoc directory. To run this software, you need Windows NT Server 3.5.1 running Internet Information Server (IIS) 2.0. You can get IIS 2.0 free from Microsoft at http://www.microsoft.com/infoserv/.

##
ActiveX ISAPI Filter Technology

ActiveX ISAPI filter technology offers several different types of filtering; some are listed briefly here:

- Enhanced/customized logging capabilities
- Enhanced/customized authentication capabilities
- Data conversion/compression/encryption on the fly
- URL mapping

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.

###
ActiveX and Business

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.

NOTE
The sample code presented later on in the chapter is on the CD-ROM included with this book. You can copy it, compile it, if you like—provided you have Visual C++ 4.1 or later—and run or test it on a PC. The operating system this code was tested on was Windows NT Server 3.5.1 and IIS 2.0, since there was not a version available for any other operating system at the time of this writing in May 1996. As a matter of fact, the IIS this was tested with was the beta version. However, it is not likely that anything that would significantly affect the code will change since the MFC layer allows a layer of protective abstraction from the specification—another nice quality of using MFC.

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 inexpensive—both for processing and memory-wise—compared to starting a new CGI process.

NOTE
Threading means what it sounds like. A process can start a new "thread" to manage a chunk of processing while the main "thread" continues its normal processing. This is a particularly nice trick for a heavily user-interface-driven application or, in fact, any type of processing in which you want a fast response time. This allows the program to return to its main task while separate threads within its process space process requests. The main thread then spends most of its time processing requests—creating threads or communicating with other threads to have the other threads do the actual results processing. Typically, a threaded process can be broken into one main thread that processes requests and one or more additional threads for processing results and probably returning the results back to the main thread, which routes the results back to the requester. For a GUI application, this means you have immediate GUI response time—Internet Explorer and Netscape Navigator are good examples of this type of threading, allowing for asynchronous GUI and URL processing. Likewise, the IIS HTTP server uses this threading to process HTTP requests, hand them off to threads that communicate to their ISAPI extension and filter DLLs, and turn around and wait for the next HTTP request

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.

NOTE
There is an equivalent CGI technology related to ISAPI filters called ISAPI extension DLLs. In Chapter 13, "Developing Web Applications Using ISAPI Extensions," you will find a sample ISAPI extension DLL with code.

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 format—for 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.

NOTE
Refer back to Chapter 5, "ActiveX Documents," for background on OLE DocObjects; Chapter 6, "ActiveX Controls," to review those controls; and Chapter 7, "ActiveX Scripting," for information on ActiveX scripting.

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 filter—to 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.

###
Event Notification Paradigm

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 paradigm—the 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 notified—or called—for the events specified to IIS during Server startup.

NOTE
The priority is specified by the DLLs in a structure returned from the GetFilterVersion() entry point into the DLL. Initially, when an IIS service (WWW, FTP, or Gopher) is started, each of the filter DLLs are loaded; this entry point routine is called to collect information on each filter. The information returned includes the filter version, a descriptive string, and a bitmask flag indicating filter priority, what types of notifications to send it, and whether to be notified for secure and non-secure ports.

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.

    Notification flags
SF_NOTIFY_READ_RAW_DATA | Before data is read by the server
SF_NOTIFY_SEND_RAW_DATA | Before data is sent to the client
SF_NOTIFY_PREPROC_HEADERS | Before processing the client headers
SF_NOTIFY_AUTHENTICATION | Before secure client connection
SF_NOTIFY_URL_MAP | Before reading the data
SF_NOTIFY_LOG

For logging

NOTE
The HttpFilterProc() entry point into the filter DLL is called for event notifications. Refer to Chapter 8, "ActiveX Internet Information Server," for information on ISAPI filters and extension DLLs.

TIP
During the event notification cycle, more than one filter may be called for the same event. If a particular ISAPI filter wants to be the only one dealing with a particular instance of an event, it may return SF_STATUS_REQ_HANDLED_NOTIFICATION to indicate that no other DLLs should be notified. This can apply to URL Map events; if your filter DLL handles the request, you probably don't want any other filter to further map the URL, but this is not the rule.

###
URL-Mapping ActiveX ISAPI Filter

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.

####
Creating a Filter with VC++ 4.1 ISAPI Extension Wizard

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.

CAUTION
To be safe, you might want to select the "As a statically-linked library" from the "How would you like to use the MFC library?" option because otherwise you would have to carry the MFC libraries with you and install them on the target Windows NT server. If you don't have VC++ 4.1 installed, then you have to install the shared DLL in the System32 directory, adding a level of complexity to your installation and debugging.

Figure 12.7 shows what the Wizard looks like after these selections have been made to the first page.

Figure 12.7. ISAPI Extension Wizard—Step 1 of 2.

Now click the Next button, which opens the ISAPI Extension Wizard—Step 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 Wizard—Step 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.

TIP
There is a trick to debugging ISAPI filters. I found the information in Technical Note 63 using the integrated InfoView in VC++ 4.1. To find this information, go to the Project Workspace window, on the InfoView tab, under Visual C++ Books\MFC 4.1\MFC Technical Notes\MFC Technical Note Index\TN063: Debugging Internet Extension DLLs.
Basically the Technical Note says to use IIS directly as the program to debug. To set this up, choose Build | Settings from the menu to bring up the Project Settings dialog box and select the Debug tab. In the "Executable for debug session" field, enter the path to the IIS executable—the default install path is c:\INetsrv\Server\Inetinfo.exe. In the "Program arguments" field, enter -e W3Svc. You must also stop all three "publishing services" (WWW, Gopher, FTP) by using the Internet Information Server Manager or choosing Control Panel | Services from the menu.

####
Implementing the Example

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.

NOTE
After compiling the code, you have to add the path to your DLL to the Filter DLLs value in the registry under the following key:
"HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\W3Svc\Parameters\"

####
Testing the Filter

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

###
Implementation Ideas: How to Use This Technology

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.

###
Conclusion

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 programmers—and the people who increase their productivity by using their applications—are the beneficiaries.

###
What's Next

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!

| Use of this site is subject certain Terms & Conditions. Copyright (c) 1996-1999 EarthWeb, Inc.. All rights reserved. Reproduction in whole or in part in any form or medium without express written permission of EarthWeb is prohibited. Please read our privacy policy for details.