Writing a Plugin for Microsoft Internet Information Server, by Joseph A. Bank (jbank@arsdigita.com)
Submitted on: 2000-10-20
ArsDigita : ArsDigita Systems Journal : One article
The two most obvious solutions have some fundamental problems:
Microsoft supports two ways of extending IIS: ISAPI
extensions and ISAPI filters. An ISAPI extension is conceptually
similar to a traditional CGI program. The ISAPI extension is given
information about the request from IIS and returns a Web page to IIS.
Unlike CGI, an ISAPI extension is loaded once and has access to a
more powerful set of APIs. An ISAPI filter does not have a CGI
equivalent. An ISAPI filter is given access to both sides of the
communication stream and can modify it at various points. For
example, an ISAPI filter can provide encryption by modifying the input
and output stream. Both ISAPI filters and ISAPI extensions are
implemented with dynamically loaded libraries (dll's).
AOLserver is an extensible multi-threaded Application Server. It's
modular architecture supports various dynamically loaded extensions.
In fact, the standard Web server communication support is handled
by an easily replaced module. This architecture
allows new communication modules to be seamlessly added without any
modification to the core AOLserver code or the code using the AOLserver
APIs.
Using ISAPI solves our problem. We can use ISAPI dll's to run
AOLserver "inside" of IIS and thus get the full set of AOLserver APIs
without requiring any changes in ACS. Since AOLserver is open-source,
we can modify AOLserver to create an ISAPI dll that uses IIS for the
communication and AOLserver to produce content.
The flexibility of ISAPI provides a number of different ways we could
implement our basic idea. In this section, we describe the method we
choose and then discuss the alternatives.
We choose to implement the AOLserver API by combining both an ISAPI
extension and an ISAPI filter. Most of the work is done by the
ISAPI extension, which implements all of the AOLserver functionality.
The ISAPI filter is used only for mapping URLs.
Processes involved in running ACS using IIS.
An example helps to illustrate this design. Without using the ISAPI
filter, a url might look like
The ISAPI filter gives a flexible way to remap URL's to use the ISAPI
extension. For example, on the acs-on-iis site, the url
The table below describes in more detail the steps involved in handling an
HTTP request using this architecture.
The current version of the ISAPI filter shows an example of the type
of flexibility this architecture provides. It supports an option to
use the hostname of the URL to determine whether or not to use the
AOLserver ISAPI extension. For example, by configuring a single IIS
machine respond to both "acs-on-iis.arsdigita.com" and
"normal-iis.arsdigita.com", any requests for
"acs-on-iis.arsdigita.com" will be redirected to use the AOLserver
extension and any requests for "normal-iis.arsdigita.com" will not be
redirected. Further extensions to this architecture would be very
straightforward. For example, to use the bboard module of the
ACS, you could modify the ISAPI filter to redirect urls starting
with /bboard to use the AOLserver ISAPI extension.
Note: A similar architecture is used by the Tomcat open-source Java
Servlet Engine plugin for IIS.
Since we'd like to be able to support arbitrary URL's, using an ISAPI
extension alone was not an option. When using an ISAPI extension alone, all
requests would look like .../nsisapi_extension.dll?..., which is
unacceptable because it would require changing the HREF links in all
ACS pages. We considered some different ways to divide the work
between an ISAPI filter and extension, and we considered how to pass data between the
two, but those design choices were fairly minor. The other main
option that we considered was to use an ISAPI filter alone and drop
the ISAPI extension.
There are a couple of different reasons that we felt a design that
used an ISAPI filter alone was inferior:
Development of the AOLserver ISAPI filter and extension for IIS
required a small set of tools. First, Microsoft Windows 2000
Professional or Server is needed. IIS 5.0 is bundled with both
versions of Windows. The AOLserver source distribution
includes a configuration for building AOLserver using Microsoft Visual
C++, so we used the integrated compiler and debugger of Visual C++.
Visual C++ also comes with Microsoft Developer Network CDs, which
includes API documentation and examples. For my own development, I
also use Emacs and various Cygnus "cygwin" tools. It would probably work
to use the gcc compiler and gdb debugger instead of Visual C++.
The overall project of getting the ArsDigita Community System to run
under IIS took two calendar weeks, of which the actual coding time was
two days. A majority of the time was spent in setting up a
development environment, learning the AOLserver code, and reading the
ISAPI specification.
The project was divided into four major steps:
Areas for improvement include the following:
Developing an ISAPI filter and ISAPI extension was a quick and
effective way of integrating an open source application server with
IIS. You can download both a binary and source version of the
AOLserver ISAPI Filter from http://www.arsdigita.com/download.
Even if you don't want to use AOLserver, it serves as a good example
of how ISAPI works.
Last updated: 2000-10-20
Running an open-source Web application in a Microsoft world doesn't
seem like a natural fit. However, ignoring the Microsoft world
neglects a sizeable user community. With a couple of weeks of effort,
we were able to get our open-source Web Application running on Windows
2000 using Microsoft's Internet Information Server (IIS).
Our Problem: How do I get ACS to run on IIS?
ArsDigita has developed a large body of source code implementing a
proven data model and workflow called the ArsDigita Community System
(ACS). IIS is one of the most popular Web servers. IIS has both a
large entrenched user base and an assortment of software support. The
basic problem is then simply: How can I get these two useful tools,
ACS and IIS, to work together?
Solution 1 will often be unacceptable for an organization already
using IIS. For someone starting from scratch who wants to run
ACS on Windows 2000, using AOLserver directly would be the recommended
course of action. However, for an organization that is depending on
an installed base of Active Server Pages in Visual Basic or a
commercial add-on to IIS, porting to AOLserver is not viable.
As for Solution 2, porting ACS would be a large effort. ACS was
developed using AOLserver, a free open-source application server with
a rich set of APIs. The APIs provided by AOLserver are
not directly supported by IIS. Porting ACS to the standard API's
supported by IIS such as Active Server Pages in Visual Basic would be
both a long and difficult process. Additionally, one of the selling
points of ACS is that ArsDigita's 150+ developers release an improved
version every 6-8 weeks. The developers are charged with building the
best solutions to the world's collaboration problems. We do not want
to distract them with having to maintain a VB version in addition to
the two current versions (AOLserver TCL API and 100% Java).
Our Choice: Use both.
There is a way around the problems associated with
the other two solutions: IIS supports an extension API called
Internet Server API (ISAPI).
Architecture
This request has the effect of sending the "/bboard" argument to
AOLserver as if AOLserver received an HTTP request for "/bboard".
http://acs-on-iis.arsdigita.com/aolserver/nsisapi_extension.dll?/bboard
is internally rewritten to
http://acs-on-iis.arsdigita.com/bboard
This change causes IIS to use the AOLserver ISAPI extension
to handle the request.
http://acs-on-iis.arsdigita.com/aolserver/nsisapi_extension.dll?/bboard
Note that all of the components are part of the same Windows process.
Component
Thread
Description
IIS
T1
HTTP request for "/bboard" is received by IIS.
ISAPI Filter
T1
IIS invokes the ISAPI filters on the request. As a result the request is changed from "/bboard" to "/aolserver/isapi_extension.dll?/bboard".
IIS
T1
IIS dispatches on the request, invoking the ISAPI extension.
ISAPI Extension
T1
The ISAPI extension queues a new IIS_Connection object representing the request into an AOLserver request queue.
ISAPI Extension
T1
The ISAPI extension returns "HSE_STATUS_PENDING" indicating that the request will be handled asynchronously.
AOLserver
T2
An AOLserver thread running in the ISAPI extension takes the request off of the queue and starts to process it.
AOLserver
T2
AOLserver executes the Tcl script found in /bboard/index.tcl, making various queries to an Oracle Database.
AOLserver
T2
AOLserver returns data for the page by writing to the IIS_Connection object.
ISAPI Extension
T2
The IIS_Connection object writes to the IIS request object.
IIS
T2
IIS sends data to the requesting client.
AOLserver
T2
AOLserver calls close on the Connection object.
ISAPI Extension
T2
The IIS_Connection object signals to IIS that the request object can be freed.
IIS
T2
IIS closes the connection to the client and frees the request object.
Other Architecture Options
Required Tools
What Happened
Future Work
Summary
asj-editors@arsdigita.com
Reader's Comments
As far as I can tell from this document, the exact same result could have been achieved in less than an hour by setting up the load balancer to forward certain URLs to different servers. This too would give you both ASP and ACS content on the same hostname.
-- Bas Scheffers, December 29, 2001