C# HttpListener响应+ GZipStream

6

我使用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,则可以正常工作,但响应的大小似乎没有被压缩。我做错了什么?


你确定Chrome没有只给你文件的解压缩大小吗?因为你实际上正在显式地写入被压缩的内容,所以由于头文件导致某些东西没有被压缩是不可能的。 - Ry-
@minitech,好问题!!!我正在尝试检查流量的实际大小。 - Edward83
3个回答

11

问题在于您的传输方向是错误的。您想要做的是将GZipStream附加到Response.OutputStream上,然后调用CopyTo方法对MemoryStream进行复制,传入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();

5

第一个问题(如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);

0

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接