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(); } } }