ISAPI Server Extensions
An ISAPI server extension is a program (implemented as a DLL loaded by IIS) that runs in response to a GET or POST request from a client program (browser). The browser can pass parameters, which are often values that the browser user types into edit controls, selects from list boxes, and so forth, to the program. The ISAPI server extension typically sends back HTML code based on those parameter values. You'll understand this process better when you see an example.
CGI and ISAPI
Internet server programs were first developed for UNIX computers, so the standards were in place long before Microsoft introduced IIS. The Common Gateway Interface (CGI) standard, which is actually part of HTTP, evolved as a way for browser programs to interact with scripts or separate executable programs running on the server. Without altering the HTTP/CGI specifications, Microsoft designed IIS to allow any browser to load and run a server DLL. DLLs are part of the IIS process and thus are faster than scripts that might need to load separate executable programs. In this chapter, we'll write an ISAPI DLL in C++ using ATL Server. There are other ways to create Web pages, including writing PERL scripts, Active Server Pages (ASP), and ASP.NET.
CGI shifts the programming burden to the server. Using CGI parameters, the browser sends small amounts of information to the server computer, and the server can do absolutely anything with this information, including access a database, generate images, and control peripheral devices. The server sends a file (HTML or otherwise) back to the browser. The file can be read from the server's disk, or it can be generated by the program. No ActiveX controls are necessary, and the browser can be running on any type of computer.
A Simple ISAPI Server Extension GET Request
Suppose an HTML file contains the following tag:
<a href=">Idaho Weather Map</a><p>
When the user clicks on Idaho Weather Map, the browser will send the server a CGI GET request like this:
GET HTTP/1.0
IIS will then load maps.dll from its scripts (virtual) directory, call a default function (often named Default), and pass it the State parameter Idaho. The DLL will then go to work generating a JPG file containing the up-to-the-minute satellite weather map for Idaho and send it to the client.If maps.dll has more than one function, the tag can specify the function name like this:
<a href=">Idaho Weather Map</a><p>
In this case, the function GetMap will be called with two parameters, State and Res.You'll soon learn how to write an ISAPI server similar to maps.dll, but first you'll need to understand HTML forms because you don't often see CGI GET requests by themselves.
HTML Forms: GET vs. POST
In the HTML code for the simple CGI GET request above, the state name is hard-coded in the tag. Why not let the user select the state from a drop-down list? For that, you need a form, and here's a simple one that can do the job:
<html>
<head><title>Weathermap HTML Form</title>
</head>
<body>
<h1><center>Welcome to the Satellite Weathermap Service</center></h1>
<form action="scripts/maps.dll?GetMap" method=GET>
<p>Select your state:
<select name="State">
<option> Alabama
<option> Alaska
<option> Idaho
<option> Washington
</select>
<p><input type="submit"><input type="reset">
</form>
</body></html>
If you look at this HTML file with a browser, you'll see the form shown in Figure 30-6.
Figure 30-6: The Weathermap HTML Form window.
The select tag provides the state name from a list of four states, and the all-important submit input tag displays the pushbutton that sends the form data to the server in the form of a CGI GET request that looks like this:
GET scripts/maps.dll?GetMap?State=Idaho HTTP/1.0
(various request headers)
(blank line)
Unfortunately, some early versions of the Netscape browser omit the function name in form-originated GET requests, giving you two choices: provide only a default function in your ISAPI DLL or use the POST method inside a form instead of the GET method.If you want to use the POST option, you can change one HTML line in the form to the following:
<form action="scripts/maps.dll?GetMap" method=POST>
Now here's what the browser will send to the server:
POST scripts/maps.dll?GetMap
(various request headers)
(blank line)
State=Idaho
Note that the parameter value is in the last line instead of in the request line.
| Note | ISAPI DLLs are usually stored in a separate virtual directory on the server because these DLLs must have execute permission but do not need read permission. Clicking the Edit button shown in Figure 30-3 will allow you to access these permissions from Internet Service Manager, or you can double-click on a directory to change its properties. |
You can use the Internet Services API to build high-performance Web applications with low-level control under IIS. You write a DLL using C/C++, and IIS uses a DLL to filter incoming requests or respond to them. These two kinds of ISAPI DLLs are called filters and extensions, respectively.An ISAPI filter is a DLL that can receive event notifications from IIS as client requests are being processed. The filter can then modify the standard behavior of IIS. Filters can be used to provide compression, encryption, logging, and custom authentication schemes, among other things.An ISAPI extension is a DLL that can receive client requests and send responses. C++ code can often generate the HTML that is sent to the client. The extension DLL must export the GetExtensionVersion and HttpExtensionProc entry points (and optionally TerminateExtension). For every client request, an EXTENSION_CONTROL_BLOCK structure is passed from IIS to the ISAPI extension DLL through HttpExtensionProc. This structure is used to get HTTP header information, call IIS helper functions, and read and write to the client stream.In a moment, you'll see how ATL Server pushes the Extension Control Block (ECB, or EXTENSION_CONTROL_BLOCK as defined in the last paragraph) processing into a set of classes more akin to what C++ developers are used to seeing. As with most C++ code within Microsoft libraries, the ECB is still directly available from within ATL Server.With low-level ISAPI control comes responsibility. For example, useful ASP intrinsic objects such as Session and Response are not available in ISAPI, although similar functions can ultimately be accessed. Programming the ECB in a normal C or C++-based ISAPI DLL involves manipulating buffers and other low-level elements. Furthermore, when you write an ISAPI extension, you typically create a thread pool to respond to incoming client requests. For more information on ISAPI, see the MSDN Online article "Developing ISAPI Extensions and Filters."