Apache Chunked

02/09/2008

Ce fut long, ténébreux… Un stagiaire utilisant un proxy PHP que j’ai codé (pour des requête Ajax distantes) avait parfois des retours “cassés”. Le contenu était bien là, mais commençait souvent par un code du genre “356e”. Le contenu de la réponse était bien correcte, puis suivait un “0” (zéro)…

Je pensais que mon ami le stagiaire avait placé des caractères spéciaux… D’ailleurs il n’utilisait pas UTF-8 (oreille gauche tirée) et laissait de temps en temps des lignes vierges en fin de script (oreille droite tirée).

Mais ce ne fut pas de sa faute… le proxy fonctionnait convenablement et la solution a été trouvé en regardant les entêtes de retour que Apache me donnait. Lorsque ces “codes” bizarres apparaissaient, il y avait une directive dans l’entête: Transfer-Encoding: chunked.

Un petit tour dans les doc Apache, et me voilà avec cette phrase magnifique:\\ //Get Body Chunk//\\ //The container asks for more data from the request (If the body was too large to fit in the first packet sent over or when the request is chuncked). The server will send a body packet back with an amount of data which is the minimum of the request_length, the maximum send body size (8186 (8 Kbytes - 6)), and the number of bytes actually left to send from the request body.//\\ //If there is no more data in the body (i.e. the servlet container is trying to read past the end of the body), the server will send back an empty packet, which is a body packet with a payload length of 0. (0x12,0x34,0x00,0x00)//

Voilà donc le soucis :) La réponse renvoyée par Apache est encodée puisque trop longue ! J’ai donc trouvé la solution sur le script http://www.milw0rm.com/exploits/6053:

` function unchunk($data) { $dsize = 1; $offset = 0;

while($dsize>0){ $hsize_size = strpos($data, “\r\n”, $offset) - $offset;
$dsize = hexdec(substr($data, $offset, $hsize_size));

  //Remove $hsize\r\n from $data
  $data = substr($data, 0, $offset) . substr($data, ($offset + $hsize_size + 2) );
  $offset += $dsize;

  //Remove the \r\n before the next $hsize
  $data = substr($data, 0, $offset) . substr($data, ($offset+2) );

}
return $data; } `

A n’effectué que si vous trouvé le transfert Encoding à chunked, voici l’expression de test que je fais de mon coté:

//... $header est l'entête envoyé à Apache... à vous de la créer $fp = fsockopen($this->host,80) or die('ERROR'); fputs($fp,$header); $output = ""; $flag = false; $b = ""; $chunked=false; while (!feof($fp)) { $b = fgets($fp,4096); if(preg_match('/Transfer-Encoding: chunked\r/',$b)){ $chunked = true; } if($flag) $output .= $b; if(strlen(trim($b))==0) $flag = true; } fclose($fp); if($chunked) $output = $this->unchunk($output); echo $output;

Ca fonctionne chez moi sans soucis.

Ça peut vous intéresser aussi


Poste de développement PHP sous Fedora

Linux est un système parfait pour développer. Simple d’installation,...


Titanium le développement révolutionnaire

Voilà des années que je me tue à le dire,...


Développer un site dans votre home

Ce week-end, un ami est passé à la maison et ...


Docker Apache Mysql PHP

Ce matin un collègue me demande “comment tu ferais ...

Merci de m'aider à financer mes services

Si vous avez apprécié cet article, je vous serai reconnaissant de m'aider à me payer une petite bière :)

Si vous voulez en savoir plus sur l'utilisation de flattr sur mon blog, lisez cette page: Ayez pitié de moi

Commentaires

Ajouter un commentaire

Ajouter un commentaire

(*) Votre e-mail ne sera ni revendu, ni rendu public, ni utilisé pour vous proposer des mails commerciaux. Il n'est utilisé que pour vous contacter en cas de souci avec le contenu du commentaire, ou pour vous prévenir d'un nouveau commentaire si vous avez coché la case prévue à cet effet.