[php-src] Issue #9369: HTTPS cURL request fails at 340th request when used in a recursive function
| From: | tschoonen | Date: | Thu, 18 Aug 2022 14:11:12 +0000 |
| Subject: | [php-src] Issue #9369: HTTPS cURL request fails at 340th request when used in a recursive function | ||
| Groups: | php.bugs | ||
| Request: | Send a blank email to php-bugs+get-242245@lists.php.net to get a copy of this message | ||
Issue: https://github.com/php/php-src/issues/9369
Author: tschoonen
### 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
<?php
/**
* This will end at request #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 #1...
Request no #2...
Request no #3...
[...]
Request no #338...
Request no #339...
Request no #340...
Request returned false
```
But I expected this output instead:
```
Request no #1...
Request no #2...
Request no #3...
[...]
Request no #398...
Request no #399...
Request no #400...
Done!
```
This code will run just fine:
```php
<?php
/**
* This will comfortably come to request #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