Click here to Skip to main content
Click here to Skip to main content

HTTP Compression - A Quick and Dirty Solution

, 11 Jul 2006 CPOL
Rate this:
Please Sign up or sign in to vote.
How to use HTTP Compression on ASP.NET 2.0 pages.

Introduction

HTTP Compression is a great thing: it can save up to 70% of the bandwidth. HTTP Compression could be a problem: if you don't have access to IIS, you cannot enable it, for instance. These considerations made me look for a different solution, to be used in particular conditions. In this article, I describe how to implement HTTP Compression on single ASP.NET pages, maintaining compatibility with most browsers, and without touching IIS.

HTTP Compression Made Easy

All the modern browsers support HTTP Compression. I tested this solution with Microsoft Internet Explorer 6 SP1, Mozilla Firefox 1.5.0.4, and Konqueror. The latter has a few (known) problems with GZip streams: the pages are displayed correctly, but a warning message is shown.

When the browser supports HTTP Compression, it sends to the server a specific request header:

Accept-encoding: gzip, deflate

When the server receives that header, it can enable HTTP compression. The server, if it decides to use HTTP Compression, must notify the browser using the response header:

Content-encoding: gzip
-- or --
Content-encoding: deflate

The server then appends the content compressed using the GZip or Deflate algorithm. Note: there are a few other compression algorithms, but they are not supported by all browsers. For further information, take a look at Wikipedia.

The Code

The code is unbelievably simple, and uses the property Filter of the Page object. This property allows you to perform operations on the output stream of the page, for example, replacing every occurrence of Smile | :) with the appropriate HTML tag, just to display the smiley (I use this method in my blog). We only have to "replace" the whole output with its compressed bit stream. All we need is to put this simple code snippet in the Page_Load method:

protected void Page_Load(object sender, EventArgs e) {
  if(Request.Headers["Accept-encoding"] != null &&
     Request.Headers["Accept-encoding"].Contains("gzip")) {
       Response.Filter = new GZipStream(Response.Filter, 
                         CompressionMode.Compress, true);
       Response.AppendHeader("Content-encoding", "gzip");
  }
  else if(Request.Headers["Accept-encoding"] != null &&
          Request.Headers["Accept-encoding"].Contains("deflate")) {
      Response.Filter = new DeflateStream(Response.Filter, 
                        CompressionMode.Compress, true);
      Response.AppendHeader("Content-encoding", "deflate");
  }
}

The code "plugs" a GZipStream or a DeflateStream into the Filter object (it's an instance of System.IO.Stream), trying to detect which algorithm the browser supports. Note: the two classes (GZipStream and DeflateStream) use the same compression algorithm.

Refinements

Since it seems that Konqueror has problems with GZip/Deflate, we should disable HTTP Compression for that browser. We can do that by checking the User Agent. The code then becomes:

protected void Page_Load(object sender, EventArgs e) {
  if(!Request.UserAgent.ToLower().Contains("konqueror")) {
    if(Request.Headers["Accept-encoding"] != null &&
       Request.Headers["Accept-encoding"].Contains("gzip")) {
          Response.Filter = new GZipStream(Response.Filter, 
                            CompressionMode.Compress, true);
          Response.AppendHeader("Content-encoding", "gzip");
    }
    else if(Request.Headers["Accept-encoding"] != null &&
            Request.Headers["Accept-encoding"].Contains("deflate")) {
          Response.Filter = new DeflateStream(Response.Filter, 
                            CompressionMode.Compress, true);
          Response.AppendHeader("Content-encoding", "deflate");
    }
  }
}

Conclusions and Disclaimer

As the article's title states, this is a quick and dirty solution, with all its problems, bugs, and worst-practices. It should be considered a mere proof-of-concept, although it actually works. In the coming weeks, I'll investigate deeply into this topic because I believe it may actually become a nice way to implement HTTP Compression on a per-page basis.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Dario Solera

Italy Italy
Software Development Manager working on IaaS cloud computing. Cloud believer, (former) entrepreneur, F1 addict.
 
Follow me at dariosolera.it or on Twitter.
Follow on   Twitter   Google+

Comments and Discussions

 
QuestionCheck if response is already compressed PinmemberMember 287857222-Feb-13 0:03 
I just stumbled upon your article and, while it is interesting (by the way, thanks for writing it), I think that it's lacking an important check; see, your approach allows to implement HTTP compression even for websites hosted "somewhere else" that is, even if you have no control over the IIS settings; now, this is ok, but then, one may also face pitfalls; first of all, the admin of that IIS may suddendly decide to enable compression "server wide" and, in such a case, recompressing the output won't be a good idea, second the compression may be enabled but not for all file types and, instead, you may want to compress your output
 
Solving the above issue is relatively easy; the idea is more or less to add a function like this
 
// checks if the response is already compressed (i.e. IIS compression enabled)
private bool IsRespCompressed(HttpResponse resp)
{
  bool result = false;
  string filter = resp.Filter.ToString().ToLower();
  if (filter.Contains("gzip") | filter.Contains("deflate")) result = true;
  return result;
}
 
and then call it from the "main code" to check if the response is already compressed or not; the above function works by looking at the response Filter name; since when compression is enabled the name either contains "gzip" or "deflate" (checking it is easy, just try debugging the code) it's easy to tell if the response stream is compressed or not
 
Notice that the above code will work for both "pipeline" and "classic" modes of IIS
 
HTH


GeneralCompression for javascript does not work Pinmemberedsanfor2320-Oct-06 6:28 
GeneralRe: Compression for javascript does not work PinmemberDario Solera20-Oct-06 6:34 
GeneralRe: Compression for javascript does not work Pinmemberhungpvtn22-Oct-06 5:13 
QuestionASP.NET v 1.1 support ?? Pinmembermarcin.rawicki18-Sep-06 3:48 
AnswerRe: ASP.NET v 1.1 support ?? PinmemberDario Solera18-Sep-06 3:53 
GeneralRe: ASP.NET v 1.1 support ?? Pinmembermarcin.rawicki18-Sep-06 4:00 
GeneralHTTP Compression module [modified] PinmemberLuis Carlos Gallego9-Aug-06 6:32 
QuestionHow to make sure that it was applied? [modified] Pinmemberdathq11-Jul-06 16:51 
AnswerRe: How to make sure that it was applied? PinmemberDario Solera11-Jul-06 21:31 
GeneralRe: How to make sure that it was applied? [modified] Pinmemberdathq11-Jul-06 23:04 
GeneralRe: How to make sure that it was applied? PinmemberDario Solera12-Jul-06 1:22 
GeneralRe: How to make sure that it was applied? Pinmemberdathq12-Jul-06 9:07 
AnswerRe: How to make sure that it was applied? PinmemberJoyprakash Saikia17-Jul-06 9:51 
AnswerRe: How to make sure that it was applied? PinmemberHeavensDoor21-Jul-06 0:42 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web04 | 2.8.141022.2 | Last Updated 11 Jul 2006
Article Copyright 2006 by Dario Solera
Everything else Copyright © CodeProject, 1999-2014
Terms of Service
Layout: fixed | fluid