php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #43468 Curl doesn't handle php://memory stream
Submitted: 2007-12-01 10:00 UTC Modified: 2008-12-18 01:00 UTC
Votes:18
Avg. Score:4.2 ± 0.8
Reproduced:17 of 17 (100.0%)
Same Version:9 (52.9%)
Same OS:5 (29.4%)
From: peter at petersmit dot eu Assigned:
Status: No Feedback Package: cURL related
PHP Version: 5.2.6 OS: Ubuntu Linux Gutsy Gibbon
Private report: No CVE-ID: None
 [2007-12-01 10:00 UTC] peter at petersmit dot eu
Description:
------------
If you use a php://memory stream in combination with curl, nothing is written to the stream.

A filestream works fine.

Reproduce code:
---------------
<?php

$c = curl_init("http://example.com");
$st = fopen("php://memory", "r+");

curl_setopt($c, CURLOPT_FILE, $st);

if(!curl_exec($c)) die ("error: ".curl_error($c));

rewind($st);
echo "Content|".htmlspecialchars(stream_get_contents($st))."|/Content";
fclose($st);

?>

Expected result:
----------------
Content|The content of example.org|/Content

Actual result:
--------------
Content||/Content

Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2008-02-13 22:16 UTC] quickshiftin at gmail dot com
i have discovered that this does work, partially, for some urls.
im not sure what is preventing this from working on all urls, but even for ones where it does work, the entire result is not placed in the buffer.
here is a modification of peters code, which illustrates 2 urls that work partially, one is the google translate 'api', the other is php.net.

<?php
#$c = curl_init("http://example.com");
#$c = curl_init("http://google.com/translate_t?langpair=en%7Cfr&text=newspaper");
$c = curl_init("http://php.net");
$st = fopen('php://memory', 'r');

curl_setopt($c, CURLOPT_FILE, $st);
curl_setopt($c, CURLOPT_USERAGENT, 'Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.11) Gecko/20080115 Firefox/2.0.0.11');

if(!curl_exec($c)) die ("error: ".curl_error($c));
curl_close($c);


rewind($st);
/*
$str =  fgets($st);
var_dump($str);
*/
echo stream_get_contents($st);
#echo "Content|".htmlspecialchars(stream_get_contents($st))."|/Content";
fclose($st);
?>
 [2008-12-10 01:55 UTC] dan dot hitt at gmail dot com
I can reproduce the bug.

I downloaded the link provided on the bug by jani (php 5.2 snapshot).

I built php (and had to also download and build libcurl).

My exact configuration line for the php was:
./configure --prefix=/home/danh/staging/php/2008_09_12_c --with-curl=/home/danh/staging/curl/2008_09_12
where the funky directory name is where i installed the curl i built.  (For the curl i used no options in the configuration except where to install it.)

My system is ubuntu 7.10.

It would be terrific to fix the bug because curl is so useful and having arbitrary streams is so useful: at least streams to memory.

Thanks everybody for your efforts on refining php.
 [2008-12-10 07:09 UTC] peter at petersmit dot eu
Sorry, not confirmed

I was checking it whit my own website address in the example code and everything looked fine. However with example.org or google.com it's not working!
 [2008-12-11 00:06 UTC] jani@php.net
Please try using this CVS snapshot:

  http://snaps.php.net/php5.2-latest.tar.gz
 
For Windows:

  http://windows.php.net/snapshots/

And provide the full configure line you used if the snapshot does not 
work.
 [2008-12-11 02:41 UTC] dan dot hitt at gmail dot com
I built again, and tried Peter's test again, and it failed again.

But note that with either the build from today or yesterday it
gives partial results for the wikipedia (it looks like it loses
the last 497 characters).

My configuration command is:

./configure --prefix=/home/danh/staging/php/2008_12_11_a --with-curl=/home/danh/staging/curl/2008_09_12

dan
 [2008-12-18 01:00 UTC] php-bugs at lists dot php dot net
No feedback was provided for this bug for over a week, so it is
being suspended automatically. If you are able to provide the
information that was originally requested, please do so and change
the status of the bug back to "Open".
 [2009-01-29 00:06 UTC] davirtavares at gmail dot com
I got the same problem. I'm trying to submit data by PUT request and aparently memory streams don't work for just a single CURL option:

curl_setopt($ch, CURLOPT_INFILESIZE, $input_size);

Aparently some servers don't like when you submit data w/o the content-size.

But... how to obtain the size of a memory stream?

Davi
 [2009-01-29 02:14 UTC] davirtavares at gmail dot com
Well, I just discovered that I can use fstat to get the size of a stream (even memory ones).

Follows the test case:

$fi = fopen('php://temp', 'rb+');

// fill the $fi stream with some data

$input_stat = fstat($fi);
$input_size = $input_stat['size'];

curl_setopt($ch, CURLOPT_PUT, true);
curl_setopt($ch, CURLOPT_INFILE, $fi);
curl_setopt($ch, CURLOPT_INFILESIZE, $input_size);

curl_exec($ch);

Davi
 [2009-02-11 02:13 UTC] davirtavares at gmail dot com
The final workaround I currently use is setting both CURLOPT_WRITEFUNCTION and CURLOPT_READFUNCTION options. So I can write and read using the memory stream, even being unsupported by CURL:

// open the memory stream (currently using "temp" but it should works with "memory" stream as well):
$temp = fopen('php://temp', 'rb+');

function cb_curl_write($ch, $data) {
	global $temp;

	return fwrite($temp, $data);
}

function cb_curl_read($ch, $fd, $size) {
	global $temp;

	return fread($temp, $size);
}

// put some data into the stream:
// TODO

rewind($temp);

// get the content size of the stream
$input_stat = fstat($temp);
$input_size = $input_stat['size'];

$ch = curl_init('http://www.php.net/');

curl_setopt($ch, CURLOPT_PUT, true);
curl_setopt($ch, CURLOPT_INFILESIZE, $input_size);
curl_setopt($ch, CURLOPT_WRITEFUNCTION, 'cb_curl_write');
curl_setopt($ch, CURLOPT_READFUNCTION, 'cb_curl_read');

curl_exec($ch);
curl_close($ch);
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Thu Dec 12 01:01:28 2024 UTC