Search code examples
c#gzip.net-4.5dotnet-httpclientwinrt-async

HttpClient: Conditionally set AcceptEncoding compression at runtime


We are trying to implement user-determined (on a settings screen) optional gzip compression in our client which uses HttpClient, so we can log and compare performance across a number of different calls over a period of time. Our first attempt was to simply conditionally add the header as follows:

HttpRequestMessage request = new HttpRequestMessage(Method, Uri);
if (AcceptGzipEncoding)
{
     _client.DefaultRequestHeaders.AcceptEncoding.Add(new System.Net.Http.Headers.StringWithQualityHeaderValue("gzip"));
}

//Send to the server
result = await _client.SendAsync(request);

//Read the content of the result response from the server
content = await result.Content.ReadAsStringAsync();

This created the correct request, but the gzipped response was not decompressed on return, resulting in a garbled response. I found that we had to include the HttpClientHandler when constructing the HttpClient:

HttpClient _client = new HttpClient(new HttpClientHandler
    { 
        AutomaticDecompression = DecompressionMethods.GZip
    });

This all works well, but we'd like to change whether the client sends the Accept-Encoding: gzip header at runtime, and there doesn't appear to be any way to access or change the HttpClientHandler after it's passed to the HttpClient constructor. In addition, altering the headers of the HttpRequestMessage object doesn't have any effect on the headers of the request if they are defined by the HttpClientHandler.

Is there any way to do this without recreating the HttpClient each time this changes?

Edit: I've also tried to modify a reference to the HttpClientHandler to change AutomaticDecompression at runtime, but that's throwing this exception:

This instance has already started one or more requests. Properties can only be modified before sending the first request.


Solution

  • As per the comments above, recreating the HttpClient is really the only (robust) way to do this. Manual decompression can be achieved but it seems to be very difficult to reliably/efficiently determine whether the content has been encoded or not, to determine whether to apply decoding.