Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Stream response from CURL request without waiting for it to finish

Tags:

php

curl

I have a PHP script on my server that is making a request to another server for an image.

The script is accessed just like a regular image source like this:

<img src="http://example.com/imagecontroller.php?id=1234" />

Browser -> Script -> External Server

The script is doing a CURL request to the external server.

Is it possible to "stream" the CURL response directly back to the client (browser) as it is received on the server?

Assume my script is on a slow shared hosting server and the external server is blazing fast (a CDN). Is there a way to serve the response directly back to the client without my script being a bottleneck? It would be great if my server didn't have to wait for the entire image to be loaded into memory before beginning the response to the client.

like image 647
andrhamm Avatar asked Dec 02 '11 20:12

andrhamm


3 Answers

Pass the -N/--no-buffer flag to curl. It does the following:

Disables the buffering of the output stream. In normal work situations, curl will use a standard buffered output stream that will have the effect that it will output the data in chunks, not necessarily exactly when the data arrives. Using this option will disable that buffering.

Note that this is the negated option name documented. You can thus use --buffer to enforce the buffering.

like image 191
ryeguy Avatar answered Nov 08 '22 07:11

ryeguy


Check out Pascal Martin's answer to an unrelated question, in which he discusses using CURLOPT_FILE for streaming curl responses. His explanation for handling " Manipulate a string that is 30 million characters long " should work in your case.

Hope this helps!

like image 1
Mike Fahy Avatar answered Nov 08 '22 07:11

Mike Fahy


Yes you can use the CURLOPT_WRITEFUNCTION flag:

curl_setopt($ch, CURLOPT_WRITEFUNCTION, $callback);

Where $ch is the Curl handler, and $callback is the callback function name. This command will stream response data from remote site. The callback function can look something like:

$result = '';
$callback = function ($ch, $str) {
    global $result;
    $result .= $str;//$str has the chunks of data streamed back. 
    //here you can mess with the stream data either with $result or $str
    return strlen($str);//don't touch this
};

If not interrupted at the end $result will contain all the response from remote site.

like image 1
Keinan Goichman Avatar answered Nov 08 '22 05:11

Keinan Goichman