59 votes

HttpWebRequest et compression native GZip

Lorsque je demande une page avec la compression Gzip, je reçois un grand nombre des 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 données décompressées

J'utilise le GZipStream natif pour décompresser et je cherche à résoudre ce problème. Dans cette optique, existe-t-il une solution de contournement ou une autre bibliothèque GZip (gratuite ?) qui gère correctement ce problème ?

Je vérifie que le ContentEncoding du 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;
}

129voto

user389823 Points 2406

Qu'en est-il de la propriété de décompression automatique des requêtes Web disponible depuis .net 2 ? Il suffit d'ajouter :

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

Il ajoute également le gzip,deflate à l'en-tête d'encodage accepté.

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

2voto

Mike L Points 557

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

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

2voto

Matthew Whited Points 12255

Est-ce que vous videz et fermez le flux ? Essayez d'envelopper votre GZipStream dans une déclaration Using.

1voto

MichaelICE Points 2209

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

-2voto

Andomar Points 115404

Le GZipStream natif peut lire un fichier compressé GZIP ( RFC 1952 ), mais il ne peut pas gérer le format de fichier ZIP.

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

L'inconvénient d'utiliser la classe GZipStream plutôt qu'un produit tiers. produit tiers, c'est qu'elle a des capacités limitées. L'une des limitations est que vous ne pouvez pas donner de nom au fichier que vous placez dans l'archive. Lorsque GZipStream compresse le fichier dans une archive ZIP, il prend la séquence d'octets de ce fichier et utilise des algorithmes de compression qui créent une séquence d'octets plus petite. La nouvelle séquence d'octets est placée dans le nouveau fichier ZIP. Lorsque vous ouvrez le fichier ZIP, vous ouvrirez le fichier archivé lui-même ; les extracteurs ZIP les plus populaires (WinZip, WinRar, etc.) vous vous montreront le contenu du ZIP sous forme de fichier fichier qui a le même nom que l'archive même.


EDIT : La note ci-dessus est incorrect . GZipStream ne produit pas un fichier ZIP. Il ne s'agit pas d'un "flux ZIP à fichier unique". C'est un flux GZIP. Ce sont des choses différentes. Il n'y a aucune garantie que les outils qui traitent les archives ZIP traiteront un fichier .gz.


Pour une implémentation qui peut lire les archives ZIP, par opposition aux flux ZIP à fichier unique, essayez #ziplib (SharpZipLib, anciennement NZipLib) .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X