Climooo
Climooo

Reputation: 295

ASP.NET WebApi : Response GZIP compression not effective

I have an ASP.NET WEB API with compression enabled. In my WebApiConfig.cs, i have

config.MessageHandlers.Insert(
     0,
     new ServerCompressionHandler(
               new GZipCompressor(),
               new DeflateCompressor()
    )
);

It seems to work: when I do a request with PostMan, i get a response with ContentEncoding = gzip, and ContentLength is 300ko, the compressed size.

But with the following C# code, in my client (console program):

            HttpWebRequest apiRequest = WebRequest.CreateHttp("http://localhost:8085/data");
        apiRequest.Method = "GET";
        apiRequest.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
        apiRequest.Accept = "application/json";

        HttpWebResponse apiResponse;
        try
        {
            apiResponse = (HttpWebResponse)apiRequest.GetResponse();
        }
        catch (WebException ex)
        {
            apiResponse = ex.Response as HttpWebResponse;
            if (apiResponse == null)
            {
                throw;
            }
        }


        var sr = new StreamReader(apiResponse.GetResponseStream());
        string ct = sr.ReadToEnd(); // Full result in string


        var respEncoding = apiResponse.ContentEncoding; // empty string  
        var respLen = apiResponse.ContentLength; // -1    

the ContentLength is set to -1, and the contentEncoding is empty. Howewer, I can get the full content in a string. Can you explain me why ?

Upvotes: 1

Views: 1186

Answers (2)

Dipen Shah
Dipen Shah

Reputation: 26085

the ContentLength is set to -1, and the contentEncoding is empty. Howewer, I can get the full content in a string. Can you explain me why ?

This is by design, check out this link. HttpWebResponse class it-self explicitly sets those values when Content-Encoding header is Gzip or Deflate and AutomaticDecompression flag is set.

It seems that replacing apiRequest.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate; by apiRequest.Headers["Accept-Encoding"] = "gzip"; works. But why ?

What do you mean by it works? If you mean you get original values for ContentEncoding and ContentLength then it is because your response hasn't been decompressed.

If you want to get original values from headers when using AutomaticDecompression flag then use Headers[header-key] to get original value from the response (in this case apiResponse.Headers["Content-Length"] will be length of compressed data). However, only catch is you will loose original value of Content-Encoding for some weird reason as explained in the referenced code.

// Setting a response header after parsing will ruin the Common Header optimization.
// This seems like a corner case.  ContentEncoding could be added as a common header, with a special
// property allowing it to be nulled.
m_HttpResponseHeaders[HttpKnownHeaderNames.ContentEncoding] = null;

Upvotes: 2

Barr J
Barr J

Reputation: 10927

If your API is behind firewall it will strip out the headers, as a result you will fail to see the response, postman does not take that into account.

see also:

Even Faster Web Sites: Performance Best Practices for Web Developers By Steve Souders

Upvotes: 0

Related Questions