Enable gzip/deflate compression

2019-01-24 13:24发布

I'm using ServiceStack (version 3.9.44.0) as a Windows Service (so I'm not using IIS) and I use both its abilities both as an API and for serving web pages.

However, I haven't been able to find how exactly I should enable compression when the client supports it.

I imagined that ServiceStack would transparently compress data if the client's request included the Accept-Encoding:gzip,deflate header, but I'm not seeing any corresponding Content-Encoding:gzip in the returned responses.

So I have a couple of related questions:

  1. In the context of using ServiceStack as a standalone service (without IIS), how do I enable compression for the responses when the browser accepts it.

  2. In the context of a C# client, how do similarly I ensure that communication between the client/server is compressed.

If I'm missing something, any help would be welcome.

Thank you.

2条回答
冷血范
2楼-- · 2019-01-24 13:51

For those interested, a partial answer to my own question, you can use the extension method ToOptimizedResult() or, if you are using caching ToOptimizedResultUsingCache().

For instance, returning a compressed result:

public class ArticleService : Service
{
  public object Get(Articles request) {
    return base.RequestContext.ToOptimizedResult( 
       new List<Articles> { 
            new Article {Ref = "SILVER01", Description = "Silver watch"},
            new Article {Ref = "GOLD1547", Description = "Gold Bracelet"}
       });
  }
}

References

查看更多
仙女界的扛把子
3楼-- · 2019-01-24 13:56

If you want to enable compression globally across your API, another option is to do this:

Add this override to your AppHost:

public override IServiceRunner<TRequest> CreateServiceRunner<TRequest>(ActionContext actionContext)
{
    return new MyServiceRunner<TRequest>(this, actionContext);
}

Then implement that class like this:

public class MyServiceRunner<TRequest> : ServiceRunner<TRequest>
{
    public MyServiceRunner(IAppHost appHost, ActionContext actionContext) : base(appHost, actionContext)
    {
    }

    public override void OnBeforeExecute(IRequestContext requestContext, TRequest request)
    {
        base.OnBeforeExecute(requestContext, request);
    }

    public override object OnAfterExecute(IRequestContext requestContext, object response)
    {
        if ((response != null) && !(response is CompressedResult))
            response = requestContext.ToOptimizedResult(response);

        return base.OnAfterExecute(requestContext, response);
    }

    public override object HandleException(IRequestContext requestContext, TRequest request, Exception ex)
    {
        return base.HandleException(requestContext, request, ex);
    }
}

OnAfterExecute will be called and give you the chance to change the response. Here, I am compressing anything that is not null and not already compressed (in case I'm using ToOptimizedResultUsingCache somewhere). You can be more selective if you need to but in my case, I'm all POCO objects with json.

References

查看更多
登录 后发表回答