C# HttpListener Response + GZipStream

本文关键字:GZipStream Response HttpListener | 更新日期: 2023-09-27 18:08:49

我使用HttpListener为我自己的http服务器(我不使用IIS)。我想用GZip压缩压缩我的OutputStream:

byte[] refBuffer = Encoding.UTF8.GetBytes(...some data source...);
var varByteStream = new MemoryStream(refBuffer);
System.IO.Compression.GZipStream refGZipStream = new GZipStream(varByteStream, CompressionMode.Compress, false);
refGZipStream.BaseStream.CopyTo(refHttpListenerContext.Response.OutputStream);
refHttpListenerContext.Response.AddHeader("Content-Encoding", "gzip");

但我得到错误在Chrome:

ERR_CONTENT_DECODING_FAILED

如果我删除AddHeader,那么它的工作,但响应的大小似乎没有被压缩。我做错了什么?

C# HttpListener Response + GZipStream

问题是你的转会方向错了。您要做的是将GZipStream附加到响应。然后在MemoryStream上调用CopyTo,传入GZipStream,如下所示:

refHttpListenerContext.Response.AddHeader("Content-Encoding", "gzip"); 
byte[] refBuffer = Encoding.UTF8.GetBytes(...some data source...); 
var varByteStream = new MemoryStream(refBuffer); 
System.IO.Compression.GZipStream refGZipStream = new GZipStream(refHttpListenerContext.Response.OutputStream, CompressionMode.Compress, false); 
varByteStream.CopyTo(refGZipStream); 
refGZipStream.Flush();

第一个问题(正如Brent M Spell所提到的)是标题的错误位置。第二是你没有正确使用GZipStream。这个流需要一个"顶部"流来写,这意味着一个空流(你用你的缓冲区填充它)。有一个空的"顶部"流,那么你所要做的就是在GZipStream上写你的缓冲区。因此,内存流将被压缩的内容填充。所以你需要这样写:

byte[] buffer = ....;
using (var ms = new MemoryStream())
{
    using (var zip = new GZipStream(ms, CompressionMode.Compress, true))
    zip.Write(buffer, 0, buffer.Length);
    buffer = ms.ToArray();
}
response.AddHeader("Content-Encoding", "gzip");
response.ContentLength64 = buffer.Length;
response.OutputStream.Write(buffer, 0, buffer.Length);

希望这能有所帮助,他们讨论了如何使GZIP工作。

c#中的套接字:如何获得响应流?