2

Yesterday I activated compression on my website, like this:

void context_BeginRequest(object sender, EventArgs e)
{

    HttpApplication app = (HttpApplication)sender;
    string encodings = app.Request.Headers.Get("Accept-Encoding");

    if (encodings == null)
        return;

    string url = app.Request.RawUrl.ToLower();           


    if (url.Contains(".js") || url.Contains(".aspx") || url.Contains(".css") || url.Contains("ajax.ashx"))
    {

        Stream baseStream = app.Response.Filter;
        encodings = encodings.ToLower();

        if (encodings.Contains("gzip"))
        {
            app.Response.Filter = new GZipStream(baseStream, CompressionMode.Compress);
            app.Response.AppendHeader("Content-Encoding", "gzip");
        }
        else if (encodings.Contains("deflate"))
        {
            app.Response.Filter = new DeflateStream(baseStream, CompressionMode.Compress);
            app.Response.AppendHeader("Content-Encoding", "deflate");
        }
    }
}

Last night, people were complaining about the styles for the website being broken. I tried the site in Firefox and Chrome and got the same problem until I did a forced refresh, clearing the cache.

This morning, I opened Safari to see what it looked like in that browser, and checked the stored style sheets. Here is a section of the top line:

���`I�%&/m�{J�J��t��`$ؐ@�������iG#)�*��eVe]f@�흼��{����{����;�N'���?\fdl��J�ɞ!���?~|?"�~+M�m�?��{�7y����l]�餮���N���̛�x�Ϋ�Q�cMVg��

I think either Safari has tried to uncompress something that was not compressed to begin with, or else it has recieved a compressed file and not decoded it.

Is this a one-time problem, that will be cleared up as soon as visitors to my site clear their cache, or have I made a mistake in writing my HttpCompression function?

Oliver
  • 11,297
  • 18
  • 71
  • 121
  • Is there a reason you don't just let [IIS do this](http://support.microsoft.com/kb/322603) for you? – Grant Thomas Oct 19 '11 at 09:35
  • @Mr.Disappointment The guy who was developing the site before me did it like this (He only had compression enabled for responses to ajax.ashx). It seems to work ok. – Oliver Oct 19 '11 at 09:39

2 Answers2

1

try this instead :

   HttpApplication app = sender as HttpApplication;
        string acceptEncoding = app.Request.Headers["Accept-Encoding"];
        Stream prevUncompressedStream = app.Response.Filter;

        if (!(app.Context.CurrentHandler is Page ||
            app.Context.CurrentHandler.GetType().Name == "SyncSessionlessHandler") ||
            app.Request["HTTP_X_MICROSOFTAJAX"] != null)
            return;

        if (string.IsNullOrEmpty(acceptEncoding))
            return;

        acceptEncoding = acceptEncoding.ToLower();


        if (acceptEncoding.Contains("gzip") || acceptEncoding == "*")
        {
            // gzip
            app.Response.Filter = new GZipStream(prevUncompressedStream, CompressionMode.Compress);
            app.Response.AppendHeader("Content-Encoding", "gzip");
        }
        else if (acceptEncoding.Contains("deflate"))
        {
            // defalte
            app.Response.Filter = new DeflateStream(prevUncompressedStream, CompressionMode.Compress);
            app.Response.AppendHeader("Content-Encoding", "deflate");
        }
Royi Namir
  • 144,742
  • 138
  • 468
  • 792
  • Thanks for this. What does the `if (!app.Context.CurrentHandler is Page || .....` statement check for, exactly? I'm cautious about compressing things that it doesn't make sense to compress, like images. For instance, I serve some dynamic PNGs from a `userImage.ashx` file. – Oliver Oct 19 '11 at 09:46
0

I believe my problem here was related to my lack of a Vary:Accept-Encoding header being added to my responses. Please see this related question on the subject. My code now looks like this:

if (url.Contains(".js") || url.Contains(".aspx") || url.Contains(".css") || url.Contains("ajax.ashx"))
{
    app.Response.AppendHeader("Vary", "Accept-Encoding");

    encodings = encodings.ToLower();

    if (encodings.Contains("gzip") || encodings == "*")
    {
        app.Response.Filter = new GZipStream(baseStream, CompressionMode.Compress);
        app.Response.AppendHeader("Content-Encoding", "gzip");

    }
    else if (encodings.Contains("deflate"))
    {
        app.Response.Filter = new DeflateStream(baseStream, CompressionMode.Compress);
        app.Response.AppendHeader("Content-Encoding", "deflate");
    }
}
Community
  • 1
  • 1
Oliver
  • 11,297
  • 18
  • 71
  • 121