HttpWebRequest & Native GZip Compression - PullRequest
58 голосов
/ 08 мая 2009

При запросе страницы со сжатием Gzip я получаю много следующих ошибок:

System.IO.InvalidDataException: CRC в нижнем колонтитуле GZip не соответствует CRC рассчитывается по распакованному данные

Я использую собственный GZipStream для распаковки и пытаюсь решить эту проблему. Имея это в виду, есть ли способ обойти эту или другую библиотеку GZip (бесплатно?), Которая будет правильно решать эту проблему?

Я проверяю, что WebResponse ContentEncoding является GZIP

Обновление 5/11 Упрощенный фрагмент

//Caller
public void SOSampleGet(string url) 
{
    // Initialize the WebRequest.
    webRequest = (HttpWebRequest)WebRequest.Create(url);
    webRequest.Method = WebRequestMethods.Http.Get;
    webRequest.KeepAlive = true;
    webRequest.Accept = "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8";
    webRequest.Headers.Add("Accept-Encoding", "gzip,deflate");
    webRequest.Referer = WebUtil.GetDomain(url);

    HttpWebResponse webResponse = (HttpWebResponse)webRequest.GetResponse();    

    using (Stream stream = GetStreamForResponse(webResponse, READTIMEOUT_CONST))
    {
        //use stream
    }
}

//Method
private static Stream GetStreamForResponse(HttpWebResponse webResponse, int readTimeOut)
{
    Stream stream;
    switch (webResponse.ContentEncoding.ToUpperInvariant())
    {
        case "GZIP":
            stream = new GZipStream(webResponse.GetResponseStream(), CompressionMode.Decompress);
            break;
        case "DEFLATE":
            stream = new DeflateStream(webResponse.GetResponseStream(), CompressionMode.Decompress);
            break;

        default:
            stream = webResponse.GetResponseStream();
            stream.ReadTimeout = readTimeOut;
            break;
        }    
    return stream;
}

Ответы [ 6 ]

126 голосов
/ 15 октября 2011

А как насчет веб-запроса свойства AutomaticDecompression, доступного с .net 2? Просто добавьте:

webRequest.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;

Также добавляет gzip, deflate к заголовку подтверждения кодировки.

См. http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.automaticdecompression.aspx

3 голосов
/ 13 июня 2017

Для .NET Core все немного сложнее. GZipStream необходим, поскольку для AutomaticCompression отсутствует свойство (на момент написания). Смотрите мой ответ здесь: https://stackoverflow.com/a/44508724/2421277

Код ответа:

var req = WebRequest.CreateHttp(uri);

/*
 * Headers
 */
req.Headers[HttpRequestHeader.AcceptEncoding] = "gzip, deflate";

/*
 * Execute
 */
try
{
    using (var resp = await req.GetResponseAsync())
    {
        using (var str = resp.GetResponseStream())
        using (var gsr = new GZipStream(str, CompressionMode.Decompress))
        using (var sr = new StreamReader(gsr))

        {
            string s = await sr.ReadToEndAsync();  
        }
    }
}
catch (WebException ex)
{
    using (HttpWebResponse response = (HttpWebResponse)ex.Response)
    {
        using (StreamReader sr = new StreamReader(response.GetResponseStream()))
        {
            string respStr = sr.ReadToEnd();
            int statusCode = (int)response.StatusCode;

            string errorMsh = $"Request ({url}) failed ({statusCode}) on, with error: {respStr}";
        }
    }
}
2 голосов
/ 08 мая 2009

Я нашел пример кода, который показывает весь запрос / ответ для страниц, закодированных GZip. Использует GZipStream.

http://www.know24.net/blog/Decompress+GZip+Deflate+HTTP+Responses.aspx

2 голосов
/ 08 мая 2009

Вы смываете и закрываете поток? Попробуйте обернуть ваш GZipStream оператором использования.

1 голос
/ 08 мая 2009

См. Мой комментарий выше, но это обычно является признаком поврежденного файла. Если сайт принадлежит вам, замените файл, к которому вы пытаетесь получить доступ.

0 голосов
/ 08 мая 2009

Собственный GZipStream может читать сжатый поток GZIP ( RFC 1952 ), но не может обрабатывать формат файла ZIP.

С http://www.geekpedia.com/tutorial190_Zipping-files-using-GZipStream.html:

Недостаток использования GZipStream класс над третьей стороной продукт в том, что он ограничен возможностей. Одно из ограничений является то, что вы не можете дать имя файл, который вы помещаете в архив. Когда GZipStream сжимает файл в ZIP-архив, он принимает последовательность байтов из этого файла и использует алгоритмы сжатия, которые создать меньшую последовательность байтов. Новая последовательность байтов помещена в новый ZIP файл. Когда вы открываете ZIP файл вы откроете в архиве сам файл; самый популярный ZIP экстракторы (WinZip, WinRar и др.) будут показать содержимое ZIP как файл с таким же архивом сам по себе.


РЕДАКТИРОВАТЬ: выше примечание неправильно . GZipStream не создает ZIP-файл. Это не «Поток ZIP с одним файлом». Это GZIP Stream. Это разные вещи. Нет гарантии, что инструменты, работающие с ZIP-архивами, будут обрабатывать файл .gz.


Для реализации, которая может читать ZIP-архивы, в отличие от однофайловых ZIP-потоков, попробуйте # ziplib (SharpZipLib, ранее NZipLib) .

...