2010-11-24 2 views
0

J'utilise PHP pour effectuer une requête POST depuis un socket. Voici un extrait de code:Pourquoi la fonction php fread() préfixe-t-elle parfois chaque ligne avec sa longueur?

// open a socket connection on port 80 
$fp = fsockopen($host, 80); 

// send the request headers: 
fwrite($fp, "POST $path HTTP/1.1\r\n"); 
fwrite($fp, "Host: $host\r\n"); 
fwrite($fp, "Referer: $referer\r\n"); 
fwrite($fp, "Content-type: application/x-www-form-urlencoded\r\n"); 
fwrite($fp, "Content-length: ". strlen($data) ."\r\n"); 
fwrite($fp, "Connection: close\r\n\r\n"); 
fwrite($fp, $data); 

$result = ''; 
while(!feof($fp)) { 
    // receive the results of the request 
    $result .= fread($fp, 5000); 
} 

Cependant, chaque ligne de la réponse semble être préfixé par sa longueur dans l'hexagone. Pourquoi cela se passe-t-il?

Par exemple, un script cgi test, auquel je poste, retourne son environnement:

BASH=/bin/bash 
BASHOPTS=cmdhist:extquote:force_fignore:hostcomplete:interactive_comments:progcomp:promptvars:sourcepath 
BASH_ALIASES=() 
BASH_ARGC=() 
BASH_ARGV=() 

Mais ma fonction PHP se termine avec ceci:

f 
BASH=/bin/bash 

69 
BASHOPTS=cmdhist:extquote:force_fignore:hostcomplete:interactive_comments:progcomp:promptvars:sourcepath 

10 
BASH_ALIASES=() 

Répondre

3

Vous devez utiliser HTTP/1.0, parce que 1.1 les serveurs répondent généralement avec le Transfer-Encoding: chunked (= qui sont les parties préfixées par des nombres hexadécimaux).

Vous pouvez essayer d'envoyer une requête en demandant identity le codage de contenu, mais le chunked est requis de tous les clients HTTP/1.1 en tant que format de transfert, donc cela pourrait être unreliabe.

1

Ce n'est pas chaque ligne qui est préfixée par sa longueur. Comme mario a suggéré le serveur envoie les données comme segmenté. Chaque bloc commence par la longueur du bloc, les données et un double-ligne double (=> ligne vide). Le bloc lui-même peut contenir toutes les données valides (en termes de http), ce qui signifie qu'il peut également contenir plusieurs lignes.

Vous pouvez l'utiliser pour vous-même. Si vous recevez un transfert en bloc, vous pouvez donner fread() la longueur du morceau en tant que paramètre au lieu d'un int abritrary (ici: 5000). Donc, vous recevrez le morceau entier à la fois.

Questions connexes