Using a HTTP module to enforce a single domain

When I first setup this blog, you could access it on both "driis.dk" and "www.driis.dk". For various reasons, it is best practice to have a single url for the same content (it makes analyzing the site traffic easier, and avoids ambiguous URLs), so I wanted to setup the site to just use the www version of the domain name.

Now, there is a couple of ways you could do this. The easiest way would be to just setup IIS to redirect incoming requests to http://www.driis.dk. However, this site is hosted by a hosting company, where I do not have access to the IIS manager. 

Instead, I decided to write a custom HTTP module to do the redirecting. HTTP modules are great, as they allow you to hook into the ASP .NET application pipeline using the evens of the HttpApplication object. This makes it is a very strong tool to build advanced functionality. In this case, I decided to handle the BeginRequest event to check if the domain name is correct. If not, I issue a HTTP Redirect and ends the request. This way, all of the work associated with rendering the page is avoided if we just want to redirect anyway. The code is really simple, and basically goes like this:

         /// <summary>
        /// Handles the BeginRequest event.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void HandleBeginRequest(object sender, EventArgs e)
        {
            HttpApplication app = (HttpApplication) sender;
            string currentDomain = app.Context.Request.Url.DnsSafeHost.ToLower();
            if ( currentDomain != TargetDomain )
            {
                string newUrl = String.Format("http://{0}/{1}", TargetDomain, app.Request.Url.PathAndQuery);
                app.Response.Redirect(newUrl);
                app.CompleteRequest();
            }
        }

 Another advantage of this method, is that once it is configured in web.config, it always works. If you had used the IIS method, you would have to remember to configure IIS correctly again if the site switches server.

You can download the code as well as the compiled assembly here: dr.BlogEngine.DomainEnforcement.zip (19,18 kb)

This is a domain enforcement module in its simplest form. It simply looks at all incoming requests, and if they don't match the specified domain, the request is redirected to the corresponding url on the correct domain. Feel free to use the module, expand it or use it as inspiration. Just don't blame me if it kills a kitten.

To use the module, simply add it to the <httpModules> section in web.config:

<add name="DomainEnforcement" type="dr.BlogEngine.DomainEnforcement.DomainEnforcementModule,dr.BlogEngine.DomainEnforcement"/>

Then add an appSetting specifying the domain you would like to use as the primary domain:

<appSettings>
  <add key="EnforceDomain" value="www.driis.dk" />
</appSettings>

That's all there is to it.