2011-09-15 36 views
5

我使用HttpListener为我自己的http服务器(我不使用IIS)。我想压缩由gzip压缩我的OutputStream:C#HttpListener响应+ GZipStream

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的,那么它的工作原理,但大小回应似乎没有被压缩。我究竟做错了什么?

+0

由于你实际上明确地写内容为压缩的,所以不可能因某个头文件而被压缩。你确定Chrome不仅仅给你文件的解压缩大小吗? – Ryan

+0

@minitech,很好的问题!我试图检查流量的实际大小。 – Edward83

回答

9

问题是您的传输方向错误。你想要做什么是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(); 
4

(如由布伦特中号拼写提及)第一个问题是报头的错误的位置。第二个是你没有正确使用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);