首页 文章

HttpWebRequest和Native GZip压缩

提问于
浏览
57

当请求具有Gzip压缩的页面时,我收到了很多以下错误:

System.IO.InvalidDataException:GZip页脚中的CRC与从解压缩数据计算的CRC不匹配

我正在使用本机GZipStream进行解压缩,正在寻找解决此问题的方法 . 考虑到这一点,是否有解决这个或另一个GZip库(免费?)的工作,它将正确处理这个问题?

我正在验证webResponse ContentEncoding是否为GZIP

Update 5/11 简化的snippit

//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 回答

  • 2

    自.net 2以来可用的webrequest AutomaticDecompression属性怎么样?只需添加:

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

    它还将gzip,deflate添加到accept编码头 .

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

  • 122

    你在冲洗和关闭溪流吗?尝试使用Using语句包装GZipStream .

  • 2

    我找到了一些示例代码,显示了GZip编码页面的整个请求/响应 . 它使用GZipStream .

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

  • -2

    对于.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}";
            }
        }
    }
    
  • 1

    请参阅上面的评论,但这通常是文件损坏的症状 . 如果该站点是您自己的站点,请替换您尝试访问的文件 .

  • 2

    本机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, formerly NZipLib) .

相关问题