开发者

Why does the php fread() function sometimes prefix each line with its length?

开发者 https://www.devze.com 2023-01-27 00:17 出处:网络
I am using PHP to perform a POST request from a socket. Here is a code snippet: // open a socket connection on port 80

I am using PHP to perform a POST request from a socket. Here is a code snippet:

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

However, each line of the response seems to be prefixed with its length in hex. Why is that happening?

For example, a test cgi script, to which I post, returns its environment:

BASH=/bin/bash
BASHOPTS=cmdhist:extquote:force_fignore:hostcomplete:interactive_comments:progcomp:promptvars:sourcepath
BASH_ALIASES=()
BASH_ARGC=()
开发者_StackOverflow社区BASH_ARGV=()

But my PHP function ends up with this:

f
BASH=/bin/bash

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

10
BASH_ALIASES=()


You should use HTTP/1.0, because 1.1 servers typically respond with the Transfer-Encoding: chunked (= which are the parts prefixed by hex numbers).

You could try to send a request begging for identity content encoding, but chunked is required from all HTTP/1.1 clients as transfer format, so that might be unreliabe.


Its not each line, which is prefixed with its length. As mario suggested the the Server sends the data as chunked. Every chunk begins with the length of the chunk, the data and a double newline (=> empty line). The chunk itself can contain any valid (in terms of http) data, which means, that it can also contain multiple lines.

You can use this for yourself. If you receive a chunked transfer you can give fread() the length of the chunk as parameter instead of an abritrary int (here: 5000). So you will receive the whole chunk at once.

0

精彩评论

暂无评论...
验证码 换一张
取 消