Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get file contents when Connection is keep-alive

Tags:

php

I need to get the contents of a remote file, but with sending a few headers, and one of them is the "Connection: keep-alive" header... so I tried it with a simple call to file_get_contents(), like this:

<?php

$sfheaders="Cache-Control:max-age=0
Connection:keep-alive";

$opts = array(
    'http' => array(
        'method' => "GET",
        'header' => $sfheaders
    )
);

$context = stream_context_create($opts);

$url="http://somedomain.com/to.php";
$file = file_get_contents($url, false, $context);
?>

... the code works, but it takes 15 seconds for file_get_contents to get the data! It looks like file_get_contents() finishes after the connection closes, but I want it to finish after the data is transferred. It is faster if I remove the keep-alive header but this time I need to get the data while the connection is kept alive. I guess that is not possible with file_get_contents, so ....

is there a way to do it with cURL or with something else?

Edit: Let me be more accurate, the "Connection:keep-alive" header must be send to the specific server I am trying to access because it checks for that header, and if it is not send, then there is no data send to me! Got it?

like image 477
Edis Golubich Avatar asked Aug 12 '13 12:08

Edis Golubich


Video Answer


1 Answers

Keep-alive connections

Normally, if a connection isn't set as keep-alive, once PHP terminates the current script, the remaining output buffer gets forwarded to the web-server, which in turn forwards the data to the client. Then the web-server closes its connection to the client (browser).

If you request

Connection: keep-alive

the server does just this: It keeps the connection open, even if a reply has completely finished. Thus, the mentioned behavior is just fine. Furthermore, e.g. feof() won't return FALSE - since more data might arrive eventually.

Note, that you can re-use the keep-alive connection within your currently running PHP script. But once your PHP script finishes, the keep-alive connection will be disconnected.

Thus, you can't reuse the keep-alive connection using your next PHP script instance.

Case 1 - Amount of data known before request

If you know the amount of data beforehand, you might read just that amount of data $expectedAmountOfDataInBytes and then close the connection:

$expectedAmountOfDataInBytes = 2023;

$handle = fopen( "http://www.stackoverflow.com/", "r" );

if ( ! is_resource( $handle )) {
    echo 'sorry';
    exit;
}

while(  ( ! feof( $handle ) )
     && ( 0 < $expectedAmountOfDataInBytes-- )
     ) {

    $contents .= fread( $handle, 1 );

}

fclose($handle);

Case 2 - Amount of data unknown before request

In case you don't know the amount of data beforehand, you need to submit a HTTP request

GET /infotext.html HTTP/1.1
Host: www.example.net

and parse an answer like so:

HTTP/1.1 200 OK
Server: Apache/1.3.29 (Unix) PHP/4.3.4
Content-Length: 4 
Content-Language: de (nach RFC 3282 sowie RFC 1766)
Connection: close
Content-Type: text/html

ABCD

Find in the PHP Manuals a simple HTTP client based on sockets I/O.

like image 149
SteAp Avatar answered Sep 28 '22 22:09

SteAp