Compression in netstandard

We want to activate the Compression feature of ServiceStack as described here in the docs. We ran into a couple of problems:

Using the SendAsync-methods does not work, because it seems that the Content-Encoding Header is not set. I went ahead and opened a PR on GitHub that tries to solve this. We got the Request Compression to work by switching to the synchronous Send-methods.

After activating the Response-Compression by using the ToOptimizedResult on the server side we ran into more problems with the client.

There are two problems:

  1. The client does not set the AcceptEncoding Header (in netstandard this is commented out with a TODO, see here)

  2. When we set the AcceptEncoding-Header in a RequestFilter like so:

    private static void RequestFilter(HttpWebRequest httpWebRequest)
    {
    httpWebRequest.Headers.Add(HttpRequestHeader.AcceptEncoding, CompressionTypes.Deflate);
    httpWebRequest.AutomaticDecompression = DecompressionMethods.Deflate;
    It seems that content is not being decompressed automatically in netstandard. When debugging we found that the ContentEncoding-Header is empty, therefore GetResponse is not decompressing. When we used wireshark to analyze the Headers we saw, that the ContentEncoding-Header was set (to deflate). With a ResponseFilter we got it to work:

    private static void ResponseFilter(HttpWebResponse httpWebResponse)
    {
    httpWebResponse.GetResponseStream().Decompress(CompressionTypes.Deflate);
    }

Is this a known limitation of netstandard at the moment or can we get rid of these workarounds somehow?

.NET Core’s HttpWebRequest is a completely different implementation for .NET Framework’s HttpWebRequest where it implements a partial feature-set where it’s a effectively a wrapper around HttpClient as such we recommend using JsonHttpClient for .NET Core given it use the same HttpClient based implementation for all .NET platforms.

We did run into issues trying to support different .NET Standard clients early on in our .NET Standard support, but it appears the compatibility has improved with .NET Standard 2.0 so I’ve un-commented AddCompression in this commit. The issue with .NET Core’s HttpWebRequest not auto decompressing is still an issue so I’ve switched all calls to GetResponseStream() to use the compat ResponseStream() ext method in this commit.

These changes should auto-enable compression support in .NET Standard projects which is available from v5.1.1 that’s now available on MyGet.

Thank you very much for fixing these issues! We will consider switching to JsonHttpClient as suggested.

We found another small issue: The compression seems to swallow exceptions that happen in a Service. We modified the OnAfterExecute so that ErrorResponses are not compressed (because clients are not handling compressed ErrorResponses correctly):

    public override object OnAfterExecute(IRequest req, object requestDto, object response)
    {
        response = base.OnAfterExecute(req, requestDto, response);
        var httpResult = response as IHttpResult;
        if (response != null && !(response is CompressedResult) && !(response is ErrorResponse) &&
            !(httpResult?.Response is ErrorResponse))
        {
            response = req.ToOptimizedResult(response);
        }

        return response;
    }