Tuesday, January 13, 2009

What is HttpModule..When and How to write own custom http module.

You might have heard of HTTP pipelines, HTTP Handlers and HTTP Modules in past but do we really know what they are? It was same with me a few months before. We make a web request n number of times in a day and rarely thing of what the number of stages the request has gone through since we often keep it as an abstraction. Finally when I realized importance of HTTP Modules I decided to write an article about how someone should go about this.
This article will start with a brief description of HTTP protocol and understanding what HTTP Modules are, where HTTP Module fit, then what HTTP Modules are and a brief description of when and how to use.

The ASP.NET HTTP Pipeline
To understand the role of HTTP modules in ASP.NET page life cycle, you need to understand how the HTTP protocol works. Once an HTTP request comes in over port 80 (the regular HTTP port or port 443 for HTTPS and the secure sockets layer), the request passes through a number of stages making up the HTTP pipeline before it's actually fielded by your application.

Request --> IIS --> ASPNET_ISAPI.DLL --> HttpApplication- (HttpModule)-> HttpHandler

IIS is the first participant in the chain. IIS is used to route the request to the ASP.NET runtime. IIS maps the ASP.NET file extensions to ASPNET_ISAPI.DLL - an ISAPI extension provided with ASP.NET. The job of ASPNET_ISAPI.DLL is to forward the request to the ASP.NET worker process, ASPNET_WP.EXE. From that point on, the request is wrapped up into an instance of HttpContext and piped through a number of ASP.NET classes.
The next step for the request is to pass through an instance of HttpApplication. This stage is useful for maintaining application-scope methods, data, and events.
After the HttpApplication object massages the request, it pushes the request through one or more HttpModule objects which play a role of providing pre- and post-processing on each request.
There are a number of system-level HTTP modules, providing services ranging from authentication to state management to output caching. The number of modules that get to intercept the request is based upon settings within the host machine's machine.config file and the application's web.config file. In classic ASP, this role of providing pre- and post-processing fell upon ISAPI filters. It turns out that ASP HTTP modules are more straightforward to write.
The final piece of the chain is the HttpHandler. If you've been working with ASP.NET for a while, you're familiar with the System.Web.UI.Page class. The Page class is an HttpHandler object, implementing the interface IHttpHandler. Classes implementing IHttpHandler can hook into the HTTP pipeline and service requests through the interface's ProcessRequest method.

HTTP Modules
One of ASP.NET's most useful features is the extensibility of the HTTP pipeline - the path that data takes between client and server. You can use them to extend your ASP.NET applications by adding pre- and post-processing to each HTTP request coming into your application. For example, if you wanted custom authentication facilities for your application, the best technique would be to intercept the request when it comes in and process the request in a custom HTTP module.
An HTTP module is simply a class that implements the System.Web.IHttpModule interface:




Public interface IHttpModule
{
void Dispose();
void Init(HttpApplication context);
}

When an HttpModule is hooked into the pipeline (via an entry in web.config), the ASP.NET runtime calls the module's Init and Dispose methods. Init is a window where the HTTP Module can initialize itself. These methods are invoked by the ASP.NET runtime when a module gets registered Init method gets executed and when unregister Dispose method gets executed. The Init and Dispose methods represent the module's opportunity to hook into a variety of events exposed by HttpApplication. These events include the beginning of a request, the end of a request, a request for authentication, and so forth. Notice the HttpApplication parameter passed in to the Init method. Usually, the Init method takes the HttpApplication object and maps event handlers to the desired events.
Following is a C# code for defining a simple custom HttpModule that attaches to an application's BeginRequest and EndRequest events to provide simple pre- and post-processing before and after each request.



namespace HttpModuleExamples

{

 public class CustomHttpModule : IHttpModule

 {

  // IHttpModule memberspublic

  void Init(HttpApplication httpApp)

  {

   httpApp.BeginRequest += new EventHandler(this.OnBeginRequest);

   httpApp.EndRequest += new EventHandler(this.OnEndRequest);

  }

  public void Dispose()

  {

   // Usually, nothing has to happen here...

  }

  // event handlers

  public void OnBeginRequest(object o, EventArgs ea)

  {

   HttpApplication httpApp = (HttpApplication) o;

   HttpContext ctx = HttpContext.Current;

   ctx.Response.Write("Beginning Request ");

  }


  public void OnEndRequest(object o, EventArgs ea)

  {

   HttpApplication httpApp = (HttpApplication) o;

   HttpContext ctx = HttpContext.Current;

   ctx.Response.Write("Ending Request ");

  }

 }

}


To wire this handler up into the processing chain, the web.config file simply declares the module within the httpModules section, as shown here:


<configuration>


 <system.web>

  <httpModules>

   <add type= "HttpModuleExamples.CustomHttpModule, HTTPModules" name="CustomHttpModule"
/>

  </httpModules>

 </system.web>

</configuration>

HTTP Handlers
HTTP handler’s process the request and are generally responsible for initiating necessary business logic tied to the request. Custom handlers must implement the System.Web.IHttpHandler interface. Additionally, a handler factory can be created which will analyze a request to determine what HTTP handler is appropriate. Custom handler factories implement the System.Web.IHttpHandlerFactory interface.
When to use Modules and Handlers
With all of the options available in ASP.NET, it is sometimes hard to determine what solution best fits your needs. Of course, it's always best to keep things simple; but, you still need to take evolutionary considerations and experience levels of current and future team members who have a potential of working on the project into account.
Consider what it is that you want to do within your module or handler. Some functions, such as authentication can be added within modules. Modules should be considered only when there is a need for pass-through and/or intercepting interaction with the request. Alternatively, handlers should be put in place when there is a need to direct functional actions to one or more parts of an application.

Conclusion
HTTP modules are very beneficial and can be complex but these can solve problems that could be very difficult to solve by any other way.

1 comment: