Share via


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 the CHttpModule-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:

  1. 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 the Web.config or applicationhost.config file.
  2. 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 an IsReusable property, which indicates whether another request can use the same handler instance, and a ProcessRequest method, which performs the actual request processing, including creating the HTTP response. The ProcessRequest method takes an HttpContext parameter, which provides access to the intrinsic server objects (for example, Request, Response, Session, and Server).
    • An asynchronous handler will implement the IHttpAsyncHandler interface, which derives from IHttpHandler. This interface adds the BeginProcessRequest method, which initiates the asynchronous processing of individual HTTP requests, and the EndProcessRequest method, which runs cleanup code when the process ends.
  3. 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. The IHttpHandlerFactory interface declares the GetHandler and ReleaseHandler 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:

  1. Create the HTTP module by creating a class that implements the IHttpModule interface, which declares only two methods, Dispose and Init. The Init method should initialize the module and subscribe to any application events that require processing (for example, the BeginRequest or PostMapRequestHandler events). This class must therefore also contain an event handler for every subscribed event. The Dispose method can optionally be implemented to perform cleanup.
  2. 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

Internet Information Services

Run-time Status & Control (RSCA) API

IIS Manager

HTTP Server API (coming soon)