HTTP协议中的压缩

Http协议中使用Accept-Encoding和Content-Encoding头来表示期望Response内容的编码和当前Request的内容编码。而Http内容的压缩其实是内容编码的子集。所以也通过这两个头来描述Http Request和Response内容的压缩方式。

常用的压缩算法有gzip(采用GNU zip压缩)和deflate(采用zlib的格式压缩),对应的Http头中的值也为:gzip或者deflate.

内容压缩与解压

Web服务器可以配置进行全局压缩和解压。当压缩或者解压需要基于某些逻辑进行判断,则要自行实现。

浏览器(或者部分移动端网络库,包括iOS系统网络库)会对Content-Encoding头的值设为gzip或deflate的Response自动解压。而压缩则需要自己实现。

实现

这里采用DotNetZip库进行压缩和解压。

首先创建两个压缩类来分别对gzip和deflate进行处理:

public abstract class Compressor
{
        public abstract byte[] Compress(byte[] originalData);

        public abstract byte[] Decompress(byte[] compressedData);
}

public class DeflateCompressor : Compressor
    {
        public static string Name => "Deflate";

        public override byte[] Compress(byte[] originalData)
        {
            using (var outputStream = new MemoryStream())
            {
                using (var gzipStream = new DeflateStream(outputStream, CompressionMode.Compress, CompressionLevel.BestSpeed))
                {
                    gzipStream.Write(originalData, 0, originalData.Length);
                }

                return outputStream.ToArray();
            }
        }

        public override byte[] Decompress(byte[] compressedData)
        {
            using (var inputStream = new MemoryStream(compressedData))
            {
                var outputStream = new MemoryStream();
                var gzipStream = new DeflateStream(inputStream, CompressionMode.Decompress, CompressionLevel.BestSpeed);
                int blockSize = 10 * 1024;
                int readSize = 1;
                while (readSize > 0)
                {
                    byte[] buffer = new byte[blockSize];
                    readSize = gzipStream.Read(buffer, 0, blockSize);
                    if (readSize > 0)
                    {
                        outputStream.Write(buffer, 0, readSize);
                    }
                }

                outputStream.Flush();
                return outputStream.ToArray();
            }
        }
    }
View Code

相关文章: