HttpWebRequest & Native GZip Compression
При запросе страницы с сжатием 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;
}
Ответы
Ответ 1
Как насчет веб-ресурса AutomaticDecompression Property, доступного с .net 2? Просто добавьте:
webRequest.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
Он также добавляет gzip, deflate к заголовку кодировки accept.
См. http://msdn.microsoft.com/en-us/library/system.net.httpwebrequest.automaticdecompression.aspx
Ответ 2
Вы смываете и закрываете поток? Попробуйте обернуть GZipStream с помощью инструкции.
Ответ 3
Я нашел пример кода, который показывает весь запрос/ответ для GZip-кодированных страниц. Он использует GZipStream.
http://www.know24.net/blog/Decompress+GZip+Deflate+HTTP+Responses.aspx
Ответ 4
См. мой комментарий выше, но это обычно является признаком поврежденного файла. Если сайт принадлежит вам, замените файл, к которому вы пытаетесь получить доступ.
Ответ 5
Для .NET Core вещи немного больше связаны. A GZipStream
необходимо, так как для AutomaticCompression
нет свойства (с момента написания). См. Мой ответ здесь: fooobar.com/questions/101706/...
Код ответа:
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}";
}
}
}
Ответ 6
Нативный 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. Это разные вещи. Там нет гарантии, что инструменты, обрабатывающие ZIP-архивы, будут обрабатывать файл .gz.
Для реализации, которая может читать ZIP-архивы, в отличие от однопоточных ZIP-потоков, попробуйте # ziplib (SharpZipLib, ранее NZipLib),