Accept-Encoding: gzip

From Logic Wiki
Jump to: navigation, search


1st approach - Web.Config

<system.webServer>
  <httpCompression directory="%SystemDrive%inetpubtempIIS Temporary Compressed Files">
    <scheme name="gzip" dll="%Windir%system32inetsrvgzip.dll"/>
    <dynamicTypes>
      <add mimeType="text/*" enabled="true"/>
      <add mimeType="message/*" enabled="true"/>
      <add mimeType="application/javascript" enabled="true"/>
      <add mimeType="*/*" enabled="false"/>
    </dynamicTypes>
    <staticTypes>
      <add mimeType="text/*" enabled="true"/>
      <add mimeType="message/*" enabled="true"/>
      <add mimeType="application/javascript" enabled="true"/>
      <add mimeType="*/*" enabled="false"/>
    </staticTypes>
  </httpCompression>
  <urlCompression doStaticCompression="true" doDynamicCompression="true"/>
</system.webServer>


2nd approach - In Application

 void Application_PreRequestHandlerExecute(object sender, EventArgs e)
    {
        HttpApplication app = sender as HttpApplication;
        string acceptEncoding = app.Request.Headers["Accept-Encoding"];
        Stream prevUncompressedStream = app.Response.Filter;

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

        if (acceptEncoding == null || acceptEncoding.Length == 0)
            return;

        acceptEncoding = acceptEncoding.ToLower();

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


3rd approach - In Application (2)

We can also programmatically compress the ASP.NET http response, for example I want to transfer a large CSVfile to the client, a simple ASPX page named ReturnGzipPackage.aspx:

protected void Page_Load(object sender, EventArgs e)
{
    Response.Headers.Add("Content-Disposition", "attachment; filename=IAmLarge.csv");
    Response.ContentType = "text/csv";
    Response.TransmitFile("D:\\IAmLarge.csv");
    Response.End();
}

If the request was submitted by a client browser, browser will automatically decompress the Http package, but in the Windows client application or Windows Service, we developers can also adopt gzip compression to save bandwidth, once received gzip Http package from the server, we can programmatically decompressing, I wrote a client console application to submit the Http request and receive/decompress the Http response package.

* Submit Http request to server with Accept-Encoding: gzip */
WebClient client = new WebClient();
// It is mandatory by the client, if this header information is not specified, 
// server will return the original content type, in my case, it is: text/csv
//client.Headers.Add("Accept-Encoding", "gzip");

using(Stream gzipData = client.OpenRead(
    "http://localhost/StudyASPNET/gzipHttp/ReturnGzipPackage.aspx"))
{
    WebHeaderCollection responseHeaders = client.ResponseHeaders;

    using(GZipStream gzip = new GZipStream(gzipData, CompressionMode.Decompress))
    {
        using(StreamReader reader= new StreamReader(gzip))
        {
            String content = reader.ReadToEnd();
            File.WriteAllText("D:\\Downloaded.csv", content);
        }
    }
}