Source code location: ./image_handler/staticimagehandler.cs

using System.Globalization;
using System.IO;
using System.Text.RegularExpressions;
using System.Web;
    
namespace AspNetResources.Web 
{
    public class StaticImageHandler : IHttpHandler 
    {
        /// <summary>
        /// Extract domain from host name.
        /// </summary>
        private static Regex reHostNameParser = new Regex("(?:www.)?(.*)", RegexOptions.IgnoreCase | RegexOptions.Compiled);

        /// <summary>
        /// If there's a referrer make sure its our own domain. Otherwise display an f-you image.
        /// </summary>
        public void ProcessRequest(System.Web.HttpContext ctx) 
        {
            string          extension = null;
            string          path = ctx.Request.PhysicalPath;
            string          contentType = null;
            HttpRequest     rq = ctx.Request;


            if (rq.UrlReferrer != null && rq.UrlReferrer.Host.Length > 0)
            {
                string host = reHostNameParser.Match (rq.Url.Host).Groups[1].Value;
                string referringHost = reHostNameParser.Match (rq.UrlReferrer.Host).Groups[1].Value;

                if (CultureInfo.InvariantCulture.CompareInfo.Compare (host, referringHost, CompareOptions.IgnoreCase) != 0)
                    path = ctx.Server.MapPath("~/images/no_leeching.gif");
            }

            extension = Path.GetExtension (path).ToLower ();
            switch (extension)
            {
                case ".jpg": contentType = "image/jpeg"; break;
                case ".gif": contentType = "image/gif"; break;
                case ".png": contentType = "image/png"; break;
                default:
                    throw new FileLoadException ("Unrecognized image type.");
            }

            if (!File.Exists (path))
            {
                ctx.Response.Status = "Image not found";
                ctx.Response.StatusCode = 404;
            }
            else
            {
                // Stream the image back to the user
                ctx.Response.StatusCode = 200;
                ctx.Response.ContentType = contentType;
                ctx.Response.WriteFile (path);
            }
        }
        
        public bool IsReusable 
        {
            get 
            {
                // To enable pooling, return true here.
                // This keeps the handler in memory.
                return true;
            }
        }        
    }
}