The HTTP Pipeline
As with most HTTP requests handled by the Microsoft platform, the first stop for an ASP.NET request is IIS. IIS intercepts the request and examines the file extension of the request. IIS keeps a list of file extensions and the ISAPI DLLs that are supposed to handle the associated files. When an extension such as ASPX shows up, IIS routes the request to a DLL named Aspnet_isapi.dll. This DLL simply takes the request and pipes it into the ASP.NET worker process Aspnet_wp.exe. ASP.NET examines the file and figures out whether the file needs to be compiled (and, of course, compiles the file if necessary).
The HttpContext Object
Next, ASP.NET cooks up an instance of a .NET Framework class named HttpContext. HttpContext represents the current request and includes almost anything you'd ever want to know about the request. Inside HttpContext you'll find the URL used to surf to the page, the file path of the physical file, whether the user has been authenticated, whether the connection is secure, and so on. The context also includes a reference to the Request and Response objects. We'll look at how the context is useful in a moment.
The HttpApplication Object
After wrapping up the information about the request in a context object, ASP.NET passes the request through an instance of HttpApplication. Remember MFC's CWinApp? CWinApp plays the role of the singleton within an MFC application. It's a rendezvous point for global application-wide data and events. HttpApplication serves the same role within an ASP.NET application. As the request is being processed, the HttpApplication object fires events to any number of waiting HTTP modules.
The HttpModule Object
HTTP modules provide an opportunity for pre- and post-processing requests. Events fired by the application object include BeginRequest, EndRequest, AuthenticateRequest, and AuthorizeRequest. Any Web application that wants to intercept these events can install an HTTP module. An HTTP module attaches itself to the application object and listens for these various events.
The Ex34b Example: Creating an HTTP Module
Ex34b listens for the BeginRequest event and dumps some of the context information at the beginning of every request. The module also rejects every other request, which of course is not useful in real life. However, you can see how it might be useful to intercept some of these events to do your own authentication or something like that. Here's the listing for Ex34b:Ex34b.h
// Ex34b.h
#pragma once
#using <system.dll>
#using <system.web.dll>
using namespace System;
using namespace System::Web;
namespace Ex34b
{
public __gc class RejectRequestModule :
public IHttpModule
{
bool m_bRejectRequest;
public:
RejectRequestModule()
{
m_bRejectRequest = false;
}
void Init(HttpApplication* httpApp) {
httpApp->
add_BeginRequest(new EventHandler(this, OnBeginRequest));
httpApp->
add_EndRequest(new EventHandler(this, OnEndRequest));
}
void Dispose() {
// Usually, nothing has to happen here. However, if
// there's any clean up you need to take care of here,
// Dispose is called before the module goes away.
}
// Event handlers
void OnBeginRequest(Object* o, EventArgs* ea) {
// showing how to get a reference to the application
HttpApplication* httpApp = dynamic_cast<HttpApplication*>(o);
// Getting the current context
HttpContext* ctx;
ctx = HttpContext::Current;
ctx->Response->Write("Beginning Request <br>");
ctx->Response->Write("URL Used to surf here: ");
ctx->Response->Write(ctx->Request->Url);
ctx->Response->Write("<br>");
ctx->Response->Write("Authenticated? ");
ctx->Response->Write
(ctx->Request->IsAuthenticated.ToString());
ctx->Response->Write("<br>");
ctx->Response->Write("Using secure connection? ");
ctx->Response->Write
(ctx->Request->IsSecureConnection.ToString());
ctx->Response->Write("<br>");
if(m_bRejectRequest) {
ctx->Response->Write
("<br>Stopping every other request...<br>");
httpApp->CompleteRequest();
ctx->Response->StatusCode = 500;
ctx->Response->StatusDescription = "Server Error";
}
m_bRejectRequest = !m_bRejectRequest;
}
void OnEndRequest(Object* o, EventArgs* ea) {
HttpApplication* httpApp = dynamic_cast<HttpApplication*>(o);
HttpContext* ctx = HttpContext::Current;
ctx->Response->Write("<br>");
ctx->Response->Write("Ending Request <br>");
}
};
}
Modules implement IHttpModule, an interface the ASP.NET infrastructure uses to tell the modules to initialize themselves. Modules are listed in the

<configuration>
<system.web>
<httpModules>
<add type="Ex34b.RejectRequestModule, Ex34b"
name="RejectRequestModule" />
</httpModules>
</system.web>
</configuration>
This configuration file tells ASP.NET to look for an implementation of IHttpModule. The file should be put in the virtual directory hosting the site. The name of the module class is Ex34b.RejectRequestModule, and the module should be found in the assembly Ex34b.dll. Finally, the system name by which the module will be known is RejectRequestModule. Modules are useful for implementing pre- and post-processing for various phases of an application. In fact, ASP.NET's session state, output caching, and various forms of authentication are already built into ASP.NET via HttpModule. Figure 34-5 shows the HttpModule in action.

Figure 34-5: The Ex34b module dumping context information and stopping every other request.
After a request is routed through a pipeline of HTTP modules, it is ultimately routed to an HTTP handler.
The HttpHandler Object
You've seen the System::Web::UI::Page class, which contains the infrastructure for rendering normal Web pages with the help of server-side controls. However, ASP.NET is flexible enough to provide other ways of handling requests.Imagine, for example, that you have a small file (such as a log file or a source code file) whose contents you want to make available to patrons of your Web site. However, you're also concerned about the performance and scalability of your application. If you look at the System::Web::UI::Page class, you'll notice that it's crammed with stuff. It's not a very lightweight class to instantiate and run. One option is to write a lightweight handler to process the request.
HttpHandler is simply a common language runtime class that implements IHttpHandler. It's listed in the application's

The Ex34c Example: Implementing a Lightweight HTTP Handler
This example implements a lightweight handler for printing out files with the CPP extension. Here's the listing:Ex34c.h
// Ex34c.h
#pragma once
#using <system.dll>
#using <system.web.dll>
using namespace System;
using namespace System::Web;
using namespace System::IO;
namespace Ex34c
{
public __gc class SourceCodeHandler :
public IHttpHandler
{
void ProcessRequest(HttpContext* context)
{
context->Response->Write("Viewing file: ");
context->Response->Write(context->Request->PhysicalPath);
context->Response->Write("<br>");
try
{
StreamReader* sr;
sr = new StreamReader(context->Request->PhysicalPath);
String* str;
do
{
str = sr->ReadLine();
context->Response->Write("<p>");
context->Response->Write(str);
context->Response->Write("</p>");
} while (str != 0);
}
catch (FileNotFoundException* )
{
context->Response->Write("<h2>Sorry –");
context->Response->Write("the file you ");
context->Response->Write("requested is not");
context->Response->Write(" available</h2>");
}
}
__property bool get_IsReusable()
{
return true;
}
};
}
When a request comes into ASP.NET, ASP.NET looks in the application's



<configuration>
<system.web>
<httpHandlers>
<add verb="*" path="*.cpp"
type="Ex34c.SourceCodeHandler, Ex34c" />
</httpHandlers>
</system.web>
</configuration>
The last task to get this handler working is to let IIS know about the file extension for the source code files you want to view. Right-click on the virtual directory within IIS and choose Properties. Click the Configuration button to get a list of file mappings, as shown in Figure 34-6.

Figure 34-6: The Application Configuration property sheet within IIS showing the list of file-to-ISAPI DLL mappings.
Click the Add button to add a new extension. You'll see a dialog box, as shown in Figure 34-7.

Figure 34-7: Adding a new file extension to the list of file-to-ISAPI DLL mappings.
Add .cpp as the extension, and point the executable to Aspnet_isapi.dll. (In Windows 2000, it's at \Winnt\Microsoft.net\Framework\v1.0.3705.) Now, when you surf to a file with a .cpp extension within that virtual directory, ASP.NET will load the handler. The handler will open the file and send the contents out to the client browser.
ASP.NET uses a handler to manage application-wide tracing. If you look inside the master Machine.config file on your host and search for httpHandlers, you'll see a file designation Trace.axd that's mapped to a system-provided class named System.Web.Handlers.TraceHandler.