web-dev-qa-db-fra.com

HttpWebRequest et compression GZip native

Lorsque je demande une page avec une compression Gzip, j'obtiens beaucoup d'erreurs suivantes:

System.IO.InvalidDataException: le CRC dans le pied de page GZip ne correspond pas au CRC calculé à partir des données décompressées

J'utilise GZipStream natif pour décompresser et cherche à résoudre ce problème. Dans cet esprit, existe-t-il un moyen de résoudre ce problème ou une autre bibliothèque GZip (gratuite?) Qui gérera correctement ce problème?

Je vérifie que le ContentEncoding de webResponse est GZIP

Mise à jour 5/11 Un extrait simplifié

//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;
}
58
Pat

Qu'en est-il de la propriété webrequest AutomaticDecompression disponible depuis .net 2? Ajoutez simplement:

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

Il ajoute également le gzip, dégonfle à l'en-tête de codage d'acceptation.

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

127
Eugene

Pour .NET Core, les choses sont un peu plus impliquées. Un GZipStream est nécessaire car il n'y a pas de propriété (au moment de l'écriture) pour AutomaticCompression. Voir ma réponse ici: https://stackoverflow.com/a/44508724/2421277

Code de réponse:

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}";
        }
    }
}
3
pim

Rincez-vous et fermez-vous le flux? Essayez d'encapsuler votre GZipStream avec une instruction Using.

2
Matthew Whited

J'ai trouvé un exemple de code qui montre l'ensemble de la demande/réponse pour les pages encodées GZip. Il utilise GZipStream.

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

2
Mike L

Voir mon commentaire ci-dessus, mais cela est généralement le symptôme d'un fichier corrompu. Si le site vous appartient, remplacez le fichier auquel vous essayez d'accéder.

1
MichaelICE