Skip to content

Commit 8596760

Browse files
committed
refactor: use curl_share_init signature per RFC
1 parent 4a19a98 commit 8596760

File tree

5 files changed

+85
-67
lines changed

5 files changed

+85
-67
lines changed

ext/curl/curl.stub.php

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3743,10 +3743,7 @@ function curl_share_close(CurlShareHandle $share_handle): void {}
37433743
function curl_share_errno(CurlShareHandle $share_handle): int {}
37443744

37453745
/** @refcount 1 */
3746-
function curl_share_init(): CurlShareHandle {}
3747-
3748-
/** @refcount 1 */
3749-
function curl_share_init_persistent(string $persistent_id, array $shares): CurlShareHandle|false {}
3746+
function curl_share_init(array $share_options = [], ?string $persistent_id = null): CurlShareHandle {}
37503747

37513748
function curl_share_setopt(CurlShareHandle $share_handle, int $option, mixed $value): bool {}
37523749

ext/curl/curl_arginfo.h

Lines changed: 3 additions & 8 deletions
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: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -135,8 +135,8 @@ typedef struct {
135135
} php_curlm;
136136

137137
typedef struct _php_curlsh {
138-
CURLSH *share;
139-
zend_bool persistent;
138+
CURLSH *share;
139+
zend_string *persistent_id;
140140

141141
struct {
142142
int no;

ext/curl/interface.c

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -217,10 +217,10 @@ zend_module_entry curl_module_entry = {
217217
NULL,
218218
PHP_MINFO(curl),
219219
PHP_CURL_VERSION,
220-
PHP_MODULE_GLOBALS(curl),
221-
PHP_GINIT(curl),
220+
PHP_MODULE_GLOBALS(curl),
221+
PHP_GINIT(curl),
222222
PHP_GSHUTDOWN(curl),
223-
NULL,
223+
NULL,
224224
STANDARD_MODULE_PROPERTIES_EX
225225
};
226226
/* }}} */
@@ -422,13 +422,11 @@ PHP_MINIT_FUNCTION(curl)
422422
}
423423
/* }}} */
424424

425-
/* {{{ PHP_GINIT_FUNCTION */
426425
PHP_GINIT_FUNCTION(curl)
427426
{
428427
zend_hash_init(&curl_globals->persistent_share_handles, 0, NULL, curl_share_free_persistent, true);
429428
GC_MAKE_PERSISTENT_LOCAL(&curl_globals->persistent_share_handles);
430429
}
431-
/* }}} */
432430

433431
PHP_GSHUTDOWN_FUNCTION(curl)
434432
{
@@ -747,8 +745,8 @@ static int curl_prereqfunction(void *clientp, char *conn_primary_ip, char *conn_
747745
// gets called. Return CURL_PREREQFUNC_OK immediately in this case to avoid
748746
// zend_call_known_fcc() with an uninitialized FCC.
749747
if (!ZEND_FCC_INITIALIZED(ch->handlers.prereq)) {
750-
return rval;
751-
}
748+
return rval;
749+
}
752750

753751
#if PHP_CURL_DEBUG
754752
fprintf(stderr, "curl_prereqfunction() called\n");

ext/curl/share.c

Lines changed: 74 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,17 @@
2121
#endif
2222

2323
#include "php.h"
24+
#include "Zend/zend_exceptions.h"
2425

2526
#include "curl_private.h"
2627

2728
#include <curl/curl.h>
2829

2930
#define SAVE_CURLSH_ERROR(__handle, __err) (__handle)->err.no = (int) __err;
3031

32+
/**
33+
* Free a persistent curl share handle.
34+
*/
3135
void curl_share_free_persistent(zval *data)
3236
{
3337
CURLSH *handle = Z_PTR_P(data);
@@ -39,84 +43,104 @@ void curl_share_free_persistent(zval *data)
3943
curl_share_cleanup(handle);
4044
}
4145

42-
/* {{{ Initialize a persistent curl share handle */
43-
PHP_FUNCTION(curl_share_init_persistent)
46+
/**
47+
* Initialize a share curl handle, optionally with share options and a persistent ID.
48+
*/
49+
PHP_FUNCTION(curl_share_init)
4450
{
45-
zend_string *id;
46-
47-
zval *persisted;
51+
zval *share_opts = NULL, *entry;
52+
zend_string *persistent_id;
4853

4954
php_curlsh *sh;
5055

51-
zval *arr, *entry;
5256
CURLSHcode error;
5357

54-
ZEND_PARSE_PARAMETERS_START(2, 2)
55-
Z_PARAM_STR_EX(id, 1, 0)
56-
Z_PARAM_ARRAY(arr)
58+
ZEND_PARSE_PARAMETERS_START(0, 2)
59+
Z_PARAM_OPTIONAL
60+
Z_PARAM_ARRAY(share_opts)
61+
Z_PARAM_STR_OR_NULL(persistent_id)
5762
ZEND_PARSE_PARAMETERS_END();
5863

5964
object_init_ex(return_value, curl_share_ce);
6065
sh = Z_CURL_SHARE_P(return_value);
6166

62-
if ((persisted = zend_hash_find(&CURL_G(persistent_share_handles), id)) != NULL) {
63-
sh->share = Z_PTR_P(persisted);
64-
sh->persistent = 1;
65-
} else {
66-
sh->share = curl_share_init();
67+
if (persistent_id) {
68+
zval *persisted = zend_hash_find(&CURL_G(persistent_share_handles), persistent_id);
69+
70+
if (persisted) {
71+
sh->share = Z_PTR_P(persisted);
72+
sh->persistent_id = zend_string_copy(persistent_id);
73+
74+
return;
75+
}
76+
}
77+
78+
// The user did not provide a persistent share ID, or we could not find an existing share handle, so we'll have to
79+
// create one.
80+
sh->share = curl_share_init();
6781

68-
ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(arr), entry) {
82+
if (share_opts) {
83+
ZEND_HASH_FOREACH_VAL(Z_ARRVAL_P(share_opts), entry) {
6984
ZVAL_DEREF(entry);
7085

71-
error = curl_share_setopt(sh->share, CURLSHOPT_SHARE, zval_get_long(entry));
86+
error = curl_share_setopt(sh->share, CURLSHOPT_SHARE, zval_get_long_ex(entry, true));
7287

7388
if (error != CURLSHE_OK) {
74-
php_error_docref(NULL, E_WARNING, "could not construct persistent curl share: %s", curl_share_strerror(error));
89+
zend_throw_exception_ex(
90+
NULL,
91+
0,
92+
"Could not construct cURL share handle: %s",
93+
curl_share_strerror(error)
94+
);
7595

7696
goto error;
7797
}
7898
} ZEND_HASH_FOREACH_END();
99+
}
79100

101+
if (persistent_id) {
80102
// It's important not to mark this as persistent until *after* we've successfully set all of the share options,
81103
// as otherwise the curl_share_free_obj in the error handler won't free the CURLSH.
82-
sh->persistent = 1;
83-
84-
zend_hash_str_add_new_ptr(&CURL_G(persistent_share_handles), ZSTR_VAL(id), ZSTR_LEN(id), sh->share);
104+
sh->persistent_id = zend_string_copy(persistent_id);
105+
106+
// We use the zend_hash_str form here, since we want to ensure it allocates a new persistent string, instead of
107+
// using the request-bound persistent_id.
108+
zend_hash_str_add_new_ptr(
109+
&CURL_G(persistent_share_handles),
110+
ZSTR_VAL(persistent_id),
111+
ZSTR_LEN(persistent_id),
112+
sh->share
113+
);
85114
}
86115

87116
return;
88117

89118
error:
90119
zval_ptr_dtor(return_value);
91120

92-
RETURN_FALSE;
121+
RETURN_THROWS();
93122
}
94-
/* }}} */
95-
96-
/* {{{ Initialize a share curl handle */
97-
PHP_FUNCTION(curl_share_init)
98-
{
99-
php_curlsh *sh;
100-
101-
ZEND_PARSE_PARAMETERS_NONE();
102123

103-
object_init_ex(return_value, curl_share_ce);
104-
sh = Z_CURL_SHARE_P(return_value);
105-
106-
sh->share = curl_share_init();
107-
}
108-
/* }}} */
109-
110-
/* {{{ Close a set of cURL handles */
124+
/**
125+
* Close a persistent curl share handle. NOP for non-persistent share handles.
126+
*/
111127
PHP_FUNCTION(curl_share_close)
112128
{
113129
zval *z_sh;
114130

131+
php_curlsh *sh;
132+
115133
ZEND_PARSE_PARAMETERS_START(1,1)
116134
Z_PARAM_OBJECT_OF_CLASS(z_sh, curl_share_ce)
117135
ZEND_PARSE_PARAMETERS_END();
136+
137+
sh = Z_CURL_SHARE_P(z_sh);
138+
139+
if (sh->persistent_id) {
140+
// Deleting the share from the hash table will trigger curl_share_free_persistent, so no need to call it here.
141+
zend_hash_del(&CURL_G(persistent_share_handles), sh->persistent_id);
142+
}
118143
}
119-
/* }}} */
120144

121145
static bool _php_curl_share_setopt(php_curlsh *sh, zend_long option, zval *zvalue, zval *return_value) /* {{{ */
122146
{
@@ -138,9 +162,10 @@ static bool _php_curl_share_setopt(php_curlsh *sh, zend_long option, zval *zvalu
138162

139163
return error == CURLSHE_OK;
140164
}
141-
/* }}} */
142165

143-
/* {{{ Set an option for a cURL transfer */
166+
/**
167+
* Set an option for a cURL transfer.
168+
*/
144169
PHP_FUNCTION(curl_share_setopt)
145170
{
146171
zval *z_sh, *zvalue;
@@ -161,9 +186,10 @@ PHP_FUNCTION(curl_share_setopt)
161186
RETURN_FALSE;
162187
}
163188
}
164-
/* }}} */
165189

166-
/* {{{ Return an integer containing the last share curl error number */
190+
/**
191+
* Return an integer containing the last share curl error number.
192+
*/
167193
PHP_FUNCTION(curl_share_errno)
168194
{
169195
zval *z_sh;
@@ -177,10 +203,11 @@ PHP_FUNCTION(curl_share_errno)
177203

178204
RETURN_LONG(sh->err.no);
179205
}
180-
/* }}} */
181206

182207

183-
/* {{{ return string describing error code */
208+
/**
209+
* Return a string describing the error code.
210+
*/
184211
PHP_FUNCTION(curl_share_strerror)
185212
{
186213
zend_long code;
@@ -197,7 +224,6 @@ PHP_FUNCTION(curl_share_strerror)
197224
RETURN_NULL();
198225
}
199226
}
200-
/* }}} */
201227

202228
/* CurlShareHandle class */
203229

@@ -219,8 +245,10 @@ void curl_share_free_obj(zend_object *object)
219245
{
220246
php_curlsh *sh = curl_share_from_obj(object);
221247

222-
if (!sh->persistent) {
248+
if (!sh->persistent_id) {
223249
curl_share_cleanup(sh->share);
250+
} else {
251+
zend_string_release(sh->persistent_id);
224252
}
225253

226254
zend_object_std_dtor(&sh->std);

0 commit comments

Comments
 (0)