Skip to content

Commit 69a9320

Browse files
committed
ext/curl: Convert handlers.server_push to just be a FCC
TODO Tests for multi handler
1 parent 4ba810f commit 69a9320

File tree

2 files changed

+25
-32
lines changed

2 files changed

+25
-32
lines changed

ext/curl/curl_private.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,7 @@ typedef struct {
114114
#define CURLOPT_SAFE_UPLOAD -1
115115

116116
typedef struct {
117-
php_curl_callback *server_push;
117+
zend_fcall_info_cache server_push;
118118
} php_curlm_handlers;
119119

120120
typedef struct {

ext/curl/multi.c

Lines changed: 24 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -372,51 +372,36 @@ static int _php_server_push_callback(CURL *parent_ch, CURL *easy, size_t num_hea
372372
php_curl *parent;
373373
php_curlm *mh = (php_curlm *)userp;
374374
size_t rval = CURL_PUSH_DENY;
375-
php_curl_callback *t = mh->handlers.server_push;
376375
zval *pz_parent_ch = NULL;
377376
zval pz_ch;
378377
zval headers;
379378
zval retval;
380-
char *header;
381-
zend_result error;
382-
zend_fcall_info fci = empty_fcall_info;
383379

384380
pz_parent_ch = _php_curl_multi_find_easy_handle(mh, parent_ch);
385381
if (pz_parent_ch == NULL) {
386382
return rval;
387383
}
388384

389-
if (UNEXPECTED(zend_fcall_info_init(&t->func_name, 0, &fci, &t->fci_cache, NULL, NULL) == FAILURE)) {
390-
php_error_docref(NULL, E_WARNING, "Cannot call the CURLMOPT_PUSHFUNCTION");
391-
return rval;
392-
}
393-
394385
parent = Z_CURL_P(pz_parent_ch);
395386

396387
ch = init_curl_handle_into_zval(&pz_ch);
397388
ch->cp = easy;
398389
_php_setup_easy_copy_handlers(ch, parent);
399390

400-
size_t i;
401391
array_init(&headers);
402-
for(i=0; i<num_headers; i++) {
392+
for (size_t i = 0; i < num_headers; i++) {
393+
char *header;
403394
header = curl_pushheader_bynum(push_headers, i);
404395
add_next_index_string(&headers, header);
405396
}
406397

407398
ZEND_ASSERT(pz_parent_ch);
408399
zval call_args[3] = {*pz_parent_ch, pz_ch, headers};
409400

410-
fci.param_count = 3;
411-
fci.params = call_args;
412-
fci.retval = &retval;
413-
414-
error = zend_call_function(&fci, &t->fci_cache);
401+
zend_call_known_fcc(&mh->handlers.server_push, &retval, /* param_count */ 3, call_args, /* named_params */ NULL);
415402
zval_ptr_dtor_nogc(&headers);
416403

417-
if (error == FAILURE) {
418-
php_error_docref(NULL, E_WARNING, "Cannot call the CURLMOPT_PUSHFUNCTION");
419-
} else if (!Z_ISUNDEF(retval)) {
404+
if (!Z_ISUNDEF(retval)) {
420405
if (CURL_PUSH_DENY != zval_get_long(&retval)) {
421406
rval = CURL_PUSH_OK;
422407
zend_llist_add_element(&mh->easyh, &pz_ch);
@@ -458,21 +443,29 @@ static bool _php_curl_multi_setopt(php_curlm *mh, zend_long option, zval *zvalue
458443
error = curl_multi_setopt(mh->multi, option, lval);
459444
break;
460445
}
461-
case CURLMOPT_PUSHFUNCTION:
462-
if (mh->handlers.server_push == NULL) {
463-
mh->handlers.server_push = ecalloc(1, sizeof(php_curl_callback));
464-
} else if (!Z_ISUNDEF(mh->handlers.server_push->func_name)) {
465-
zval_ptr_dtor(&mh->handlers.server_push->func_name);
466-
mh->handlers.server_push->fci_cache = empty_fcall_info_cache;
446+
case CURLMOPT_PUSHFUNCTION: {
447+
/* See php_curl_set_callable_handler */
448+
if (ZEND_FCC_INITIALIZED(mh->handlers.server_push)) {
449+
zend_fcc_dtor(&mh->handlers.server_push);
467450
}
468451

469-
ZVAL_COPY(&mh->handlers.server_push->func_name, zvalue);
452+
char *error_str = NULL;
453+
if (UNEXPECTED(!zend_is_callable_ex(zvalue, /* object */ NULL, /* check_flags */ 0, /* callable_name */ NULL, &mh->handlers.server_push, /* error */ &error_str))) {
454+
if (!EG(exception)) {
455+
zend_argument_type_error(2, "must be a valid callback for option CURLMOPT_PUSHFUNCTION, %s", error);
456+
}
457+
efree(error_str);
458+
return false;
459+
}
460+
zend_fcc_addref(&mh->handlers.server_push);
461+
470462
error = curl_multi_setopt(mh->multi, CURLMOPT_PUSHFUNCTION, _php_server_push_callback);
471463
if (error != CURLM_OK) {
472464
return false;
473465
}
474466
error = curl_multi_setopt(mh->multi, CURLMOPT_PUSHDATA, mh);
475467
break;
468+
}
476469
default:
477470
zend_argument_value_error(2, "is not a valid cURL multi option");
478471
error = CURLM_UNKNOWN_OPTION;
@@ -548,9 +541,9 @@ static void curl_multi_free_obj(zend_object *object)
548541

549542
curl_multi_cleanup(mh->multi);
550543
zend_llist_clean(&mh->easyh);
551-
if (mh->handlers.server_push) {
552-
zval_ptr_dtor(&mh->handlers.server_push->func_name);
553-
efree(mh->handlers.server_push);
544+
545+
if (ZEND_FCC_INITIALIZED(mh->handlers.server_push)) {
546+
zend_fcc_dtor(&mh->handlers.server_push);
554547
}
555548

556549
zend_object_std_dtor(&mh->std);
@@ -562,8 +555,8 @@ static HashTable *curl_multi_get_gc(zend_object *object, zval **table, int *n)
562555

563556
zend_get_gc_buffer *gc_buffer = zend_get_gc_buffer_create();
564557

565-
if (curl_multi->handlers.server_push) {
566-
zend_get_gc_buffer_add_zval(gc_buffer, &curl_multi->handlers.server_push->func_name);
558+
if (ZEND_FCC_INITIALIZED(curl_multi->handlers.server_push)) {
559+
zend_get_gc_buffer_add_fcc(gc_buffer, &curl_multi->handlers.server_push);
567560
}
568561

569562
zend_llist_position pos;

0 commit comments

Comments
 (0)