The Windows Vista and Windows Server 2008 Developer Story: IIS Modules
Microsoft Corporation
April 2006
Revised January 2007
The Windows Vista and Windows Server 2008 Developer Story includes content for developers, and other technology experts and managers, interested in an in-depth exploration of some of the new and extended features in Windows Vista. It is released to the Windows Vista Developer Center in the form of Articles, published approximately one every two weeks. Those Articles are only a summary of the Windows Help file, which can be downloaded here.
Note To provide feedback about the articles, please send e-mail to Vistadev@microsoft.com.
Contents
Introduction
Creating Win32 HTTP Modules
The RegisterModule Function
The CHttpModule-Derived Class
The Module Factory
Creating ASP.NET Managed Extensions
HTTP Handlers
HTTP Modules
IIS Operation Modes and Interoperability
See Also
Introduction
IIS 7 has a completely new architecture that contains a core server containing a unified pipeline with notifications available to IIS & ASP.NET developers. This core engine relies upon modules to perform HTTP request processing and related services, such as user authentication, authorization, and compression. IIS 7.0 has componentized functionality into various modules that expose features of IIS and ASP.NET.
This architecture is extensible, allowing third parties to readily develop modules through either Win32 or ASP.NET interfaces. In either case, creating a module is relatively straightforward. It is the addition of notification-based, robust, scalable processing logic that demands more consideration and effort.
Creating Win32 HTTP Modules
A Win32 IIS module is a DLL that meets the following three requirements:
- It implements and exports a
RegisterModule
function. This function is called by the core server engine to register the extension after an entry for it is read from the globalModules section of the applicationhost.config file.RegisterModule
serves three primary purposes: it specifies the notifications that the module will handle, specifies the relative processing priority for the module, and provides the core engine access to the module factory. - It implements a public class derived from
CHttpModule
. This class represents the primary functionality for the extension module, which is implemented in a set of virtual functions that handle notifications. - It implements a module factory derived from the
IHttpModuleFactory
interface (virtual class). This class creates an instance of theCHttpModule
-derived class for your extension.
Public declarations for the native-mode HTTP Server API (which includes declarations for RegisterModule
, CHttpModule
, and IHttpModuleFactory
) are contained in the file httpserv.h
.
The RegisterModule Function
This function has the following prototype:
HRESULT WINAPI RegisterModule(
// IIS version
DWORD dwServerVersion,
// module's registration
IHttpModuleRegistrationInfo* pModuleInfo,
// describes and controls the core engine
IHttpServer* pGlobalInfo
);
The parameters may be optionally used by the extension module to adapt to the current server state, request server functions, or modify the server environment.
The pModuleInfo
parameter is used to set the characteristics associated with the module. The IHttpModuleRegistrationInfo
class has the following members for this purpose:
Member | Description |
---|---|
SetGlobalNotifications |
Specifies which global events the module should be notified of. |
SetPriorityForGlobalNotification |
Specifies the relative priority of the module in the chain of modules that handle global events. |
SetRequestNotifications |
Specifies which request processing events the module should be notified of. This function also specifies the module factory that the server engine uses to instantiate the extension module. |
SetPriorityForRequestNotification |
Specifies the relative priority of the module in the chain of modules that handle request processing events. |
A collection of constants, to represent the notification events and the relative priorities, are provided to use when invoking these member functions. For more information, see IIS Request-Processing Constants in the Windows SDK.
The RegisterModule
function must be exported in a standard fashion: either by specifying this in the module definition (.def) file for the project, or by using the /EXPORT:RegisterModule
compiler switch.
The CHttpModule-Derived Class
Each extension module must have a single class derived from CHttpModule
that contains the primary module functionality. In addition to a constructor and a Dispose
method, this class contains, for each server event, a virtual function of the form:
virtual
REQUEST_NOTIFICATION_STATUS
On<event-name>(
IN IHttpContext* pHttpContext,
IN OUT IHttpEventProvider* pProvider )
{
//...
return RQ_NOTIFICATION_CONTINUE;
}
For each event that was specified as being handled within the RegisterModule
function (see SetRequestNotifications
and SetGlobalNotifications
above), the corresponding virtual function should be overridden and handled properly. For example, if the AuthorizeRequest
event was registered as being handled by the module, then this derived class should override the OnAuthorizeRequest
member function. The pHttpContext
and pProvider
parameters provide additional information about the current event.
Note Although the type of
pProvider
parameter is prototyped as
IHttpEventProvider*
, it is often a derived type that corresponds to the event type. For example, the
OnAuthenticateRequest
method actually receives a second parameter of type
IAuthenticationProvider*
.
The Module Factory
A matching module factory class must be provided so that the core server engine can instantiate the main module class on demand. This class must be derived from IHttpModuleFactory
, which is a simple class consisting of two member functions:
GetHttpModule
should create an instance of the primary extension module (CHttpModule
-derived) class.Terminate
should delete and clean up the extension module in case the current process must be terminated by the core server.
For more information, including sample code, see Native-Code HTTP Modules in the Windows SDK.
Creating ASP.NET Managed Extensions
The IIS 7 unified pipeline enables managed extension modules using the standard ASP.NET extension classes. Two .NET types of extensions can be created:
- HTTP handlers—are associated with file extensions, and are invoked to service requests to their associated resource types. ASP.NET comes with several built-in handlers, including ASP.NET page handler (.aspx), Web service handler (.asmx), ASP.NET user control handler (.ascx), and trace handler (.axd).
- HTTP modules—are called on every request made to your application as part of the ASP.NET request pipeline event processing. HTTP modules are commonly used for customized functionality, such as security, statistics and logging, or customized content processing (for example, adding customized headers or footers).
All of the classes and interfaces used to create HTTP handlers and modules are found in the System.Web
namespace. Assemblies containing handlers or modules may be in the GAC, the bin
directory (most of the time), or as automatically compiled source code inside the containing Web site's App_Code
directory.
HTTP Handlers
There are several steps that are required to create an HTTP handler:
- Create an association to a file extension. By default, ASP.NET maps the file extension .ashx for custom HTTP handlers. This may be adequate for developing and testing HTTP handlers or generalized resource requests. However, if developing a dedicated handler for a particular file or information type, such as RSS feeds, it will be beneficial to map the handler to an unused file extension by explicitly registering the extension by adding an appropriate
<handlers>
entry in theWeb.config
or applicationhost.config file. - Create the handler class, the specifics of which depend upon whether the handler should respond to requests synchronously or asynchronously.
- A synchronous handler will implement the
IHttpHandler
interface. This interface contains anIsReusable
property, which indicates whether another request can use the same handler instance, and aProcessRequest
method, which performs the actual request processing, including creating the HTTP response. TheProcessRequest
method takes anHttpContext
parameter, which provides access to the intrinsic server objects (for example,Request
,Response
,Session
, andServer
). - An asynchronous handler will implement the
IHttpAsyncHandler
interface, which derives fromIHttpHandler
. This interface adds theBeginProcessRequest
method, which initiates the asynchronous processing of individual HTTP requests, and theEndProcessRequest
method, which runs cleanup code when the process ends.
- A synchronous handler will implement the
- Optionally, an associated handler factory can be created and associated with the file extension, instead of associating the handler directly with the extension. In this option, the handler factory class, which implements the
IHttpHandlerFactory
interface, dynamically determines which handler to use then creates and returns an instance of the handler. TheIHttpHandlerFactory
interface declares theGetHandler
andReleaseHandler
methods. This option is used when more flexible request handling is required.
For more information, see Introduction to HTTP Handlers in the Windows SDK.
HTTP Modules
Creating an HTTP module is relatively straightforward, and involves just the following two steps:
- Create the HTTP module by creating a class that implements the
IHttpModule
interface, which declares only two methods,Dispose
andInit
. TheInit
method should initialize the module and subscribe to any application events that require processing (for example, theBeginRequest
orPostMapRequestHandler
events). This class must therefore also contain an event handler for every subscribed event. TheDispose
method can optionally be implemented to perform cleanup. - Register the module in the
Web.config
file to associate it with one or more applications.
For more information, see Extending ASP.NET Processing with HTTP Modules in the Windows SDK.
IIS Operation Modes and Interoperability
IIS 7 offers two ways of running managed applications and extensions:
- Integrated mode—the default, preferred method of operation. An integrated pipeline processes native and managed code. It supports ASP.NET version 2.1 and above.
- ISAPI mode—the operation of previous versions of IIS by running managed code via a special ISAPI extension (
AspNet_Isapi.dll
). Although it is highly compatible with previous versions of IIS, it lacks the unified pipeline processing and some of the advanced features of integrated mode.
From the administrative perspective, configuration of IIS and ASP.NET applications are now uniform, using the new IIS configuration files, which can use the delegated XML web.config
hierarchy familiar to ASP.NET developers. Older metabase properties are mapped to section groups, sections, elements, or attributes in the IIS 7.0 configuration schema. For example, managed and native services are configured in the unified <modules>
configuration section, and handlers are configured in the unified <handlers>
configuration section. For more information, see Metabase-to-Configuration-Elements Map in the Windows SDK.
When running in integrated mode, IIS uses its own module and handler configuration instead of the <httpHandlers>
and <httpModules>
section ASP.NET developers are used to. The newer management tools and utilities uniformly work with native IIS and ASP.NET applications. In ISAPI mode, ASPNET ISAPI.DLL uses legacy elements, such as <httpModules>
and <httpHandlers>
.
From a development perspective, much of the work within ASP.NET 2.1 to support the integrated mode of IIS 7.0 is hidden to the developer. It just works. Typically, these applications will also work under ISAPI mode in IIS 7 or on a previous version of IIS, with a loss of some functionality. In those situations where a capability is supported only under IIS 7 integrated mode, the application will throw a PlatformNotSupportedException
.
See Also
Run-time Status & Control (RSCA) API
HTTP Server API (coming soon)