Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions UPGRADING
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down Expand Up @@ -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.
Expand Down
1 change: 0 additions & 1 deletion Zend/zend_llist.c
Original file line number Diff line number Diff line change
Expand Up @@ -121,7 +121,6 @@ ZEND_API void zend_llist_destroy(zend_llist *l)
ZEND_API void zend_llist_clean(zend_llist *l)
{
zend_llist_destroy(l);
l->head = l->tail = NULL;
}


Expand Down
30 changes: 12 additions & 18 deletions ext/curl/config.m4
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,8 @@ if test "$PHP_CURL" != "no"; then
AC_MSG_RESULT([$CURL_SSL])

AS_IF([test "x$PHP_THREAD_SAFETY" = xyes && test "x$CURL_SSL" = xyes],
[AC_CACHE_CHECK([whether libcurl is linked against old OpenSSL < 1.1],
[php_cv_lib_curl_ssl], [
[AC_CACHE_CHECK([whether libcurl is linked against a supported OpenSSL version],
[php_cv_lib_curl_ssl_supported], [
save_LIBS=$LIBS
save_CFLAGS=$CFLAGS
LIBS="$LIBS $CURL_SHARED_LIBADD"
Expand All @@ -34,17 +34,14 @@ if test "$PHP_CURL" != "no"; then

while(*ptr == ' ') ++ptr;
int major, minor;
if (sscanf(ptr, "OpenSSL/%d", &major) == 1) {
if (major >= 3) {
/* OpenSSL version 3 or later */
return 4;
}
}
if (sscanf(ptr, "OpenSSL/%d.%d", &major, &minor) == 2) {
if (major > 1 || (major == 1 && minor >= 1)) {
/* OpenSSL version 1.1 or later */
/* Check for 1.1.1+ (including 1.1.1a, 1.1.1b, etc.) */
if ((major > 1) || (major == 1 && minor == 1 && strncmp(ptr + 12, "1", 1) == 0)) {
/* OpenSSL 1.1.1+ - supported */
return 3;
}
/* OpenSSL 1.1.0 and earlier - unsupported */
return 0;
}
if (strncasecmp(ptr, "OpenSSL", sizeof("OpenSSL")-1) == 0) {
/* Old OpenSSL version */
Expand All @@ -56,18 +53,15 @@ if test "$PHP_CURL" != "no"; then
/* No SSL support */
return 1;
])],
[php_cv_lib_curl_ssl=yes],
[php_cv_lib_curl_ssl=no],
[php_cv_lib_curl_ssl=no])
[php_cv_lib_curl_ssl_supported=no],
[php_cv_lib_curl_ssl_supported=yes],
[php_cv_lib_curl_ssl_supported=yes])
LIBS=$save_LIBS
CFLAGS=$save_CFLAGS
])

AS_VAR_IF([php_cv_lib_curl_ssl], [yes], [
AC_DEFINE([HAVE_CURL_OLD_OPENSSL], [1],
[Define to 1 if libcurl is linked against old OpenSSL < 1.1.])
PHP_SETUP_OPENSSL([CURL_SHARED_LIBADD],
[AC_CHECK_HEADERS([openssl/crypto.h])])
AS_VAR_IF([php_cv_lib_curl_ssl_supported], [no], [
AC_MSG_ERROR([libcurl is linked against an unsupported OpenSSL version. OpenSSL 1.1.1 or later is required.])
])
])

Expand Down
7 changes: 7 additions & 0 deletions ext/curl/curl.stub.php
Original file line number Diff line number Diff line change
Expand Up @@ -3103,6 +3103,13 @@
*/
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
Expand Down
5 changes: 4 additions & 1 deletion ext/curl/curl_arginfo.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

73 changes: 5 additions & 68 deletions ext/curl/interface.c
Original file line number Diff line number Diff line change
Expand Up @@ -39,20 +39,6 @@
#define HttpPost curl_httppost
#endif

/* {{{ cruft for thread safe SSL crypto locks */
#if defined(ZTS) && defined(HAVE_CURL_OLD_OPENSSL)
# if defined(HAVE_OPENSSL_CRYPTO_H)
# define PHP_CURL_NEED_OPENSSL_TSL
# include <openssl/crypto.h>
# else
# warning \
"libcurl was compiled with OpenSSL support, but configure could not find " \
"openssl/crypto.h; thus no SSL crypto locking callbacks will be set, which may " \
"cause random crashes on SSL requests"
# endif
#endif /* ZTS && HAVE_CURL_OLD_OPENSSL */
/* }}} */

#include "zend_smart_str.h"
#include "ext/standard/info.h"
#include "ext/standard/file.h"
Expand All @@ -70,27 +56,6 @@

ZEND_DECLARE_MODULE_GLOBALS(curl)

#ifdef PHP_CURL_NEED_OPENSSL_TSL /* {{{ */
static MUTEX_T *php_curl_openssl_tsl = NULL;

/* Locking callbacks are no longer used since OpenSSL 1.1. Mark the functions as unused to
* avoid warnings due to this. */
static ZEND_ATTRIBUTE_UNUSED void php_curl_ssl_lock(int mode, int n, const char * file, int line)
{
if (mode & CRYPTO_LOCK) {
tsrm_mutex_lock(php_curl_openssl_tsl[n]);
} else {
tsrm_mutex_unlock(php_curl_openssl_tsl[n]);
}
}

static ZEND_ATTRIBUTE_UNUSED unsigned long php_curl_ssl_id(void)
{
return (unsigned long) tsrm_thread_id();
}
#endif
/* }}} */

#define CAAL(s, v) add_assoc_long_ex(return_value, s, sizeof(s) - 1, (zend_long) v);
#define CAAD(s, v) add_assoc_double_ex(return_value, s, sizeof(s) - 1, (double) v);
#define CAAS(s, v) add_assoc_string_ex(return_value, s, sizeof(s) - 1, (char *) (v ? v : ""));
Expand Down Expand Up @@ -389,24 +354,6 @@ PHP_MINIT_FUNCTION(curl)

register_curl_symbols(module_number);

#ifdef PHP_CURL_NEED_OPENSSL_TSL
if (!CRYPTO_get_id_callback()) {
int i, c = CRYPTO_num_locks();

php_curl_openssl_tsl = malloc(c * sizeof(MUTEX_T));
if (!php_curl_openssl_tsl) {
return FAILURE;
}

for (i = 0; i < c; ++i) {
php_curl_openssl_tsl[i] = tsrm_mutex_alloc();
}

CRYPTO_set_id_callback(php_curl_ssl_id);
CRYPTO_set_locking_callback(php_curl_ssl_lock);
}
#endif

if (curl_global_init(CURL_GLOBAL_DEFAULT) != CURLE_OK) {
return FAILURE;
}
Expand Down Expand Up @@ -568,21 +515,6 @@ zend_result curl_cast_object(zend_object *obj, zval *result, int type)
PHP_MSHUTDOWN_FUNCTION(curl)
{
curl_global_cleanup();
#ifdef PHP_CURL_NEED_OPENSSL_TSL
if (php_curl_openssl_tsl) {
int i, c = CRYPTO_num_locks();

CRYPTO_set_id_callback(NULL);
CRYPTO_set_locking_callback(NULL);

for (i = 0; i < c; ++i) {
tsrm_mutex_free(php_curl_openssl_tsl[i]);
}

free(php_curl_openssl_tsl);
php_curl_openssl_tsl = NULL;
}
#endif
UNREGISTER_INI_ENTRIES();
return SUCCESS;
}
Expand Down Expand Up @@ -2690,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) {
Expand Down
146 changes: 146 additions & 0 deletions ext/curl/tests/curl_getinfo_CURLINFO_CONN_ID.phpt
Original file line number Diff line number Diff line change
@@ -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)