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.
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 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.
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 likeprovided you have Visual C++ 4.1 or
laterand 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 specificationanother 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 inexpensiveboth for processing and
memory-wisecompared 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 requestscreating 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 timeInternet 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
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.
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 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.
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.
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.
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
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.
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
executablethe 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.
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\\"
stringindex = 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\"
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 inpVer->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:
<HEAD>
<TITLE>Upper Case Test</TITLE>
</HEAD>
<H3>This code should appear in uppercase</H3>
<P>
<A HREF="FileStor\BusinessPlan3rdQ96.doc.htm">Third Quarter 1996 Business Plan</A>
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!