Search code examples
c#.nethttp-headershttpresponsehttpresponsemessage

ERR_CONTENT_DECODING_FAILED when trying to return gzip with HttpResponseMessage


Getting 'ERR_CONTENT_DECODING_FAILED' in the browser when running:

                HttpResponseMessage response = Request.CreateResponse();
                response.Content = new StringContent("H4sIAAAAAAAAAytJLS5RKIETAAP1QQcPAAAA");
                response.StatusCode = HttpStatusCode.OK;
                response.Content.Headers.ContentType = new MediaTypeHeaderValue("text/html");
                response.Content.Headers.ContentType.CharSet = Encoding.UTF8.HeaderName;
                response.Headers.Add("Vary", "Accept-Encoding");
                response.Content.Headers.ContentEncoding.Clear();
                response.Content.Headers.ContentEncoding.Add("gzip");
                return response;

H4sIAAAAAAAAAytJLS5RKIETAAP1QQcPAAAA is 'test test test'

Expecting the response to be 'test test test' in Chrome


Solution

  • You made a false assumption. The string "H4sIAAAAAAAAAytJLS5RKIETAAP1QQcPAAAA" itself is not gzip data. Even if you twiddle the HTTP headers just right, the fact that this string is not gzip data doesn't change. You just told the web browser the content you sent to it is something (gzip) that it really is not.

    Think about it. Gzip stream data is just some binary data stream. It's not text in any shape or form, it's just some binary data. (In a similar way, the .exe or .dll file of your program is also -mostly- binary data that is not text in any shape or form, either.) So, a string cannot really hold the actual gzip data directly.

    So, what is this "H4sIAAAAAAAAAytJLS5RKIETAAP1QQcPAAAA" string then? It is a Base64 encoding of binary data. Base64-decoding this string yields the bytes (in hex notation):

    1F 8B 08 00 00 00 00 00  00 03 2B 49 2D 2E 51 28
    81 13 00 03 F5 41 07 0F  00 00 00
    

    These bytes are your actual gzip data.

    So, one possible solution to your problem is to first decode the Base64 string you got into a byte array. And then, if you really want to send the gzip data in the byte array as-is to the web browser, you would use a ByteArrayContent instead of a StringContent (since you have now a byte array instead of a string). Don't forget to set the http headers appropriately.