Bug #68743 [Com]: Infinite loop when CURLOPT_INFILESIZE doesn't match sended data
| From: | nacridan at gmail dot com | Date: | Sun, 11 Jan 2015 01:08:26 +0000 |
| Subject: | Bug #68743 [Com]: Infinite loop when CURLOPT_INFILESIZE doesn't match sended data | ||
| References: | 1 | Groups: | php.bugs |
| Request: | Send a blank email to php-bugs+get-189877@lists.php.net to get a copy of this message | ||
Edit report at https://bugs.php.net/bug.php?id=68743&edit=1
ID: 68743
Comment by: nacridan at gmail dot com
Reported by: sjaillet at gmail dot com
Summary: Infinite loop when CURLOPT_INFILESIZE doesn't match
sended data
Status: Not a bug
Type: Bug
Package: cURL related
Operating System: Ubuntu 14.04.1
PHP Version: 5.6.4
Block user comment: N
Private report: N
New Comment:
The documentation of CURLOPT_READFUNCTION is pretty explicit: "It should return an empty string
to signal EOF." which is the case here.
So if the data returned by READFUNCTION has the wrong length, it should generate an error, not an
infinite loop so please reconsider the status of this ticket.
Previous Comments:
------------------------------------------------------------------------
[2015-01-09 07:29:21] krakjoe@php.net
This is programmer error, you are forcing curl or your loop to execute indefinitely by providing the
wrong length.
cURL, and PHP, cannot possibly detect that you have programmed it wrong.
------------------------------------------------------------------------
[2015-01-04 18:43:40] sjaillet at gmail dot com
Just for information, using
curl_exec($handle) directly instead of the multi loop has
the same behavior and the call hangs out indefinitely.
------------------------------------------------------------------------
[2015-01-04 14:25:16] sjaillet at gmail dot com
Description:
------------
cURL multi enter into an infinite loop when CURLOPT_INFILESIZE doesn't match the size of sended
data.
In the test script below I intentionally set the CURLOPT_INFILESIZE to the size of the sended data
plus 1 byte.
In the documentation we can see that CURLOPT_READFUNCTION should return an empty string to signal an
EOF.
So it's what I done in the following script.
So since CURLOPT_READFUNCTION returned the EOF signal which indicates that there's nothing to
wait for, I expected cURL to bail out and throwing an error (or at least timeout), but the test
script run into an infinite loop instead.
Test script:
---------------
$options = [
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_RETURNTRANSFER => false,
CURLOPT_HEADER => false,
CURLOPT_CUSTOMREQUEST => 'PUT',
CURLOPT_UPLOAD => true,
CURLOPT_URL => 'http://httpbin.org/put',
CURLOPT_CONNECTTIMEOUT => 1,
CURLOPT_HTTPHEADER => [
'Content-Type: text/plain; charset=UTF-8',
],
CURLOPT_READFUNCTION => function($handle, $fp, $length) {
static $data = 'HelloWorld';
$readed = $data;
$data = '';
echo "Length asked: '{$length}'\n";
echo "Readed: '{$readed}'\n";
return $readed;
},
CURLOPT_INFILESIZE => strlen('HelloWorld') + 1 // The extra byte
];
$handle = curl_init();
curl_setopt_array($handle, $options);
$mh = curl_multi_init();
curl_multi_add_handle($mh, $handle);
$running = 0;
do {
if (curl_multi_select($mh) === -1) {
usleep(1000);
}
curl_multi_exec($mh, $running);
echo "Number of running request(s): '{$running}'\n";
} while ($running > 0);
Expected result:
----------------
# of running request(s): '1'
# of running request(s): '1'
# of running request(s): '1'
# of running request(s): '1'
# of running request(s): '1'
# of running request(s): '1'
# of running request(s): '1'
Length asked: '16384'
Readed: 'HelloWorld'
# of running request(s): '1'
Length asked: '16384'
Readed: ''
# of running request(s): '1'
# of running request(s): '0'
And a call to curl_strerror() should be able to display the error.
Actual result:
--------------
# of running request(s): '1'
# of running request(s): '1'
# of running request(s): '1'
# of running request(s): '1'
# of running request(s): '1'
# of running request(s): '1'
# of running request(s): '1'
Length asked: '16384'
Readed: 'HelloWorld'
# of running request(s): '1'
Length asked: '16384'
Readed: ''
# of running request(s): '1'
# of running request(s): '1'
# of running request(s): '1'
# of running request(s): '1'
# of running request(s): '1'
# of running request(s): '1'
# of running request(s): '1'
# of running request(s): '1'
# of running request(s): '1'
# of running request(s): '1'
# of running request(s): '1'
# of running request(s): '1'
# of running request(s): '1'
... etc.
------------------------------------------------------------------------
--
Edit this bug report at https://bugs.php.net/bug.php?id=68743&edit=1