tags:

views:

43

answers:

5

I have the following problem:

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

+1  A: 

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.

Rushyo
A: 

feof($sock) would be OK

baton
+1  A: 

When the entity ends is either guided by:

It's possible you may have to process this chunked transfer encoding if you get this header. There are libraries to do so.

Bruno
Transfer-Encoding: chunked, I *have*. I'll read about this. thanks.
thorsten
I'd strongly recommend using a library to do so, unless you have a good reason not to. libcurl is available via PHP (as @Rushyo said).
Bruno
A: 

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.

Artefacto
You can, if it's using HTTP Chunked Transfer Encoding.
Bruno
@Bruno That's true. It remains to be seen if that's the case (the OP doesn't specify it).
Artefacto
@Bruno: That's a big *if*. However, unless the server specifies this or Content-length and doesn't close the connection, there's indeed no way to tell (shouldn't happen, but apparently can).
Piskvor
I'll read about Transfer-Encoding: chunked and tell my success (or not ;) )
thorsten
+1  A: 

You 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 check stream_get_meta_data() to see if it has been reached in order to break out.

Fanis