Figure 1 Minimal HTTP Module
using System;
using System.Web;
using System.Diagnostics;
namespace Panos.Test
{
public class HttpModule : IHttpModule
{
public void Init(HttpApplication context)
{
EventLog.WriteEntry("Panos.Test.HttpModule_Init", "");
m_context = context;
m_beginRequest = new
System.EventHandler(this.OnBeginRequest);
m_context.BeginRequest += m_beginRequest;
}
public void Dispose()
{
EventLog.WriteEntry("Panos.Test.HttpModule_Dispose", "");
m_context.BeginRequest -= m_beginRequest;
m_beginRequest = null;
}
protected void OnBeginRequest(object sender, EventArgs ea)
{
EventLog.WriteEntry("TestHTTPModule_BeginRequest","");
}
private HttpApplication m_context;
private EventHandler m_beginRequest;
}
}
Figure 2 Events in the Order They are Invoked
BeginRequest
|
Request is just initiating
|
AuthenticateRequest
|
Can now add custom authentication scheme
|
AuthorizeRequest
|
Allows you to add custom authorization scheme such as ACLs based on an XML file
|
ResolveRequestCache
|
A caching module can resolve the request from the cache
|
AcquireRequestState
|
At this point, the module can retrieve session state
|
PreRequestHandlerExecute
|
The Web form is about to fire
|
(Execution)
|
(Actual execution of .aspx or page file—doesn't fire an event)
|
PostRequestHandlerExecute
|
The Web form just fired
|
ReleaseRequestState
|
Module can store session state at this point
|
UpdateRequestCache
|
A caching module can update its caches here
|
EndRequest
|
Request has ended
|
Non-deterministic Transmission Events
|
Description
|
PreSendRequestHeaders
|
Headers are about to be sent to the client; module can add its own headers here
|
PreSendRequestContent
|
Content is about to be sent to the client; module can add its own content here
|
Error
|
An unhandled exception was generated
|
Figure 4 Redirection Handler
using System;
using System.Web;
using System.Diagnostics;
using System.IO;
namespace Panos.Test
{
public class RedirectionHttpHandler : IHttpHandler
{
public void ProcessRequest(HttpContext context)
{
string virtualPath = context.Request.Path;
// Break down the path fom /foo/microsoft/report.bestpayroll
// to /foo and microsoft/report.bestpayroll
int indexOfSlashLast = virtualPath.LastIndexOf('/;
int indexOfLastMinusOne = virtualPath.LastIndexOf('/',
indexOfSlashLast - 1);
string firstHalf = virtualPath.Substring(0,
indexOfLastMinusOne);
string secondHalf = virtualPath.Substring
(indexOfLastMinusOne + 1,
virtualPath.Length - indexOfLastMinusOne - 1);
// split the microsoft/report.bestpayroll
string[] aComps = secondHalf.Split('/
string companyName = aComps[0];
string fileName = aComps[1];
// drop the .bestpayroll
fileName = Path.GetFileNameWithoutExtension(fileName);
context.Items.Add("company", companyName);
context.Server.Transfer(firstHalf + "/" + fileName +
".aspx");
}
public bool IsReusable
{
get
{
return true;
}
}
}
}
Figure 6 ISAPI Filter Solution
const DWORD cnURLSize = 4096;
const char cVirtualPathPrefix[] = "/bestpayroll";
DWORD CURLRewriteFilter::OnPreprocHeaders(CHttpFilterContext* pfc,
PHTTP_FILTER_PREPROC_HEADERS pHeaders)
{
// get the URL using the special "url" pseudoheader
char lpszOriginalURL[cnURLSize], lpszCompanyName[1000],
lpszNewUrl[cnURLSize];
DWORD nURLSize = cnURLSize;
if ((pHeaders->GetHeader(pfc->m_pFC, "url", lpszOriginalURL,
&nURLSize))) {
// Only apply the filter to the best payroll directory
if (strnicmp(lpszOriginalURL, cPrefix, sizeof(cPrefix) - 1))
return CHttpFilter::OnPreprocHeaders(pfc, pHeaders);
size_t urlSize = strlen(lpszOriginalURL);
char *pPage = lpszOriginalURL + urlSize;
char *pPageEnd = pPage;
// move back to find the page name
while (*pPage != '/') pPage;
char* pCompany = pPage - 1; // just before the /
char* pCompanyEnd = pPage;
pPage++; // just past the /
while (*pCompany != '/') pCompany;
pCompany++; // just past the /
// move back to find the company name
strncpy(lpszNewUrl, lpszOriginalURL, pCompany - lpszOriginalURL);
lpszNewUrl[pCompany - lpszOriginalURL] = '\0';
strncat(lpszNewUrl, pPage, pPageEnd - pPage);
strcat(lpszNewUrl, ".aspx");
strncpy(lpszCompanyName, pCompany, (pCompanyEnd- pCompany));
lpszCompanyName[pCompanyEnd- pCompany] = '\0';
pHeaders->SetHeader(pfc->m_pFC, "COMPANYNAME:",
(char*)lpszCompanyName);
pHeaders->SetHeader(pfc->m_pFC, "url", (char*)lpszNewUrl);
}
return CHttpFilter::OnPreprocHeaders(pfc, pHeaders);
}
|