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).
How to use automatic decompression
(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(); if (handler.SupportsAutomaticDecompression) { handler.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate; } 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
Host: en.wikipedia.org
Accept-Encoding: gzip, deflate
Connection: Keep-Alive
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
Server: nginx/1.1.19
Date: Wed, 13 Mar 2013 14:04:24 GMT
Content-Type: text/html; charset=UTF-8
Content-Length: 17765
Connection: keep-alive
X-Content-Type-Options: nosniff
Content-Language: en
Last-Modified: Tue, 05 Mar 2013 03:38:51 GMT
Content-Encoding: gzip
Expires: Thu, 01 Jan 1970 00:00:00 GMT
Cache-Control: private, s-maxage=0, max-age=0, must-revalidate
Vary: Accept-Encoding,Cookie
Age: 179
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.
Summary
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.
blogs.msdn.com/…/httpclient-2-2-is-now-rc.aspx
@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 decompression 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.
blogs.msdn.com/…/httpclient.aspx
@Morten: Thanks keeping us on our toes ๐
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.
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.
Amazing, thanks guys.
Getting this error atm:
Error 1 The type 'System.Net.CookieContainer' is defined in an assembly that is not referenced. You must add a reference to assembly 'System.Net, Version=2.0.5.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e, Retargetable=Yes'.
Error 2 'System.Net.CookieContainer' does not contain a definition for 'Add' and no extension method 'Add' accepting a first argument of type 'System.Net.CookieContainer' could be found (are you missing a using directive or an assembly reference?)
I've tried reparing vs2012 update3 with no luck.
I've tried msiexec.exe /fomus {6A6F1B4D-1BCE-3703-93D8-4494FB7F1280} with no luck (doesnt work for me).
Hints?
@Sproa: It seems the command we provided is outdated. Can you try to repair the installation via Programs and Features (Add or remove programs)? In essence, select the appropriate VS installation/highest VS update and click on "Change". In the VS setup click the "Repair" button.
@Immo Landwerth
I tried the repair on the vs2012 udpate 3 as well (see my previous post) and that did not help. Can add I've also installed the 2013 preview. Could that be the culprit?
Now when Windows 8.1 preview is available with new features in HttpClient, do you plan to backport these features to HttpClient NuGet package as well?
@Sproa: If the problem still exists please send a mail to immol at microsoft dot com. I'll put you in touch with people that can troubleshoot this issue.
@Martin: The WinRT version of HttpClient is tied to Windows 8.1 while our NuGet package supports a wider range of platforms. We are thinking of ways to align the two without losing creating a platform dependency in all cases.
Does the HttpClient 2.2 handle custom ssl certificates without throwing a 404 not found for WP7/8?
Thanks
@AsurionDevelopers: HttpClient uses the phone's networking stack and thus has the same limitations. So I'm afraid the answer is no.
@Immo @Sproa Did you find a solution to the "assembly not referenced" problem? I too side-installed VS2013 thinking it would be safe, but I cannot longer work on my Windows Phone project due this week! I've tried uninstalling VS2013, repairing VS2012, the WP8 SDK and VS2012 Update 3, but nothing seems to help. Any ideas are welcome.
@Mauricio DIAZ ORLICH
No I haven't. I am still waiting to hear back from techs at Microsoft that was put in touch with me.
Wow, this piece of software helps me a lot. Thanks!
Is there any way you can include in the response headers of .PostAsync() and .SendAsync() the "set-cookies" headers? In windows phone there is a know problem with httponly cookies that are not accessible through cookiecontainer. A simple solution will be to get the cookies in headers and forget the cookiecontainer implementation and process these myself.
I know I can pass the cookiecontainer in subsequent request, but the problem is that Iยดm "fighting" with lot of different servers that does not send the cookies in correct RFC format, so cookiecontainer miss these and this solution does not work for me. Also in WP there is no reflection support so I can not bypass the cookiecontainer to extract these cookies.
Any hint on this?
Looks like there is some problem with HttpClient Lib on Win Phone 8/7 with Content-Length header value
It does not give the content-length header value when doing a Head request. Content-Length is always "0".
Checked with Fidler and there Content-Length is there with a proper value.
Here is code in WinPhone 8 [Note: The same code works for Windows 8 store apps]
Uri uri = new Uri("download.microsoft.com/…/MSDN_EULA.pdf");
HttpClient cc = new HttpClient();
var request = new HttpRequestMessage(HttpMethod.Head, uri);
var response = await cc.SendAsync(request);
Response from Fidler when i configured Fidler for Windows Phone Emulator
HTTP/1.1 200 OK
Content-Length: 138139
Content-Type: application/octet-stream
Last-Modified: Tue, 07 Apr 2009 06:50:49 GMT
Accept-Ranges: bytes
ETag: "8f1c882f4db7c91:0"
Server: Microsoft-IIS/8.0
Content-Disposition: attachment
Date: Thu, 07 Nov 2013 05:39:40 GMT
Connection: keep-alive
Have any one faced this before ? Is there any workaround for this.
@Saurabh: indeed this appears to be an issue on Phone. We'll look into a fix in our next release. Thanks for reporting. For now you can workaround this by sending the HEAD with HttpWebRequest and looking at the Content-Length value in the Headers collection of the response (don't use the ContentLength property, as this will be incorrect and is the source of this bug).
Hi, I posted a bug report of trouble I am having when HttpClient makes http requests to a bad url:
stackoverflow.com/…/httpclient-async-requests-not-completing-for-large-batch-sent-out-in-a-loop
Hi, anyone having the following exception when simply trying to connect to a web service:
'iso-8859-1' is not a supported encoding name.
Parameter name: name
Client is using Silverlight 5 and web service is using Web API 2.0. Performing a simple GetStringAsync gives me this exception. I don't specify an encoding but I don't see a request event come out of the client using Fiddler.
I'm also struggling with the bug described by @Jagoba Los Arcos
I can't process my post request correctly, I tried setting them manually in the headers but it doesn't work anyway…