Search code examples
asp.netiis-7hotlinking

ASP.NET detect hotlink image views


Is there a way to detect hotlink image views in ASP.NET / IIS 7 ? I don't want to block the viewers, I just need to increment the image views counter for each static image when someone clicks on my images in google image search.


Solution

  • This is pretty easy. You can simply check the Referrer request header, and log the request if it doesn't match your local domain(s). Something like this should work:

    using System;
    using System.Linq;
    using System.Web;
    
    namespace ImageLogger
    {
        public class ImageLoggerModule : IHttpModule
        {
            public void Init(HttpApplication context)
            {
                context.LogRequest += new EventHandler(context_LogRequest);
            }
    
            void context_LogRequest(object sender, EventArgs e)
            {
                var context = HttpContext.Current;
    
                // perhaps you have a better way to check if the file needs logging,
                // e.g.: it is a file in a certain folder
                switch (context.Request.Url.AbsolutePath.Split('.').Last().ToLower())
                {
                    case "png":
                    case "jpg":
                    case "gif":
                    case "bmp":
                        if (context.Request.UrlReferrer != null)
                        {
                            if (!"localhost".Equals(
                                context.Request.UrlReferrer.Host, 
                                StringComparison.CurrentCultureIgnoreCase)
                                )
                            {
                                // request is not from local domain --> log request
                            }
                        }
                        break;
                }
            }
    
            public void Dispose()
            {
            }
        }
    }
    

    In the web.config you link this module in the modules section:

    <system.webServer>
        <modules>
            <add name="ImageLogger" type="ImageLogger.ImageLoggerModule"/>
    

    This only works in Integrated Mode in IIS - in classic mode ASP.NET never gets any events for static files.

    Now that I think about it; you could scrap the current logging altogether (in the page, I guess?), and just use this module, and get rid of the referrer logic. That way you only have one place where you do your logging.