I have to write a PHP script that works as a client against another HTTP Server. This Server ignores the HTTP Connection:Close header and keeps the TCP connection open unless it is closed by the client. And here is my dilemma. I (the client) have to deciede when a HTTP request/response has finished and then close the connection. Simply use:
$data = file_get_contents($url);
.. won't work, as file_get_contents returns only if the connection timeout (default 30 seconds) has reached.
So I have to write my own read - loop like this (pseudo code):
$sock = fsockopen(...);
$data = '';
while($line = fgets($sock)) {
$data .= $line;
if(http_package_recieved()) {
break;
}
}
Unfortunately there is no Content-Length header in the response. My question is, how the function
http_package_recieved()
... should look like.
Greets Thorsten
feof($sock)
would be OKYou can check if $line is empty to see if the server isn't sending anything. You can also set a small read timeout on the socket with
stream_set_timeout()
, and then inside the loop checkstream_get_meta_data()
to see if it has been reached in order to break out.When the entity ends is either guided by:
Content-Length
header (which you don't have)Transfer-Encoding: chunked
header: do you have one of these?).It's possible you may have to process this chunked transfer encoding if you get this header. There are libraries to do so.
You'd be better of using a library, such as cURL (http://uk.php.net/manual/en/intro.curl.php), to handle this. The HTTP spec isn't simple: http://tools.ietf.org/html/rfc2616 (see Section 4.4) and you'd likely miss something crucial.
If it doesn't close the connection and it doesn't tell you the total length of the response, you have no way to know whether all the data has been received.
You could specify a maximum time interval between packets, but that won't be reliable.