2009-07-26 7 views
15

J'ai une grande quantité de données (~ 100k) que mon application C# envoie sur mon serveur Apache avec mod_gzip installé. J'essaye de gzip les données d'abord en utilisant System.IO.Compression.GZipStream. PHP reçoit les données gzippées brutes, donc Apache ne le décompresse pas comme je m'y attendais. Est-ce que je manque quelque chose?Envoi de données gzippées dans WebRequest?

System.Net.WebRequest req = WebRequest.Create(this.Url); 
req.Method = this.Method; // "post" 
req.Timeout = this.Timeout; 
req.ContentType = "application/x-www-form-urlencoded"; 
req.Headers.Add("Content-Encoding: gzip"); 

System.IO.Stream reqStream = req.GetRequestStream(); 

GZipStream gz = new GZipStream(reqStream, CompressionMode.Compress); 

System.IO.StreamWriter sw = new System.IO.StreamWriter(gz, Encoding.ASCII); 
sw.Write(large_amount_of_data); 
sw.Close(); 

gz.Close(); 
reqStream.Close() 


System.Net.WebResponse resp = req.GetResponse(); 
// (handle response...) 

Je ne suis pas tout à fait sûr "Content-Encoding: gzip" applique aux en-têtes fournis par le client.

+6

+1 pour le code affichant qui compresse les données affichées. Je crois que vous êtes le seul à l'avoir fait dans toute l'ère Internet ;-) –

+0

J'adorerais entendre si l'une des idées ci-dessous vous a aidé - j'essaie de résoudre le même problème. –

Répondre

1

Selon http://www.dominoexperts.com/articles/GZip-servlet-to-gzip-your-pages

Vous devez setContentType() au format original, que vous faites avec l'application/x-www-form-urlencoded je suppose. Alors ...

// See if browser can handle gzip 
String encoding=req.getHeader("Accept-Encoding"); 
if (encoding != null && encoding.indexOf("gzip") >=0) { // gzip browser 
     res.setHeader("Content-Encoding","gzip"); 
     OutputStream o=res.getOutputStream(); 
     GZIPOutputStream gz=new GZIPOutputStream(o); 
     gz.write(content.getBytes()); 
     gz.close(); 
     o.close(); 
      } else { // Some old browser -> give them plain text.      PrintWriter o = res.getWriter(); 
        o.println(content); 
        o.flush(); 
        o.close(); 
      } 
4

J'ai regardé le code source pour mod_gzip et je ne pouvais pas trouver un code qui décompresse données. Apparemment mod_gzip compresse seulement les données sortantes qui n'est pas trop surprenant après tout. La fonctionnalité que vous recherchez est probablement rarement utilisée, et j'ai peur que vous deviez faire votre propre décompression sur le serveur.

4

En ce qui concerne votre question de savoir si Content-Encoding est applicable aux en-têtes fournis par le client - selon HTTP/1.1 standard, il est:

(de la section 7)

messages de demande et de réponse peuvent transférer une entité si non autrement restreint par la méthode de requête ou le code d'état de réponse.

(de la section 7,1)

entity-header = Allow     ; Section 14.7 
        | Content-Encoding   ; Section 14.11 
        | Content-Language   ; Section 14.12 
        | Content-Length   ; Section 14.13 
        | Content-Location   ; Section 14.14 
        | Content-MD5    ; Section 14.15 
        | Content-Range   ; Section 14.16 
        | Content-Type    ; Section 14.17 
        | Expires     ; Section 14.21 
        | Last-Modified   ; Section 14.29 
        | extension-header 
+5

Ceci est vrai, avec la mise en garde que la plupart des serveurs ne feront pas la décompression des requêtes HTTP, à cause de la possibilité d'attaques dites "Zip Bomb". – EricLaw

2

Vous devez changer

req.Headers.Add("Content-Encoding: gzip"); 

à

req.Headers.Add("Content-Encoding","gzip"); 
0

Sur le PHP côté cela dépouilleront-tête et pied de page du fichier

function gzip_stream_uncompress($data) { return gzinflate(substr($data, 10, -8)); }