C # HttpListener Response + GZipStream - PullRequest
       22

C # HttpListener Response + GZipStream

5 голосов
/ 16 сентября 2011

Я использую HttpListener для своего http-сервера (я не использую IIS). Я хочу сжать свой OutputStream сжатием GZip:

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, то он работает, но размер ответа не сжимается. Что я делаю не так?

Ответы [ 3 ]

9 голосов
/ 16 сентября 2011

Проблема в том, что ваш перевод идет в неправильном направлении. Что вы хотите сделать, это присоединить 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 голосов
/ 07 июня 2012

Первая проблема (как упомянуто 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 голосов
/ 16 сентября 2011

Надеюсь, это поможет, они обсудят, как заставить работать GZIP.

Сокеты в C #: Как получить поток ответов?

...