Add or remove the www sub domain

Jan 9, 2008

Most websites needs a policy for handling the www sub domain because of SEO. It doesn’t matter if you redirect all requests coming from http://www.example.com to http://example.com or the other way around. The important thing is that you do one of them. Otherwise search engines will punish you for duplicate content.

This feature is built in to BlogEngine.NET and it allows you to either enforce the use of www or to remove it. It’s an HttpModule that handles these two scenarios and I’ve pulled it out of BlogEngine.NET and polished it so it can be used in any ASP.NET web application.

The code

This is the bit that handles the incoming request and either removes or enforces the www sub domain based on a web.config appSetting.

/// <summary>

/// Handles the BeginRequest event of the context control.

/// </summary>

/// <param name="sender">The source of the event.</param>

/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>

private void context_BeginRequest(object sender, EventArgs e)

{

  string rule = ConfigurationManager.AppSettings.Get("WwwRule");

 

  HttpContext context = (sender as HttpApplication).Context;

  if (context.Request.HttpMethod != "GET" || context.Request.IsLocal)

    return;

 

  if (context.Request.PhysicalPath.EndsWith(".aspx", StringComparison.OrdinalIgnoreCase))

  {

    string url = context.Request.Url.ToString();

 

    if (url.Contains("://www.") && rule == "remove")

      RemoveWww(context);

 

    if (!url.Contains("://www.") && rule == "add")

      AddWww(context);

  }

}

 

/// <summary>

/// Adds the www subdomain to the request and redirects.

/// </summary>

private static void AddWww(HttpContext context)

{

  string url = context.Request.Url.ToString().Replace("://", "://www.");

  PermanentRedirect(url, context);

}

 

private static readonly Regex _Regex = new Regex("(http|https)://www\\.", RegexOptions.IgnoreCase | RegexOptions.Compiled);

 

/// <summary>

/// Removes the www subdomain from the request and redirects.

/// </summary>

private static void RemoveWww(HttpContext context)

{

  string url = context.Request.Url.ToString();

  if (_Regex.IsMatch(url))

  {

    url = _Regex.Replace(url, "$1://");

    PermanentRedirect(url, context);

  }

}

 

/// <summary>

/// Sends permanent redirection headers (301)

/// </summary>

private static void PermanentRedirect(string url, HttpContext context)

{

  context.Response.Clear();

  context.Response.StatusCode = 301;

  context.Response.AppendHeader("location", url);

  context.Response.End();

}

 

Implementation

Download the HttpModule below and drop it in your App_Code folder. Then register the module in the web.config’s system.web section like so:

<httpModules>
  <add type="WwwSubDomainModule" name="WwwSubDomainModule" />
</httpModules>

You also need to add an appSetting like so:

<appSettings>
  <!-- Values can be 'add' or 'remove' -->
  <add key="WwwRule" value="add"/>
</appSettings>

WwwSubDomainModule.zip (1,23 kb)

* Only $4.95/month ASP.NET & Windows 2008 + IIS 7 Hosting! FREE SQL Included

Comments (14) -

Josh Stodola
Josh Stodola United States
1/9/2008 3:37:14 PM #

Cool, but where's that PermanentRedirect subroutine?  I am guessing it is something like this...

private void PermanentRedirect(string url)
{
   Response.Clear();
   Response.StatusCode = 301;
   Response.AppendHeader("location", url);
   Response.End();
}


Best regards...

Mads Kristensen
Mads Kristensen Denmark
1/9/2008 3:40:29 PM #

Yep, that's how it looks like. I didn't think it was that important to include in the post, but it is of course in the source.

Josh Stodola
Josh Stodola United States
1/9/2008 3:47:19 PM #

I think more people would favor highlighting/copying/pasting code on a web page as opposed to downloading a zip, opening it, extracting the contents, and then viewing the source.  But, that's just me being very picky.  I guess that I never have really liked the whole "zip" concept.  Sometimes it is warranted and highly beneficial, but in most cases I think it's overly used.  Too many steps involved just to view a chunk of code!

Im a VB guy, so I typically highlight code, go to a converter, and then bring the results of the conversion into VS and start tweaking it to my needs.  That's how I roll.

Thanks for sharing!

Mads Kristensen
Mads Kristensen Denmark
1/9/2008 3:52:19 PM #

Josh, you are absolutely right. I've added the missing code piece. Thanks

Brendan Enrick
Brendan Enrick United States
1/9/2008 5:06:24 PM #

Yeah, this is a great trick. I also use it. Perhaps you know this better than I do. How much of a performance issue is it to have this http module? Since it would have to check every single request to see if it had the "www" or didn't have it.

I know URL Rewriter modules will KILL performance on high traffic sites. Just wondering if this module, which is a simple rewriter module, will also hurt performance.

Andreas Kraus
Andreas Kraus Germany
1/9/2008 6:33:51 PM #

You can do this with IIS6, too. If you want to focus on http://yourdomain.com Add a seperate website with www.yourdomain.com.

Go to the fourth tab in the second row "Basisverzeichnis" / "Base Folder" or something and choose "Redirect to another URL". Redirect to: http://yourdomain.com and check "permanent redirection". It will 301 redirect every suburl/subfolder to the correct url without www.

Cheers,
Andreas

Damien Guard
Damien Guard United Kingdom
1/10/2008 10:13:59 AM #

It might be worth mentioning the DNS entry to add for 'domain.com' to point to your web site and a reminder about adding that to the host headers in IIS Admin?

[)amien

Wayne
Wayne United States
1/10/2008 8:26:57 PM #

Oh great!  Now another thing that I need to address on my sites.  Thanks for the great post!
Cheers!

Wayne

Mike Hamilton
Mike Hamilton United States
1/11/2008 2:15:36 PM #

can this same type of module be used to force people come to https:// instead of http://? I would guess so, but just want your thoughts, any issues you see using the module in that way.

tgh
tgh United States
1/12/2008 6:34:00 AM #

fdghf

Paulo Morgado
Paulo Morgado Portugal
1/12/2008 7:32:02 PM #

Hi Mads.

Nice piece of code, but I think you could make id better.

Leaving out the part that such an infrastructure should have it's own configuration (and defining that configuration section is beyond the subject of this post) instead of AppSettings, I think you should initialize the configuration settings into a boolean or enum in the initialization method of the module.

Your code is calling url.Contains("://www.") twice if it's not a remove action. You should refactor it into a local variable or change the position of the two conditions in each if statement.

And I'm not so sure Regex isn't an overkill in this case.

Dan Sylvester
Dan Sylvester United States
1/11/2009 7:45:36 PM #

I'm having trouble too running in a subdomain.  Biggest problem is the error page runs more code and also fails so I have to modifiy the code to see the errors.

Prashant
Prashant India
2/18/2009 3:29:39 AM #

Hi,

I am on godaddy's shared hosting server. When i am adding the HTTP Module settings to my web.config file, then my application giving me 500- Internal server error when I am running it. Please tell me how to implement this on shared hosting server???

Prashant
Prashant India
2/21/2009 12:51:52 PM #

Hi @Mads

I am seeing a problem in this module which is as follows,

If I am entering following url..
http://example.com/dom/

..then it redirects to following url
http://www.example.com/dom/default.aspx

Which is I think not correct it must redirects me at http://www.techsvr.com/dom/

What you think? Can we do this, if yes then how, please tell me.

Thanks

Pingbacks and trackbacks (1)+

Comments are closed

About the author

Mads Kristensen

Mads Kristensen
Program Manager at the Microsoft Web Platform team and founder of BlogEngine.NET.

More...

Month List

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer’s view in any way.