Add support for CURLINFO_CONN_ID in curl_getinfo() (#18984)

This patch adds support for the CURLINFO_CONN_ID constant in the curl_getinfo() function when compiled with libcurl >= 8.2.0.

CURLINFO_CONN_ID allows retrieving the unique identifier of the underlying connection used in the most recent transfer. This is useful for advanced features like connection reuse tracking, diagnostics, or connection pooling implementations at the PHP level.
This commit is contained in:
Emre Çalışkan 2025-07-16 12:08:19 +03:00 committed by GitHub
parent 2ecafd41ba
commit e84320ad75
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 168 additions and 1 deletions

View file

@ -188,6 +188,11 @@ PHP 8.5 UPGRADE NOTES
first redirect thus if there is any follow up redirect, it won't go
any further. CURLFOLLOW_ALL is equivalent to setting CURLOPT_FOLLOWLOCATION
to true.
. Added support for CURLINFO_CONN_ID (libcurl >= 8.2.0) to the curl_getinfo()
function. This constant allows retrieving the unique ID of the connection
used by a cURL transfer. It is primarily useful when connection reuse or
connection pooling logic is needed in PHP-level applications. When
curl_getinfo() returns an array, this value is available as the "conn_id" key.
- DOM:
. Added Dom\Element::$outerHTML.
@ -517,6 +522,7 @@ PHP 8.5 UPGRADE NOTES
. CURLINFO_USED_PROXY.
. CURLINFO_HTTPAUTH_USED.
. CURLINFO_PROXYAUTH_USED.
. CURLINFO_CONN_ID.
. CURLOPT_INFILESIZE_LARGE.
. CURLFOLLOW_ALL.
. CURLFOLLOW_OBEYCODE.

View file

@ -3103,6 +3103,13 @@ const CURLINFO_USED_PROXY = UNKNOWN;
*/
const CURLINFO_POSTTRANSFER_TIME_T = UNKNOWN;
#endif
#if LIBCURL_VERSION_NUM >= 0x080200 /* Available since 8.2.0 */
/**
* @var int
* @cvalue CURLINFO_CONN_ID
*/
const CURLINFO_CONN_ID = UNKNOWN;
#endif
/**
* @var int
* @cvalue CURLOPT_DISALLOW_USERNAME_IN_URL

View file

@ -1,5 +1,5 @@
/* This is a generated file, edit the .stub.php file instead.
* Stub hash: c087ac501d0abe14ed87968023d837f358e6fee8 */
* Stub hash: 533884c442ca1146a61c0824a4f8c9628c31aae3 */
ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_curl_close, 0, 1, IS_VOID, 0)
ZEND_ARG_OBJ_INFO(0, handle, CurlHandle, 0)
@ -824,6 +824,9 @@ static void register_curl_symbols(int module_number)
#endif
#if LIBCURL_VERSION_NUM >= 0x080a00 /* Available since 8.10.0 */
REGISTER_LONG_CONSTANT("CURLINFO_POSTTRANSFER_TIME_T", CURLINFO_POSTTRANSFER_TIME_T, CONST_PERSISTENT);
#endif
#if LIBCURL_VERSION_NUM >= 0x080200 /* Available since 8.2.0 */
REGISTER_LONG_CONSTANT("CURLINFO_CONN_ID", CURLINFO_CONN_ID, CONST_PERSISTENT);
#endif
REGISTER_LONG_CONSTANT("CURLOPT_DISALLOW_USERNAME_IN_URL", CURLOPT_DISALLOW_USERNAME_IN_URL, CONST_PERSISTENT);
REGISTER_LONG_CONSTANT("CURLOPT_PROXY_TLS13_CIPHERS", CURLOPT_PROXY_TLS13_CIPHERS, CONST_PERSISTENT);

View file

@ -2622,6 +2622,11 @@ PHP_FUNCTION(curl_getinfo)
if (curl_easy_getinfo(ch->cp, CURLINFO_PROXYAUTH_USED, &l_code) == CURLE_OK) {
CAAL("proxyauth_used", l_code);
}
#endif
#if LIBCURL_VERSION_NUM >= 0x080200 /* Available since 8.2.0 */
if (curl_easy_getinfo(ch->cp, CURLINFO_CONN_ID , &co) == CURLE_OK) {
CAAL("conn_id", co);
}
#endif
} else {
switch (option) {

View file

@ -0,0 +1,146 @@
--TEST--
Curlinfo CURLINFO_CONN_ID
--EXTENSIONS--
curl
--SKIPIF--
<?php
$curl_version = curl_version();
if ($curl_version['version_number'] < 0x080200) die("skip: test works only with curl >= 8.2.0");
?>
--FILE--
<?php
include 'server.inc';
$host = curl_cli_server_start();
$port = (int) (explode(':', $host))[1];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "{$host}/get.inc?test=get");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$info = curl_getinfo($ch);
var_dump(isset($info['conn_id']));
var_dump($info['conn_id'] === -1);
$result = curl_exec($ch);
$info = curl_getinfo($ch);
var_dump(isset($info['conn_id']));
var_dump(is_int($info['conn_id']));
var_dump(curl_getinfo($ch, CURLINFO_CONN_ID) === $info['conn_id']);
var_dump(curl_getinfo($ch, CURLINFO_CONN_ID) === 0);
curl_setopt($ch, CURLOPT_URL, "{$host}/get.inc?test=get");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($ch);
$info = curl_getinfo($ch);
var_dump(isset($info['conn_id']));
var_dump(is_int($info['conn_id']));
var_dump(curl_getinfo($ch, CURLINFO_CONN_ID) === $info['conn_id']);
var_dump(curl_getinfo($ch, CURLINFO_CONN_ID) === 1);
$ch1=curl_init();
$ch2=curl_init();
$cmh=curl_multi_init();
foreach([$ch1, $ch2] as $ch) {
curl_setopt($ch, CURLOPT_URL, "{$host}/get.inc?test=getpost&get_param=Curl%20Handle");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$info = curl_getinfo($ch);
var_dump(isset($info['conn_id']));
var_dump($info['conn_id'] === -1);
curl_multi_add_handle($cmh,$ch);
}
$running=0;
do {
curl_multi_exec($cmh,$running);
} while ($running>0);
foreach([$ch1, $ch2] as $key => $ch) {
$result = curl_multi_getcontent($ch);
$info = curl_getinfo($ch);
var_dump(isset($info['conn_id']));
var_dump(is_int($info['conn_id']));
var_dump(curl_getinfo($ch, CURLINFO_CONN_ID) === $info['conn_id']);
var_dump(curl_getinfo($ch, CURLINFO_CONN_ID) === $key);
}
$csh = curl_share_init();
curl_share_setopt($csh, CURLSHOPT_SHARE, CURL_LOCK_DATA_COOKIE);
curl_share_setopt($csh, CURLSHOPT_SHARE, CURL_LOCK_DATA_CONNECT);
curl_share_setopt($csh, CURLSHOPT_SHARE, CURL_LOCK_DATA_DNS);
curl_share_setopt($csh, CURLSHOPT_SHARE, CURL_LOCK_DATA_SSL_SESSION);
$ch1=curl_init();
$ch2=curl_init();
foreach([$ch1, $ch2] as $ch) {
curl_setopt($ch, CURLOPT_URL, "{$host}/get.inc?test=getpost&get_param=Curl%20Handle");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$info = curl_getinfo($ch);
var_dump(isset($info['conn_id']));
var_dump($info['conn_id'] === -1);
}
curl_setopt($ch1, CURLOPT_SHARE, $csh);
$result = curl_exec($ch1);
$info = curl_getinfo($ch1);
var_dump(isset($info['conn_id']));
var_dump(is_int($info['conn_id']));
var_dump(curl_getinfo($ch1, CURLINFO_CONN_ID) === $info['conn_id']);
var_dump(curl_getinfo($ch1, CURLINFO_CONN_ID) === 0);
curl_setopt($ch2, CURLOPT_SHARE, $csh);
$result = curl_exec($ch2);
$info = curl_getinfo($ch2);
var_dump(isset($info['conn_id']));
var_dump(is_int($info['conn_id']));
var_dump(curl_getinfo($ch2, CURLINFO_CONN_ID) === $info['conn_id']);
var_dump(curl_getinfo($ch2, CURLINFO_CONN_ID) === 1);
?>
--EXPECT--
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)
bool(true)