在dotnet core 2 asp .net中路由特定的响应压缩?

时间:2017-09-08 03:45:46

标签: asp.net-core .net-core

这似乎有点无意义,但我希望我的一个API端点支持“最佳”gzip压缩。对于所有其他人,我想要“无”或“最快”。

这可能吗?我怎样才能做到这一点?

最好我想以某种方式从控制器操作中向服务指示我希望当前请求被GZip以及要使用的设置。

我以为我可以尝试从ResponseCompressionMiddleware中提取Invoke方法并将其混合到它自己的服务中,但我想先看看是否有更简单的东西。

2 个答案:

答案 0 :(得分:0)

好的,所以我玩这个太久了。这个答案是分享我如何设法让这个工作,但我不建议这种方法,希望有人可以指出一个我错过的非常简单的方法。

因此,如果没有进一步的说明,以下代码可以满足我的需求:

class GZipAttribute : ResultFilterAttribute
{
    private class ResponseCompressionOptionsProvider : IOptions<ResponseCompressionOptions>
    {
        private class GZipCompressionProviderOptionsProvider : IOptions<GzipCompressionProviderOptions>
        {
            public GZipCompressionProviderOptionsProvider(CompressionLevel compressionLevel)
            {
                this.Value = new GzipCompressionProviderOptions()
                {
                    Level = compressionLevel
                };
            }
            public GzipCompressionProviderOptions Value { get; private set; }
        }
        public ResponseCompressionOptionsProvider(CompressionLevel level)
        {
            this.Value = new ResponseCompressionOptions()
            {
                EnableForHttps = true
            };
            this.Value.Providers.Add(new GzipCompressionProvider(new GZipCompressionProviderOptionsProvider(level)));
        }
        public ResponseCompressionOptions Value { get; private set; }
    }

    public CompressionLevel CompressionLevel { get; private set; }
    public bool BodyContainsSecret { get; private set; }
    public bool BodyContainsFormInput { get; private set; }

    public GZipAttribute(CompressionLevel compressionLevel, bool bodyContainsSecret = true, bool bodyContainsFormInput = true)
    {
        CompressionLevel = compressionLevel;
    }

    private void logSkippingGzip(ResultExecutingContext ctxt, string reason)
    {
        ILogger logger = ctxt.HttpContext.RequestServices.GetService<ILogger>();
        logger.LogWarning("[GZip] SKIPPED -- " + reason);
    }

    public override async Task OnResultExecutionAsync(ResultExecutingContext executingContext, ResultExecutionDelegate next)
    {
        if (executingContext.HttpContext.Request.IsHttps && BodyContainsFormInput && BodyContainsSecret)
        {
            logSkippingGzip(executingContext, "Request is HTTPS but endpoint is not marked as being impervious to BREACH exploit.");
            await next();
        }
        else
            await new ResponseCompressionMiddleware((context) => { return next(); }, new ResponseCompressionProvider(executingContext.HttpContext.RequestServices, new ResponseCompressionOptionsProvider(CompressionLevel))).Invoke(executingContext.HttpContext);

        return;
    }
}

现在似乎在游泳,但我想要更简洁的东西。如果你们/ gals有任何其他想法,请告诉我。要应用此功能,我只需将[GZip(CompressionLevel.Optimal)]添加到我的MVC控制器中的任何操作。

答案 1 :(得分:0)

Mvc具有可以为特定路由/控制器添加中间件的功能。

请在此处查看中间件过滤器属性: https://blogs.msdn.microsoft.com/webdev/2016/11/16/announcing-asp-net-core-1-1/