HTTP Module Description

Description and samples
Table of Contents
Summary

Description of how to implement a custom (i.e. not built-in) HTTP module.

Description

An HTTP module is an assembly that is called on every request that is made to a web application.

An HTTP module is called as part of the request pipeline described on the article How IIS handles incoming ASP.NET requests, and according the subscribed events it allow to:

  • Examine incoming requests and take action based on the request’s context contents;
  • Examine the outgoing response and modify it.

ASP.NET HTTP modules are like ISAPI filters because they are invoked for all requests.

However, they are written in managed code and are fully integrated with the life cycle of an ASP.NET application.

How it works

A new custom HTTP module implemented in .NET can respond to any event of the ASP.NET pipeline (II6.0 version and previous) or the integrated pipeline on the II7.x and later versions.

This is achived by:

  1. Subscribe to one or more events at instantiation;
  2. Implement the HTTP module in a separated DLL or as an application item in the ASP.NET App_Code directory;
  3. The HTTP module must be registered on the web application. This configuration can be done on the “web.config” configuration file of each web application or for all aplications on the “machine.config” file.

When ASP.NET creates an instance of the HttpApplication class representing the web application
all the module assemblies that have been registered are initialized and the appropriated methods
binded to each event are invoked.

During event handling, the module can have access to the “HttpRequest::Context” property of the current request and therefore:

  • Redirect the request to an alternative page;
  • Modify the request;
  • Check authentication;
  • Log request and response details;
  • etc.

When a module’s event handler has finished running, ASP.NET calls the next process in the pipeline.
This can be:

  • Another custom or native module; or at the end
  • The appropriated HTTP handler.
Globalization File

The same functionality of a module can be obtained in the application’s Global.asax file,
which enables to respond to some application events.

Module or Global.asax ?

A module should be implemented when:

  • The module is to be re-used in other applications;
  • No complex code is desirable the Global.asax file;
  • The module applies to all requests in the pipeline (IIS 7.0 Integrated mode only).

The Global.asax file should be used when:

  • The application events that are not available to modules, needs to be subscribed (e.g. Application_Start);
  • The code is not to be reused

IIS 5.x and IIS 6.x

In order to make possible HTTP modules to execute at beggining of each request on IIS verions prier than 7, a wildcard mapping must be configured as described on this article.

Operations
How to create an HTTP module
How to do it
using System;
using System.Web;
using System.Web.SessionState;

public class helloworldModule : IHttpModule
{
    public helloworldModule()
    {
    }

    public String ModuleName
    {
        get { return "HelloWorldModule"; }
    }

    // In the Init function, register for HttpApplication events by adding handlers.
    public void Init(HttpApplication pApplication)
    {
        pApplication.BeginRequest +=
            (new EventHandler(this.Application_BeginRequest));
        pApplication.EndRequest +=
            (new EventHandler(this.Application_EndRequest));

        IHttpModule sessionModule = pApplication.Modules["Session"];
        if (sessionModule != null &&
            sessionModule.GetType() == typeof(System.Web.SessionState.SessionStateModule))
        {
            (sessionModule as System.Web.SessionState.SessionStateModule).Start
              += new EventHandler(Application_SessionStart);
        }
    }

    private void Application_SessionStart(Object source, EventArgs e)
    {
        HttpContext ctx = HttpContext.Current;
        SessionStateModule mod = (SessionStateModule)source;

        string filePath = ctx.Request.FilePath;
        string fileExtension = VirtualPathUtility.GetExtension(filePath);

       ctx.Response.Write("<h1><font color=red>" +
                "helloWorldModule: Session start" +
                "</font></h1><hr>");
    }

    private void Application_BeginRequest(Object source, EventArgs e)
    {
        //HttpContext ctx = HttpContext.Current;
        HttpApplication app = (HttpApplication)source;
        HttpContext ctx = app.Context;

        string filePath = ctx.Request.FilePath;
        string fileExtension = VirtualPathUtility.GetExtension(filePath);

        if (fileExtension.Equals(".aspx"))
        {
            ctx.Response.Write("<h1><font color=red>" +
                "helloWorldModule: Beginning of Request (ASP.NET page)" +
                "</font></h1><hr>");
        }
    }

    private void Application_EndRequest(Object source, EventArgs e)
    {
        HttpApplication app = (HttpApplication)source;
        HttpContext ctx = app.Context;

        string filePath = ctx.Request.FilePath;
        string fileExtension = VirtualPathUtility.GetExtension(filePath);

        if (fileExtension.Equals(".aspx"))
        {
            ctx.Response.Write("<hr><h1><font color=red>" +
                "HelloWorldModule: End of Request</font></h1>");
        }
    }

    public void Dispose() { }
}
<configuration>

	<!-- Configuration for II6 and prior versions -->
	<system.web>

		<httpModules>
			<!--
				<add type="[COM+ Class], [Assembly]" name="[ModuleName]" />
				<remove type="[COM+ Class], [Assembly]" name="[ModuleName]" />
				<clear />
		   -->
		   <add name="helloworldModule" type="helloworldModule"/>
		</httpModules>

	</system.web>

	<!-- Configuration for II7 and prior versions -->
	<system.webServer>

		<modules>
		   <!--
				<add type="[COM+ Class], [Assembly]" name="[ModuleName]" />
				<remove type="[COM+ Class], [Assembly]" name="[ModuleName]" />
				<clear />
		   -->
		   <add name="helloworldModule" type="helloworldModule"/>
		</modules>

	</system.webServer>

</configuration>