2010-11-24 3 views
0

Ich verwende PHP, um eine POST-Anfrage von einem Socket durchzuführen. Hier ist ein Code-Schnipsel:Warum setzt die php fread() Funktion manchmal jede Zeile mit ihrer Länge voran?

// 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); 
} 

Allerdings scheint jede Zeile der Antwort mit seiner Länge in Hex vorangestellt werden. Warum passiert das?

Zum Beispiel kann ein Test CGI-Skript, auf die ich schreiben, gibt seine Umgebung:

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

Aber meine PHP-Funktion endet mit auf den Punkt:

f 
BASH=/bin/bash 

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

10 
BASH_ALIASES=() 

Antwort

3

Sie sollten HTTP/1.0 verwenden, da 1.1-Server antworten normalerweise mit der Transfer-Codierung: chunked (= die Teile sind mit Hexadezimalzahlen vorangestellt).

Sie könnten versuchen, eine Anfrage zu senden, die nach identity Inhaltscodierung fragt, aber Chunked wird von allen HTTP/1.1-Clients als Übertragungsformat benötigt, so dass es unzuverlässig sein könnte.

1

Es ist nicht jede Zeile, die mit ihrer Länge vorangestellt ist. Wie Mario vorgeschlagen hat, sendet der Server die Daten als chunked. Jeder Chunk beginnt mit der Länge des Chunks, den Daten und einem doppelten Zeilenumbruch (=> leere Zeile). Der Chunk selbst kann beliebige gültige (in Bezug auf http) Daten enthalten, was bedeutet, dass er auch mehrere Zeilen enthalten kann.

Sie können dies für sich selbst verwenden. Wenn Sie eine chunked Übertragung erhalten, können Sie fread() die Länge des Chunks als Parameter anstelle eines abritrary int geben (hier: 5000). So erhalten Sie den ganzen Brocken auf einmal.

Verwandte Themen