简体   繁体   中英

Skype Emoticon downloaded with C# HttpClient is a different byte stream than downloaded with browser

This is the most bizarre thing.

I'm trying to download this file using the C# HttpClient: https://statics.teams.microsoft.com/evergreen-assets/skype/v2/smile/50.png

It happens to be one of the Microsoft Teams emoticon image files.

笑脸.png

(Incidentally, I had to download this image locally to my machine with Chrome, then upload it from there, as the StackOverflow image upload couldn't handle the URL either...)

I've tried a number of different cracks at the code to download this file - the most straightforward and usual way of doing so, stripped down to essentials, is:

var client = new HttpClient();
var webStream = await client.GetStreamAsync("https://statics.teams.microsoft.com/evergreen-assets/skype/v2/smile/50.png");
using (var fileStream = new FileStream("smilely.png", FileMode.OpenOrCreate)) {
    webStream.CopyTo(fileStream);
}

I've tried several different ways using HttpClient, using the System.Net.WebClient, and raw WebRequests as well, with the same results.

If I put the URL into my browser and go to it, I see the image as expected, but if I am downloading the file from C#, I get a corrupted image that won't open.

The proper file, downloaded using the browser is 2127 bytes, starting with the proper PNG header bytes, like so:

89 50 4E 47 0D 0A 1A 0A

The file that I download programmatically is screwed up, with an entirely different byte stream, which is only 2093 bytes, and starts:

1F 8B 08 00 00 00 00 00

I don't have this problem downloading other emoticon images from the same set, like https://statics.teams.microsoft.com/evergreen-assets/skype/v2/laugh/50.png

在此处输入图像描述

What in the world could possibly be going on with this?

1F 8B is the magic number for GZIP.

If we look at the response content headers with:

var client = new HttpClient();
var response = await client.GetAsync("https://statics.teams.microsoft.com/evergreen-assets/skype/v2/smile/50.png");
var contentHeaders = response.Content.Headers;

We can see that ContentEncoding is gzip .

So it looks like something's up with the server configuration. Normally a server will only give you something with content-encoding if you explicitly state that you accept encoded responses with the Accept-Encoding header, but it looks like this particular server isn't playing by the rules for this file.

Your browser did say that it accepted gzip-encoded files, so doesn't blink when it gets a gzip-encoded response. Your C# code wasn't expecting that.

You can get HttpClient to automatically decompress gzip-encoded content with:

var handler = new HttpClientHandler()
{
    AutomaticDecompression = System.Net.DecompressionMethods.GZip
};
var client = new HttpClient(handler);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM