using Ionic.Zlib;
using System;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Http.Filters;
namespace WebAPI.Filters
{
/// <summary>
/// 压缩返回信息
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method, Inherited = true, AllowMultiple = true)]
public class CompressionFilter : ActionFilterAttribute
{
public override Task OnActionExecutedAsync(HttpActionExecutedContext actionExecutedContext, CancellationToken cancellationToken)
{
if (actionExecutedContext.Response == null || actionExecutedContext.Request.Method == HttpMethod.Options)
{
return DefaultResult(actionExecutedContext, cancellationToken);
}
var content = actionExecutedContext.Response.Content;
if (content == null)
{
return DefaultResult(actionExecutedContext, cancellationToken);
}
var acceptEncoding = actionExecutedContext.Request.Headers.AcceptEncoding.Where(x => x.Value == "gzip" || x.Value == "deflate").ToList();
if (acceptEncoding.Count == 0)
{
return DefaultResult(actionExecutedContext, cancellationToken);
}
var bytes = content.ReadAsByteArrayAsync();
switch (acceptEncoding[0].Value)
{
case "gzip":
actionExecutedContext.Response.Content = new ByteArrayContent(CompressionHelper.GZipBytes(bytes.Result));
actionExecutedContext.Response.Content.Headers.Add("Content-Encoding", "gzip");
break;
case "deflate":
actionExecutedContext.Response.Content = new ByteArrayContent(CompressionHelper.DeflateBytes(bytes.Result));
actionExecutedContext.Response.Content.Headers.Add("Content-encoding", "deflate");
break;
}
return DefaultResult(actionExecutedContext, cancellationToken);
}
private Task DefaultResult(HttpActionExecutedContext actionExecutedContext, CancellationToken cancellationToken)
{
return base.OnActionExecutedAsync(actionExecutedContext, cancellationToken);
}
}
/// <summary>
/// 压缩帮助类
/// </summary>
internal static class CompressionHelper
{
public static byte[] DeflateBytes(byte[] bytes)
{
if (bytes.Length == 0)
{
return null;
}
using (var output = new MemoryStream())
{
using (var compressor = new DeflateStream(output, CompressionMode.Compress, CompressionLevel.Default))
{
compressor.Write(bytes, 0, bytes.Length);
}
return output.ToArray();
}
}
public static byte[] GZipBytes(byte[] bytes)
{
if (bytes.Length == 0)
{
return null;
}
using (var output = new MemoryStream())
{
using (var compressor = new GZipStream(output, CompressionMode.Compress, CompressionLevel.Default))
{
compressor.Write(bytes, 0, bytes.Length);
}
return output.ToArray();
}
}
}
}