Skip to content

Commit

Permalink
RFC: Add CurlSharePersistentHandle objects (#16937)
Browse files Browse the repository at this point in the history
  • Loading branch information
ericnorris authored Jan 6, 2025
1 parent 95d1476 commit d20880c
Show file tree
Hide file tree
Showing 16 changed files with 424 additions and 10 deletions.
1 change: 1 addition & 0 deletions NEWS
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ PHP NEWS

- Curl:
. Added curl_multi_get_handles(). (timwolla)
. Added curl_share_init_persistent(). (enorris)

- Date:
. Fix undefined behaviour problems regarding integer overflow in extreme edge
Expand Down
13 changes: 13 additions & 0 deletions UPGRADING
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,11 @@ PHP 8.5 UPGRADE NOTES
. Added support for Closures in constant expressions.
RFC: https://wiki.php.net/rfc/closures_in_const_expr

- Curl:
. Added support for share handles that are persisted across multiple PHP
requests, safely allowing for more effective connection reuse.
RFC: https://wiki.php.net/rfc/curl_share_persistence_improvement

- DOM:
. Added Dom\Element::$outerHTML.

Expand Down Expand Up @@ -148,6 +153,9 @@ PHP 8.5 UPGRADE NOTES
. curl_multi_get_handles() allows retrieving all CurlHandles current
attached to a CurlMultiHandle. This includes both handles added using
curl_multi_add_handle() and handles accepted by CURLMOPT_PUSHFUNCTION.
. curl_share_init_persistent() allows creating a share handle that is
persisted across multiple PHP requests.
RFC: https://wiki.php.net/rfc/curl_share_persistence_improvement

- DOM:
. Added Dom\Element::insertAdjacentHTML().
Expand All @@ -166,6 +174,11 @@ PHP 8.5 UPGRADE NOTES
7. New Classes and Interfaces
========================================

- Curl:
. CurlSharePersistentHandle representing a share handle that is persisted
across multiple PHP requests.
RFC: https://wiki.php.net/rfc/curl_share_persistence_improvement

========================================
8. Removed Extensions and SAPIs
========================================
Expand Down
1 change: 1 addition & 0 deletions Zend/Optimizer/zend_func_infos.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@ static const func_info_t func_infos[] = {
F1("curl_multi_strerror", MAY_BE_STRING|MAY_BE_NULL),
F1("curl_share_init", MAY_BE_OBJECT),
F1("curl_share_strerror", MAY_BE_STRING|MAY_BE_NULL),
F1("curl_share_init_persistent", MAY_BE_OBJECT),
F1("curl_strerror", MAY_BE_STRING|MAY_BE_NULL),
F1("curl_version", MAY_BE_ARRAY|MAY_BE_ARRAY_KEY_STRING|MAY_BE_ARRAY_OF_LONG|MAY_BE_ARRAY_OF_STRING|MAY_BE_ARRAY_OF_ARRAY|MAY_BE_FALSE),
F1("date", MAY_BE_STRING),
Expand Down
12 changes: 12 additions & 0 deletions ext/curl/curl.stub.php
Original file line number Diff line number Diff line change
Expand Up @@ -3668,6 +3668,15 @@ final class CurlShareHandle
{
}

/**
* @strict-properties
* @not-serializable
*/
final class CurlSharePersistentHandle
{
public readonly array $options;
}

function curl_close(CurlHandle $handle): void {}

/** @refcount 1 */
Expand Down Expand Up @@ -3750,6 +3759,9 @@ function curl_share_setopt(CurlShareHandle $share_handle, int $option, mixed $va
/** @refcount 1 */
function curl_share_strerror(int $error_code): ?string {}

/** @refcount 1 */
function curl_share_init_persistent(array $share_options): CurlSharePersistentHandle {}

/** @refcount 1 */
function curl_strerror(int $error_code): ?string {}

Expand Down
24 changes: 23 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.

13 changes: 13 additions & 0 deletions ext/curl/curl_private.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,20 @@
#define SAVE_CURL_ERROR(__handle, __err) \
do { (__handle)->err.no = (int) __err; } while (0)


ZEND_BEGIN_MODULE_GLOBALS(curl)
HashTable persistent_curlsh;
ZEND_END_MODULE_GLOBALS(curl)

ZEND_EXTERN_MODULE_GLOBALS(curl)

#define CURL_G(v) ZEND_MODULE_GLOBALS_ACCESSOR(curl, v)

PHP_MINIT_FUNCTION(curl);
PHP_MSHUTDOWN_FUNCTION(curl);
PHP_MINFO_FUNCTION(curl);
PHP_GINIT_FUNCTION(curl);
PHP_GSHUTDOWN_FUNCTION(curl);

typedef struct {
zend_fcall_info_cache fcc;
Expand Down Expand Up @@ -153,6 +164,8 @@ static inline php_curlsh *curl_share_from_obj(zend_object *obj) {

void curl_multi_register_handlers(void);
void curl_share_register_handlers(void);
void curl_share_persistent_register_handlers(void);
void curl_share_free_persistent_curlsh(zval *data);
void curlfile_register_class(void);
zend_result curl_cast_object(zend_object *obj, zval *result, int type);

Expand Down
48 changes: 39 additions & 9 deletions ext/curl/interface.c
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@

#include "curl_arginfo.h"

ZEND_DECLARE_MODULE_GLOBALS(curl)

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

Expand Down Expand Up @@ -215,18 +217,34 @@ zend_module_entry curl_module_entry = {
NULL,
PHP_MINFO(curl),
PHP_CURL_VERSION,
STANDARD_MODULE_PROPERTIES
PHP_MODULE_GLOBALS(curl),
PHP_GINIT(curl),
PHP_GSHUTDOWN(curl),
NULL,
STANDARD_MODULE_PROPERTIES_EX
};
/* }}} */

#ifdef COMPILE_DL_CURL
ZEND_GET_MODULE (curl)
#endif

PHP_GINIT_FUNCTION(curl)
{
zend_hash_init(&curl_globals->persistent_curlsh, 0, NULL, curl_share_free_persistent_curlsh, true);
GC_MAKE_PERSISTENT_LOCAL(&curl_globals->persistent_curlsh);
}

PHP_GSHUTDOWN_FUNCTION(curl)
{
zend_hash_destroy(&curl_globals->persistent_curlsh);
}

/* CurlHandle class */

zend_class_entry *curl_ce;
zend_class_entry *curl_share_ce;
zend_class_entry *curl_share_persistent_ce;
static zend_object_handlers curl_object_handlers;

static zend_object *curl_create_object(zend_class_entry *class_type);
Expand Down Expand Up @@ -410,6 +428,10 @@ PHP_MINIT_FUNCTION(curl)

curl_share_ce = register_class_CurlShareHandle();
curl_share_register_handlers();

curl_share_persistent_ce = register_class_CurlSharePersistentHandle();
curl_share_persistent_register_handlers();

curlfile_register_class();

return SUCCESS;
Expand Down Expand Up @@ -2281,16 +2303,24 @@ static zend_result _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue

case CURLOPT_SHARE:
{
if (Z_TYPE_P(zvalue) == IS_OBJECT && Z_OBJCE_P(zvalue) == curl_share_ce) {
php_curlsh *sh = Z_CURL_SHARE_P(zvalue);
curl_easy_setopt(ch->cp, CURLOPT_SHARE, sh->share);
if (Z_TYPE_P(zvalue) != IS_OBJECT) {
break;
}

if (ch->share) {
OBJ_RELEASE(&ch->share->std);
}
GC_ADDREF(&sh->std);
ch->share = sh;
if (Z_OBJCE_P(zvalue) != curl_share_ce && Z_OBJCE_P(zvalue) != curl_share_persistent_ce) {
break;
}

php_curlsh *sh = Z_CURL_SHARE_P(zvalue);

curl_easy_setopt(ch->cp, CURLOPT_SHARE, sh->share);

if (ch->share) {
OBJ_RELEASE(&ch->share->std);
}

GC_ADDREF(&sh->std);
ch->share = sh;
}
break;

Expand Down
1 change: 1 addition & 0 deletions ext/curl/php_curl.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ extern zend_module_entry curl_module_entry;

PHP_CURL_API extern zend_class_entry *curl_ce;
PHP_CURL_API extern zend_class_entry *curl_share_ce;
PHP_CURL_API extern zend_class_entry *curl_share_persistent_ce;
PHP_CURL_API extern zend_class_entry *curl_multi_ce;
PHP_CURL_API extern zend_class_entry *curl_CURLFile_class;
PHP_CURL_API extern zend_class_entry *curl_CURLStringFile_class;
Expand Down
Loading

0 comments on commit d20880c

Please sign in to comment.