Skip to content

Instantly share code, notes, and snippets.

@fengelz
Created November 3, 2011 08:06
Show Gist options
  • Save fengelz/1336018 to your computer and use it in GitHub Desktop.
Save fengelz/1336018 to your computer and use it in GitHub Desktop.
404 Http module for umbraco.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text.RegularExpressions;
using System.Web;
using umbraco.BusinessLogic;
using umbraco.NodeFactory;
namespace Web.Modules
{
public class Lang404Module : IHttpModule
{
private const string DefaultLang = "gb";
private const string ErrorNodeType = "Error404";
//Assumes the url contains language code ie. '/en/non-existing-pages/'
private static readonly Regex ReturnUrlRegex = new Regex(@"/(?<country>[a-zA-Z]{2})/");
public void Init(HttpApplication application)
{
application.EndRequest += ApplicationEndRequest;
}
// Note: remember web.config: <httpErrors existingResponse="PassThrough" /> in system.webServer
// Note: remember web.config: <add type="Modules.Lang404ErrorModule" name="Lang404ErrorModule" /> system.webServer.modules
static void ApplicationEndRequest(object sender, EventArgs e)
{
Node currentNode = null;
// check if we have a 404 response in progress
var ctx = HttpContext.Current;
// if path has extension... forget it.
var path = ctx.Request.Url.LocalPath;
if (path.Length - path.LastIndexOf('.') < 5) return;
// to avoid calling the Node.GetCurrent for all image, css and js requests we check the mimetype
if (ctx.Response.ContentType == "text/html")
try
{
currentNode = Node.GetCurrent();
if (currentNode.template == 0 && !ctx.Request.RawUrl.StartsWith("/umbraco/editContent.aspx", StringComparison.InvariantCultureIgnoreCase))
ctx.Response.StatusCode = 404;
}
catch { }
// if we're not in a 404 state, return
if (ctx.Response.StatusCode != 404) return;
// if we're already on a 404 Node, return
if (currentNode != null && currentNode.NodeTypeAlias == ErrorNodeType) return;
// determine language
var targetLang = DefaultLang; // default language
var orgTargetUrl = ctx.Request.RawUrl;
// if any language-matches in the original url, set this as the target language
var match = ReturnUrlRegex.Match(orgTargetUrl);
if (match.Success)
targetLang = match.Groups["country"].Value.ToLower();
// if everything runs smooth, transfer the the response of the 404 page, as the current (remember to response with statuscode: 404)
ctx.Server.TransferRequest("/404/");
}
public void Dispose()
{
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment