Skip to content

HTTPS cURL request fails at 340th request when used in a recursive function #1757

Open
@tschoonen

Description

@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

/**
 * 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

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions