Open
Description
Description
Recently a consumer of an API I had made ran into some strange issues, upon inspection of his code I discovered that the problem was because he used cURL in a recursive function, once put in a regular loop the problems disappeared.
Further inspection revealed this only seemed to occur with HTTPS requests, not plain HTTP. The server that the requests are made to does not make a difference as I've tested several differen hosts.
The included code uses the default snakeoil Apache configuration, the extra cert opts do not affect the outcome if left out on a properly configured server with TLS.
The following code:
<?php
/**
* This will end at request php/php-src#340
*/
function recursiveFunctionTest($request_no = 1)
{
echo "Request no #$request_no...\n";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://localhost/');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_CAINFO, '/etc/ssl/certs/ssl-cert-snakeoil.pem');
$response = curl_exec($ch);
curl_close($ch);
if ($response === false) {
echo 'Request returned false', PHP_EOL;
exit(1);
}
if ($request_no < 400) {
recursiveFunctionTest(++$request_no);
}
echo "Done!\n";
}
recursiveFunctionTest();
Resulted in this output:
Request no php/php-src#1...
Request no php/php-src#2...
Request no php/php-src#3...
[...]
Request no php/php-src#338...
Request no php/php-src#339...
Request no php/php-src#340...
Request returned false
But I expected this output instead:
Request no php/php-src#1...
Request no php/php-src#2...
Request no php/php-src#3...
[...]
Request no php/php-src#398...
Request no php/php-src#399...
Request no php/php-src#400...
Done!
This code will run just fine:
<?php
/**
* This will comfortably come to request php/php-src#400
*/
function whileLoopTest()
{
$request_no = 0;
do {
$request_no++;
echo "Request no #$request_no...\n";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://localhost/');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_CAINFO, '/etc/ssl/certs/ssl-cert-snakeoil.pem');
$response = curl_exec($ch);
curl_close($ch);
if ($response === false) {
echo 'Request returned false', PHP_EOL;
exit(1);
}
} while($request_no < 400);
echo "Done!\n";
}
whileLoopTest();
PHP Version
8.1.8
Operating System
Ubuntu 22.04 LTS