Understanding IIS 7.0 Architecture : Request Processing in Application Pool

In IIS 7.0, two modes are available for an application pool: Integrated mode and Classic mode. When you configure an application pool with Integrated mode, IIS 7.0 processes ASP.NET requests using the integrated IIS and ASP.NET request processing pipeline. When you configure an application pool with Classic mode, IIS 7.0 processes ASP.NET requests using the separate IIS and ASP.NET request processing pipelines, as in IIS 6.0.

Application pools configured with different modes can run on the same server machine. You can specify the mode for an application pool by configuring the Managed Pipeline Mode setting in IIS Manager.

To use IIS Manager to configure the ASP.NET processing mode for an application pool, perform the following steps:

  1. In IIS Manager, expand the server node and select the Application Pools node in the Connections pane.
  2. On the Application Pools page, select the application pool you’d like to configure.
  3. In the Actions pane, under Edit Application Pool, select Basic Settings.
  4. In the Edit Application Pool dialog box, in the Managed Pipeline Mode drop-down list, choose the desired mode (Integrated or Classic) and click OK.

Classic Mode

Classic mode in IIS 7.0 provides backward compatibility with IIS 6.0. When an application pool is in Classic mode, IIS 7.0 processes ASP.NET requests using two separate IIS and ASP.NET request processing pipelines, as in IIS 6.0. To understand Classic mode in IIS 7.0, let’s first look into how ASP.NET requests are processed in IIS 6.0.

Figure 1 shows ASP.NET request processing in IIS 6.0. In IIS releases up to version 6.0, ASP.NET connects to the Web server as a stand-alone application framework. In these releases, ASP.NET is implemented as an IIS Internet Server Application Programming Interface (ISAPI) extension.

Figure 1. ASP.NET request processing in IIS 6.0.

In IIS 6.0, the ASP.NET ISAPI extension (aspnet_isapi.dll) is responsible for processing the content types that are registered to it, such as ASPX and ASMX. For those requests, it offers powerful features, for example, Forms Authentication and Response Output Caching. However, only content types registered to ASP.NET can benefit from these services. Other content types—including ASP pages, static files, images, and Common Gateway Interface (CGI) applications—have no access to these features at all.

A request to an ASP.NET content type is first processed by IIS and then forwarded to aspnet_isapi.dll that hosts the ASP.NET application and request processing model. This effectively exposes two separate server pipelines, one for native ISAPI filters and extension components, and another for managed application components. ASP.NET components execute entirely inside the ASP.NET ISAPI extension and only for requests mapped to ASP.NET in the IIS script map configuration. Requests to non-ASP.NET content, such as ASP pages or static files, are processed by IIS or other ISAPI extensions and are not visible to ASP.NET.

In addition, even for ASP.NET resources, certain functionalities are not available to ASP.NET because of run-time limitations. For example, it is not possible to modify the set of outgoing HTTP response headers before they are sent to the client because this occurs after the ASP.NET execution path.

In IIS 7.0 in Classic mode, ASP.NET requests are also processed using the ASP.NET ISAPI extension, as shown in Figure 2. The core Web server in IIS 7.0 is fully componentized, whereas in IIS 6.0, it is monolithic. However, the ASP.NET requests in Classic mode are processed by asnet_isapi.dll in the same way as in IIS 6.0. After the request has been processed by asnet_isapi.dll, it is routed back through IIS to send the response.

Figure 2. ASP.NET request processing in Classic mode in IIS 7.0.

Classic mode in IIS 7.0 has the same major limitations as ASP.NET processing in the IIS 6.0. In summary, these limitations are as follows:

  • Services provided by ASP.NET modules are not available to non-ASP.NET requests.
  • Some processing steps are duplicated, such as authentication.
  • Some settings must be managed in two locations, such as authorization, tracing, and output caching.
  • ASP.NET applications are unable to affect certain parts of IIS request processing that occur before and after the ASP.NET execution path due to the placement of the ASP.NET ISAPI extension in the server pipeline.

Classic mode is provided only for backward compatibility with IIS 6.0. Simply put, you should add an application to an application pool in Classic mode only if the application fails to work in Integrated mode.

.NET Integrated Mode

When an application pool is configured with .NET Integrated mode, you can take advantage of the integrated request processing architecture of IIS 7.0 and ASP.NET.

In IIS 7.0, ASP.NET run time is integrated with the core Web server. The IIS and ASP.NET request pipelines are combined, providing a unified (that is, integrated) request processing pipeline that is exposed to both native and managed modules.

The IIS 7.0 request processing pipeline is implemented by the core Web server engine. It enables multiple independent modules to provide services for the same request. All of the Web server features are implemented as stand-alone modules. There are over 40 separate native and managed modules. Each module implements a particular Web server feature or functionality, such as logging or output caching.

Native modules are implemented as dynamic-link libraries (DLLs) based on public IIS 7.0 C++ extensibility APIs. Managed modules are implemented as managed .NET Framework classes based on the ASP.NET integration model in IIS 7.0. (IIS 7.0 has integrated the existing IHttpModule API for ASP.NET.) Both of these APIs enable modules to participate in the IIS 7.0 request processing pipeline and access all events for all requests.

An IIS 7.0 integrated request processing pipeline is shown in Figure 3. A pipeline is an ordered list consisting of native and managed modules that perform specific tasks in response to requests. When a worker process in an application pool receives a request from HTTP.sys, the request passes through an ordered list of stages. As a result of processing, the response is generated and sent back to HTTP.sys.

Each stage in the pipeline raises an event. Native and managed modules subscribe to events in the stages of the pipeline that are relevant to them. When the event is raised, the native and managed modules that subscribe to that event are notified and do their work to process the request. The pipeline event model enables multiple modules to execute during request processing.

Figure 3. IIS 7.0 integrated processing pipeline.

Most of the pipeline events are intended for a specific type of task, such as authentication, authorization, caching, and logging. The following list describes stages and corresponding events in the request processing pipeline:

  • Begin Request stage. This stage starts request processing. The BeginRequest event is raised.

  • Authenticate Request stage. This stage authenticates the requesting user. The AuthenticateRequest event is raised.

  • Authorize Request stage. At this stage, the AuthorizeRequest event is raised. This stage checks access to the requested resource for the authenticated user. If access is denied, the request is rejected.

  • Resolve Cache stage. At this stage, ResolveRequestCache event is raised. This stage checks to see if the response to the request can be retrieved from a cache.

  • Map Handler stage. At this stage, the MapRequestHandler event is raised. This stage determines the handler for the request.

  • Acquire State stage. At this stage, the AcquireRequestState event is raised. This stage retrieves the required state for the request.

  • Pre-execute Handler stage. At this stage, the PreExecuteRequestHandler event is raised. This stage signals that the handler is about to be executed and performs the preprocessing tasks if needed.

  • Execute Handler stage. At this stage, the ExecuteRequestHandler event is raised. The handler executes and generates the response.

  • Release State stage. At this stage, the ReleaseRequestState event is raised. This stage releases the request state.

  • Update Cache stage. This stage updates the cache. The UpdateRequestCache event is raised.

  • Log Request stage. At this stage, the request is logged. The LogRequest event is raised.

  • End Request stage. At this stage, the EndRequest event is raised, which signals that the request processing is about to complete.

Modules that subscribe to an event provide specific services appropriate for the relevant stage in the pipeline. For example, Figure 4 shows several native and managed modules that subscribe to the AuthenticateRequest event at the Authenticate Request stage, such as the Basic Authentication module, the Windows Authentication module, the ASP.NET Forms Authentication module, and the Anonymous Authentication module. Basic, Windows, and Anonymous Authentication modules are native modules, whereas Forms Authentication is a managed module.

.NET integrated pipeline provides several key advantages over previous versions of IIS, as follows:

  • Allowing services provided by both native and managed modules to apply to all requests.

    All file types can use features that in IIS 6.0 are available only to managed code. For example, you can now use ASP.NET Forms authentication and Uniform Resource Locator (URL) authorization for static files, ASP files, CGI, static files, and all other file types in your sites and applications.

  • Eliminating the duplication of several features in IIS and ASP.NET.

    For example, when a client requests a managed file, the server calls the appropriate authentication module in the integrated pipeline to authenticate the client. In previous versions of IIS, this same request goes through an authentication process in both the IIS pipeline and the ASP.NET pipeline. Other unified IIS and ASP.NET functionality includes URL authorization, tracing, custom errors, and output caching.

  • Managing all of the modules in one location, thus simplifying site and application administration on the server.

    Instead of managing some features in IIS and some in the ASP.NET configuration, there is a single place to implement, configure, monitor, and support server features. For example, because of the run-time integration, IIS and ASP.NET can use the same configuration for enabling and ordering server modules, as well as configuring handler mappings.

  • Extending IIS with ASP.NET managed modules.

    IIS 7.0 enables ASP.NET modules to plug directly into the server pipeline, in the same way as modules developed with the native C++ IIS API. ASP.NET modules can execute in all run-time stages of the request processing pipeline and can be executed in any order with respect to native modules. The ASP.NET API has also been expanded to allow for more control over request processing than was previously possible.

Figure 4. Native and managed modules in the integrated processing pipeline.

How ASP.NET Integration Is Implemented

Though native and managed modules implement the same logical module concept, they use two different APIs. To enable an integrated pipeline model for both native and managed modules, IIS 7.0 provides a special native module called Managed Engine. The Managed Engine module in effect provides an integration wrapper for ASP.NET modules that enables these managed modules to act as if they were native IIS modules and handlers. It acts as a proxy for event notifications and propagates a required request state to the managed modules. Together with the ASP.NET engine, it sets up the integrated pipeline and is also responsible for reading the managed modules and handlers configuration.

When a request requires a managed module, the Managed Engine module creates an AppDomain where that managed module can perform the necessary processing, such as authenticating a user with Forms authentication. Figure 5 shows the Managed Engine module, with the managed Forms Authentication module executing within an AppDomain.

Figure 5. Managed Engine module.

All managed modules are dependent on the Managed Engine module, and they cannot execute without it. For the integrated pipeline and ASP.NET applications to work, the Managed Engine module must be installed and enabled in IIS 7.0.

In Windows Server 2008, the Managed Engine module is installed as a part of the Role Service component and .NET Extensibility Component. In Windows Vista, it is installed as a part of the .NET Extensibility component.

Module Scope

Modules can be installed and enabled on different levels. Modules that are enabled on the server level provide a default feature set for all applications on the server. The IIS global configuration store, applicationHost.config, provides the unified list of both native and managed modules. Each time WAS activates a worker process, it gets the configuration from the configuration store, and the worker process loads all globally listed modules.

Native modules can be installed only at the server level. They cannot be installed at the application level. At the application level, the global native modules that are enabled at the server level can be removed, or those that are installed but not enabled globally can be enabled for that application.

Managed modules can be added at the server, site, and application levels. Application-specific modules are loaded upon the first request to the application. Application managed modules can be xcopy-deployed together with other application files.

You can manage both native and managed modules using the Modules feature in IIS Manager.

Module Ordering

The pipeline model ensures that the typical Web server processing tasks are performed in the correct order. For example, authentication must happen before authorization: authenticating the user associated with a request at the Authenticate Request stage has to happen before checking that user’s access to the requested resource at the Authorize Request stage.

The server uses the sequence of modules list in the <modules> configuration section to order module execution within each request processing stage. By executing during the relevant stage, the majority of modules automatically avoid ordering problems. However, multiple modules that execute within the same stage may have ordering dependencies. For example, the built-in authentication modules that run at the Authenticate Request stage should be executed in the strongest to weakest order so that the request is authenticated with the strongest credentials available.

To manage ordering dependencies, the administrator can control the ordering of modules by changing the order in which they are listed in the <modules> section. This can be done, for example, using the Modules feature in IIS Manager.

To view, and optionally change, the ordered list of modules for a server, perform the following steps:

  1. In IIS Manager, in the Connections pane, select the server node.
  2. In the server’s home page, open the Modules feature.
  3. In the Actions pane, click View Ordered List.
  4. You can change a position of a module in the processing sequence by selecting the module and then using Move Up and Move Down options in the Action pane to move it to the desired position in the list.