Archive

Posts Tagged ‘HTTP Compression’

Http Compression in ASP.Net

January 5th, 2010 Anuraj P No comments

Yesterday I got a chance to attend web performance optimization team meeting, and they suggested, HTTP Compression will help to reduce the Bandwidth and thus improves the performance. Later I come to know some of other teams in my organization are using these techniques in their web applications. I found few implementations, and the code is written in Global.asax. But the problem with this approach is the code is not reusable. I thought of implementing it an Http Module for compressing the HTTP response. For more information about HttpModules, check MSDN.

Here is the code of Compression Module.

public class CompressionModule : IHttpModule
{
    private HttpApplication httpApplication;
    private string acceptEncoding;
    private const string DEFLATE = "deflate";
    private const string GZIP = "gzip";
    private const string AJAX = "HTTP_X_MICROSOFTAJAX";
    private const string WEBSERVICE = "SyncSessionlessHandler";

    /// <summary>
    /// Disposes of the resources (other than memory) used by the module that implements <see cref="T:System.Web.IHttpModule"/>.
    /// </summary>
    public void Dispose()
    {
        //Do nothing
    }

    /// <summary>
    /// Initializes a module and prepares it to handle requests.
    /// </summary>
    /// <param name="context">An <see cref="T:System.Web.HttpApplication"/> that provides access to the methods, properties, and events common to all application objects within an ASP.NET application</param>
    public void Init(HttpApplication context)
    {
        context.BeginRequest += new EventHandler(context_BeginRequest);
        this.httpApplication = context;
    }

    /// <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)
    {
        if (IsEncodingSupported)
        {
            //Converting the Accept encoding to lower, it can be gZip, GZip, Gzip
            this.acceptEncoding = acceptEncoding.ToLower();
            Stream prevUncompressedStream = this.httpApplication.Response.Filter;

            //First checks whether deflate compression is supported or not.
            //Because Deflate offers better compression compared to GZip

            if (acceptEncoding.Contains(DEFLATE) || acceptEncoding == "*")
            {
                // defalte
                this.httpApplication.Response.Filter = new DeflateStream(prevUncompressedStream,
                    CompressionMode.Compress);
                this.httpApplication.Response.AppendHeader("Content-Encoding", DEFLATE);
            }
            else if (acceptEncoding.Contains(GZIP))
            {
                // gzip
                this.httpApplication.Response.Filter = new GZipStream(prevUncompressedStream,
                    CompressionMode.Compress);
                this.httpApplication.Response.AppendHeader("Content-Encoding", GZIP);
            }
        }
    }

    /// <summary>
    /// Gets a value indicating whether this instance is encoding supported.
    /// </summary>
    /// <value>
    /// 	<c>true</c> if this instance is encoding supported; otherwise, <c>false</c>.
    /// </value>
    private bool IsEncodingSupported
    {
        get
        {
            //Check wheather the Request is for Page or Web Service.
            //Also check wheather it an AJAX Request.
            this.acceptEncoding = this.httpApplication.Request.Headers["Accept-Encoding"];

            if (!this.httpApplication.Request.RawUrl.Contains(".aspx") ||
                this.httpApplication.Request[AJAX] != null)
            {
                return (false);
            }
            //Check whether browser supports compression.
            if (acceptEncoding == null || acceptEncoding.Length == 0)
            {
                return (false);
            }
            return true;
        }
    }
}

As the code is in App_Code folder, you need to register the http module in the Web.Config file.

<httpModules>
      <add name="CompressionModule" type="CompressionModule, App_Code"/>
</httpModules>

If you are using IIS 7 the settings will be different like this.

<system.webServer>
<modules>
      <add name="CompressionModule" type="CompressionModule, App_Code"/>
</modules>
</system.webServer>