Edward83
Edward83

Reputation: 6686

C# HttpListener Response + GZipStream

I use HttpListener for my own http server (I do not use IIS). I want to compress my OutputStream by GZip compression:

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");

But I getting error in Chrome:

ERR_CONTENT_DECODING_FAILED

If I remove AddHeader, then it works, but the size of response is not seems being compressed. What am I doing wrong?

Upvotes: 6

Views: 7182

Answers (3)

Nickz
Nickz

Reputation: 1880

Hopeful this might help, they discuss how to get GZIP working.

Sockets in C#: How to get the response stream?

Upvotes: 0

user1088520
user1088520

Reputation:

The first problem (as mentioned by Brent M Spell) is the wrong position of the header. The second is that you don't use properly the GZipStream. This stream requires a "top" stream to write to, meaning an empty stream (you fill it with your buffer). Having an empty "top" stream then all you have to do is to write on GZipStream your buffer. As a result the memory stream will be filled by the compressed content. So you need something like:

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

Upvotes: 5

Brent M. Spell
Brent M. Spell

Reputation: 2257

The problem is that your transfer is going in the wrong direction. What you want to do is attach the GZipStream to the Response.OutputStream and then call CopyTo on the MemoryStream, passing in the GZipStream, like so:

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

Upvotes: 11

Related Questions