Share via


© 2004 Microsoft Corporation. All rights reserved.

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

Deterministic Events
Description
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);
}