A first hand look from the .NET engineering teams
As promised, we’ve just pushed the RTM version of HttpClient 2.2 to NuGet. This version adds support for automatic decompression. As announced here, this doesn’t require a dependency on Microsoft.Bcl.Compression. This allowed us to support automatic decompression on more platforms and without forcing your projects to change the CPU architecture.
It’s worth noting that we didn’t make any changes since the RC version we published a week ago (despite changing the version).
(For the sake of keeping this post self-contained I’ve copied the content from the post that introduced automatic decompression)
First, automatic decompression is not enabled by default for HttpClient. To use it, you need to set the AutomaticDecompression property on HttpClientHandler to GZip or Deflate. This API follows the optional feature pattern; meaning it exposes an API that indicates whether a particular feature is supported. Automatic decompression support is indicated with the SupportsAutomaticDecompression property.
If an implementation of HttpClient doesn’t support automatic decompression, it returns false from the SupportsAutomaticDecompression property and throws a NotSupportedException from the setter and getter for the AutomaticDecompression property.
With this pattern in mind, using automatic decompression looks like this:
var handler = new HttpClientHandler();
handler.AutomaticDecompression = DecompressionMethods.GZip |
var httpClient = new HttpClient(handler);
var str = await httpClient.GetStringAsync("http://en.wikipedia.org/wiki/Gzip");
The request then provides the additional Accept-Encoding header:
GET http://en.wikipedia.org/wiki/Gzip HTTP/1.1
Accept-Encoding: gzip, deflate
Servers that choose to support it will respond and indicate the compression algorithm they used. In this example, the server compressedt he body using gzip:
HTTP/1.1 200 OK
Date: Wed, 13 Mar 2013 14:04:24 GMT
Content-Type: text/html; charset=UTF-8
Last-Modified: Tue, 05 Mar 2013 03:38:51 GMT
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Cache-Control: private, s-maxage=0, max-age=0, must-revalidate
The response stream that HttpClient returns to you will automatically decompress the result using the appropriate algorithm. On my machine I got the following results:
This yields to a reduction by 77%. Needless to say, the actual results depend on the request and how well it compresses. So your results will naturally vary.
We’ve just shipped the RTM version of HttpClient 2.2, which updates HttpClient by adding support for automatic decompression. It's supported on .NET 4.0, Windows Phone 7.5, and partially supported on Silverlight (see this blog post for details).
Thanks for all the feedback we’ve received. We’d love to hear how you like the new version!
This is just what I've been waiting for, thanks!
Congratulations guys, and thanks again for preferring compatibility.
Should we update as well even if we don't use compression?
Does the compression work with POST? Debugging I see it set the handler, but do not see it set the Accept header and as a result no compression.
Cannot get response.StatusCode.ToString(); on Phone8
It says it needs System.Net.
Can you not make a blog post summarizing the various HTTP clients in .NET , what do we use where and when? I mean there's a client in WEB.API? is this the same as HttpClient?
I notice that the platform restrictions are still there. (Only allowed to use on Windows) Any information on when / if that will be removed?
How to uncompress the results once you receive decompressed response?
@Paul, @Richard: Glad you like it!
@Martin: If you used HttpClient 2.1 RTM, then we've fixed a few bugs as well.
@Andy: Interesting idea. Let me see what I can do.
@Steinar Herland: We don't have anything to share at this point.
@robert: The decompression is automatic -- you don't have to do anything despite setting the AutomaticDecompression property.
@Byron: We will set the Accept-Encoding header on a POST when HttpHandler.AutomaticDecompression is set. The API only supports automatic *de*compression of the response body. The server can choose to return a response to the post with compressed response body and we'll decompress it. HttpClient does not support compression of the request body of a POST on any platform.
WRT System.Net. See issue 2 @ support.microsoft.com/.../2840147. You need to repair VS to fix it.
Thank you guys. I'll stop yelling about this lack on WinPhone now. My throat is sore after 2.5 years of that :-)
What are the plans wrt. to code compatibility with the WinRT HttpClient, which is based on IHttpFilter rather than HttpClientHandler?
Also do you have any plans to improve HttpCaching support on all platforms? (ETag/Cache-Control header handling).
Lastly there's still an outstanding issue with WebRequests on WinPhone that takes longer than 100 seconds. They time out an there's no way to increase the timeout beyond that limit.
Just a note, even though in the changelog is noted, that HttpClient on WP8 may cache responses and we should use proper cache-control headers, the responses are cached even when our server uses "cache-control: private".
I had to manually add random string to each our request to fix this. This is the only complain I have right now.
@Morten: Thanks keeping us on our toes :-)
> What are the plans wrt. to code compatibility with the WinRT HttpClient, which is based on IHttpFilter rather than HttpClientHandler?
With respect to the WinRT HttpClient: our goal is offer a continuous experience in .NET class libraries across all our platforms, which includes both, clients as well as servers.
It's clear that the clients will adopt more and WinRT based APIs so we'd like to avoid API-level overlap as much as possible. .NET has a long history of "wrapping" OS APIs which is great for improving usability of some APIs but really hurt in the long run when the OS innovates because .NET usually versions at different rate than the OS. Since WinRT came alive the OS level APIs are virtually as usable as .NET APIs so the need to wrap OS functionality for gaining usability has disappeared.
That being said, it's also clear that networking is one of those concepts that make sense on both server as well as client. We also see that many customers want to share networking code across server and clients -- in the end, a server talking to another server acts as a client. Thus, having a managed HttpClient still makes a lot of sense.
However, given the issues around us wrapping and thus hiding OS APIs we are thinking of ways to have a meaningful interoperability story between the managed and the WinRT HttpClient. For example we could have have HttpClientHandler that takes an IHttpFilter. Stay tuned.
> Also do you have any plans to improve HttpCaching support on all platforms? (ETag/Cache-Control header handling).
Our number one priority is having consistency between all the platforms. Where we can't have consistency we ensure that you can write code that works on all platform, by, for example using the optional feature pattern.
Of course, we'd also like to improve features. The tricky part with HttpClient is that our out-of-band release doesn't contain the implementation for all platforms. On the platforms that have it (e.g. Windows Store and .NET Framework 4.5) we have to use the platform one. That means, adding features is a matter of moving those platforms as well. So I'm afraid the answer is there aren't plans but a strong desire on our side but this will likely take much longer than the speed in which we usually deliver NuGet packages.
@Martin: cache-control: private means that the cache cannot be shared between users. Have the server set cache-control: no-cache and it should work.
Yeah, finally !!
Many thanks for this amazing work.