Skip to content

Commit d20880c

Browse files
authored
RFC: Add CurlSharePersistentHandle objects (#16937)
see https://wiki.php.net/rfc/curl_share_persistence_improvement
1 parent 95d1476 commit d20880c

16 files changed

+424
-10
lines changed

NEWS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ PHP NEWS
1919

2020
- Curl:
2121
. Added curl_multi_get_handles(). (timwolla)
22+
. Added curl_share_init_persistent(). (enorris)
2223

2324
- Date:
2425
. Fix undefined behaviour problems regarding integer overflow in extreme edge

UPGRADING

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,11 @@ PHP 8.5 UPGRADE NOTES
6868
. Added support for Closures in constant expressions.
6969
RFC: https://wiki.php.net/rfc/closures_in_const_expr
7070

71+
- Curl:
72+
. Added support for share handles that are persisted across multiple PHP
73+
requests, safely allowing for more effective connection reuse.
74+
RFC: https://wiki.php.net/rfc/curl_share_persistence_improvement
75+
7176
- DOM:
7277
. Added Dom\Element::$outerHTML.
7378

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

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

177+
- Curl:
178+
. CurlSharePersistentHandle representing a share handle that is persisted
179+
across multiple PHP requests.
180+
RFC: https://wiki.php.net/rfc/curl_share_persistence_improvement
181+
169182
========================================
170183
8. Removed Extensions and SAPIs
171184
========================================

Zend/Optimizer/zend_func_infos.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ static const func_info_t func_infos[] = {
4646
F1("curl_multi_strerror", MAY_BE_STRING|MAY_BE_NULL),
4747
F1("curl_share_init", MAY_BE_OBJECT),
4848
F1("curl_share_strerror", MAY_BE_STRING|MAY_BE_NULL),
49+
F1("curl_share_init_persistent", MAY_BE_OBJECT),
4950
F1("curl_strerror", MAY_BE_STRING|MAY_BE_NULL),
5051
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),
5152
F1("date", MAY_BE_STRING),

ext/curl/curl.stub.php

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3668,6 +3668,15 @@ final class CurlShareHandle
36683668
{
36693669
}
36703670

3671+
/**
3672+
* @strict-properties
3673+
* @not-serializable
3674+
*/
3675+
final class CurlSharePersistentHandle
3676+
{
3677+
public readonly array $options;
3678+
}
3679+
36713680
function curl_close(CurlHandle $handle): void {}
36723681

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

3762+
/** @refcount 1 */
3763+
function curl_share_init_persistent(array $share_options): CurlSharePersistentHandle {}
3764+
37533765
/** @refcount 1 */
37543766
function curl_strerror(int $error_code): ?string {}
37553767

ext/curl/curl_arginfo.h

Lines changed: 23 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ext/curl/curl_private.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,20 @@
4040
#define SAVE_CURL_ERROR(__handle, __err) \
4141
do { (__handle)->err.no = (int) __err; } while (0)
4242

43+
44+
ZEND_BEGIN_MODULE_GLOBALS(curl)
45+
HashTable persistent_curlsh;
46+
ZEND_END_MODULE_GLOBALS(curl)
47+
48+
ZEND_EXTERN_MODULE_GLOBALS(curl)
49+
50+
#define CURL_G(v) ZEND_MODULE_GLOBALS_ACCESSOR(curl, v)
51+
4352
PHP_MINIT_FUNCTION(curl);
4453
PHP_MSHUTDOWN_FUNCTION(curl);
4554
PHP_MINFO_FUNCTION(curl);
55+
PHP_GINIT_FUNCTION(curl);
56+
PHP_GSHUTDOWN_FUNCTION(curl);
4657

4758
typedef struct {
4859
zend_fcall_info_cache fcc;
@@ -153,6 +164,8 @@ static inline php_curlsh *curl_share_from_obj(zend_object *obj) {
153164

154165
void curl_multi_register_handlers(void);
155166
void curl_share_register_handlers(void);
167+
void curl_share_persistent_register_handlers(void);
168+
void curl_share_free_persistent_curlsh(zval *data);
156169
void curlfile_register_class(void);
157170
zend_result curl_cast_object(zend_object *obj, zval *result, int type);
158171

ext/curl/interface.c

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,8 @@
6767

6868
#include "curl_arginfo.h"
6969

70+
ZEND_DECLARE_MODULE_GLOBALS(curl)
71+
7072
#ifdef PHP_CURL_NEED_OPENSSL_TSL /* {{{ */
7173
static MUTEX_T *php_curl_openssl_tsl = NULL;
7274

@@ -215,18 +217,34 @@ zend_module_entry curl_module_entry = {
215217
NULL,
216218
PHP_MINFO(curl),
217219
PHP_CURL_VERSION,
218-
STANDARD_MODULE_PROPERTIES
220+
PHP_MODULE_GLOBALS(curl),
221+
PHP_GINIT(curl),
222+
PHP_GSHUTDOWN(curl),
223+
NULL,
224+
STANDARD_MODULE_PROPERTIES_EX
219225
};
220226
/* }}} */
221227

222228
#ifdef COMPILE_DL_CURL
223229
ZEND_GET_MODULE (curl)
224230
#endif
225231

232+
PHP_GINIT_FUNCTION(curl)
233+
{
234+
zend_hash_init(&curl_globals->persistent_curlsh, 0, NULL, curl_share_free_persistent_curlsh, true);
235+
GC_MAKE_PERSISTENT_LOCAL(&curl_globals->persistent_curlsh);
236+
}
237+
238+
PHP_GSHUTDOWN_FUNCTION(curl)
239+
{
240+
zend_hash_destroy(&curl_globals->persistent_curlsh);
241+
}
242+
226243
/* CurlHandle class */
227244

228245
zend_class_entry *curl_ce;
229246
zend_class_entry *curl_share_ce;
247+
zend_class_entry *curl_share_persistent_ce;
230248
static zend_object_handlers curl_object_handlers;
231249

232250
static zend_object *curl_create_object(zend_class_entry *class_type);
@@ -410,6 +428,10 @@ PHP_MINIT_FUNCTION(curl)
410428

411429
curl_share_ce = register_class_CurlShareHandle();
412430
curl_share_register_handlers();
431+
432+
curl_share_persistent_ce = register_class_CurlSharePersistentHandle();
433+
curl_share_persistent_register_handlers();
434+
413435
curlfile_register_class();
414436

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

22822304
case CURLOPT_SHARE:
22832305
{
2284-
if (Z_TYPE_P(zvalue) == IS_OBJECT && Z_OBJCE_P(zvalue) == curl_share_ce) {
2285-
php_curlsh *sh = Z_CURL_SHARE_P(zvalue);
2286-
curl_easy_setopt(ch->cp, CURLOPT_SHARE, sh->share);
2306+
if (Z_TYPE_P(zvalue) != IS_OBJECT) {
2307+
break;
2308+
}
22872309

2288-
if (ch->share) {
2289-
OBJ_RELEASE(&ch->share->std);
2290-
}
2291-
GC_ADDREF(&sh->std);
2292-
ch->share = sh;
2310+
if (Z_OBJCE_P(zvalue) != curl_share_ce && Z_OBJCE_P(zvalue) != curl_share_persistent_ce) {
2311+
break;
22932312
}
2313+
2314+
php_curlsh *sh = Z_CURL_SHARE_P(zvalue);
2315+
2316+
curl_easy_setopt(ch->cp, CURLOPT_SHARE, sh->share);
2317+
2318+
if (ch->share) {
2319+
OBJ_RELEASE(&ch->share->std);
2320+
}
2321+
2322+
GC_ADDREF(&sh->std);
2323+
ch->share = sh;
22942324
}
22952325
break;
22962326

ext/curl/php_curl.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,7 @@ extern zend_module_entry curl_module_entry;
3737

3838
PHP_CURL_API extern zend_class_entry *curl_ce;
3939
PHP_CURL_API extern zend_class_entry *curl_share_ce;
40+
PHP_CURL_API extern zend_class_entry *curl_share_persistent_ce;
4041
PHP_CURL_API extern zend_class_entry *curl_multi_ce;
4142
PHP_CURL_API extern zend_class_entry *curl_CURLFile_class;
4243
PHP_CURL_API extern zend_class_entry *curl_CURLStringFile_class;

0 commit comments

Comments
 (0)