From: Michael Wallner Date: Tue, 21 Jun 2016 07:09:14 +0000 (+0200) Subject: Merge branch 'v2.6.x' X-Git-Tag: RELEASE_3_1_0_BETA1~6 X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-http;a=commitdiff_plain;h=7214e1aef4efce10bcc509d2a741acef88d28781;hp=-c Merge branch 'v2.6.x' --- 7214e1aef4efce10bcc509d2a741acef88d28781 diff --combined src/php_http_client.c index 4e4a0cf,f1b1fc5..b719d2f --- a/src/php_http_client.c +++ b/src/php_http_client.c @@@ -20,141 -20,131 +20,141 @@@ */ static HashTable php_http_client_drivers; +static void php_http_client_driver_hash_dtor(zval *pData) +{ + pefree(Z_PTR_P(pData), 1); +} + ZEND_RESULT_CODE php_http_client_driver_add(php_http_client_driver_t *driver) { - return zend_hash_add(&php_http_client_drivers, driver->name_str, driver->name_len + 1, (void *) driver, sizeof(php_http_client_driver_t), NULL); + return zend_hash_add_mem(&php_http_client_drivers, driver->driver_name, (void *) driver, sizeof(php_http_client_driver_t)) + ? SUCCESS : FAILURE; } -ZEND_RESULT_CODE php_http_client_driver_get(const char *name_str, size_t name_len, php_http_client_driver_t *driver) +php_http_client_driver_t *php_http_client_driver_get(zend_string *name) { + zval *ztmp; php_http_client_driver_t *tmp; - if ((name_str && SUCCESS == zend_hash_find(&php_http_client_drivers, name_str, name_len + 1, (void *) &tmp)) - || (SUCCESS == zend_hash_get_current_data(&php_http_client_drivers, (void *) &tmp))) { - *driver = *tmp; - return SUCCESS; + if (name && (tmp = zend_hash_find_ptr(&php_http_client_drivers, name))) { + return tmp; } - return FAILURE; + if ((ztmp = zend_hash_get_current_data(&php_http_client_drivers))) { + return Z_PTR_P(ztmp); + } + return NULL; } -static int apply_driver_list(void *p, void *arg TSRMLS_DC) +static int apply_driver_list(zval *p, void *arg) { - php_http_client_driver_t *d = p; - zval *zname; + php_http_client_driver_t *d = Z_PTR_P(p); + zval zname; - MAKE_STD_ZVAL(zname); - ZVAL_STRINGL(zname, d->name_str, d->name_len, 1); + ZVAL_STR_COPY(&zname, d->driver_name); - zend_hash_next_index_insert(arg, &zname, sizeof(zval *), NULL); + zend_hash_next_index_insert(arg, &zname); return ZEND_HASH_APPLY_KEEP; } -void php_http_client_driver_list(HashTable *ht TSRMLS_DC) +void php_http_client_driver_list(HashTable *ht) +{ + zend_hash_apply_with_argument(&php_http_client_drivers, apply_driver_list, ht); +} + +static zend_class_entry *php_http_client_class_entry; +zend_class_entry *php_http_client_get_class_entry(void) { - zend_hash_apply_with_argument(&php_http_client_drivers, apply_driver_list, ht TSRMLS_CC); + return php_http_client_class_entry; } -void php_http_client_options_set_subr(zval *this_ptr, char *key, size_t len, zval *opts, int overwrite TSRMLS_DC) +void php_http_client_options_set_subr(zval *instance, char *key, size_t len, zval *opts, int overwrite) { if (overwrite || (opts && zend_hash_num_elements(Z_ARRVAL_P(opts)))) { - zend_class_entry *this_ce = Z_OBJCE_P(getThis()); - zval *old_opts, *new_opts, **entry = NULL; + zend_class_entry *this_ce = Z_OBJCE_P(instance); + zval old_opts_tmp, *old_opts, new_opts, *entry = NULL; - MAKE_STD_ZVAL(new_opts); - array_init(new_opts); - old_opts = zend_read_property(this_ce, getThis(), ZEND_STRL("options"), 0 TSRMLS_CC); + array_init(&new_opts); + old_opts = zend_read_property(this_ce, instance, ZEND_STRL("options"), 0, &old_opts_tmp); if (Z_TYPE_P(old_opts) == IS_ARRAY) { - array_copy(Z_ARRVAL_P(old_opts), Z_ARRVAL_P(new_opts)); + array_copy(Z_ARRVAL_P(old_opts), Z_ARRVAL(new_opts)); } if (overwrite) { if (opts && zend_hash_num_elements(Z_ARRVAL_P(opts))) { Z_ADDREF_P(opts); - zend_symtable_update(Z_ARRVAL_P(new_opts), key, len, (void *) &opts, sizeof(zval *), NULL); + zend_symtable_str_update(Z_ARRVAL(new_opts), key, len, opts); } else { - zend_symtable_del(Z_ARRVAL_P(new_opts), key, len); + zend_symtable_str_del(Z_ARRVAL(new_opts), key, len); } } else if (opts && zend_hash_num_elements(Z_ARRVAL_P(opts))) { - if (SUCCESS == zend_symtable_find(Z_ARRVAL_P(new_opts), key, len, (void *) &entry)) { - array_join(Z_ARRVAL_P(opts), Z_ARRVAL_PP(entry), 0, 0); + if ((entry = zend_symtable_str_find(Z_ARRVAL(new_opts), key, len))) { + array_join(Z_ARRVAL_P(opts), Z_ARRVAL_P(entry), 0, 0); } else { Z_ADDREF_P(opts); - zend_symtable_update(Z_ARRVAL_P(new_opts), key, len, (void *) &opts, sizeof(zval *), NULL); + zend_symtable_str_update(Z_ARRVAL(new_opts), key, len, opts); } } - zend_update_property(this_ce, getThis(), ZEND_STRL("options"), new_opts TSRMLS_CC); + zend_update_property(this_ce, instance, ZEND_STRL("options"), &new_opts); zval_ptr_dtor(&new_opts); } } -void php_http_client_options_set(zval *this_ptr, zval *opts TSRMLS_DC) +void php_http_client_options_set(zval *instance, zval *opts) { - php_http_array_hashkey_t key = php_http_array_hashkey_init(0); - HashPosition pos; - zval *new_opts; - zend_class_entry *this_ce = Z_OBJCE_P(getThis()); - zend_bool is_client = instanceof_function(this_ce, php_http_client_class_entry TSRMLS_CC); + php_http_arrkey_t key; + zval new_opts; + zend_class_entry *this_ce = Z_OBJCE_P(instance); + zend_bool is_client = instanceof_function(this_ce, php_http_client_class_entry); - MAKE_STD_ZVAL(new_opts); - array_init(new_opts); + array_init(&new_opts); if (!opts || !zend_hash_num_elements(Z_ARRVAL_P(opts))) { - zend_update_property(this_ce, getThis(), ZEND_STRL("options"), new_opts TSRMLS_CC); + zend_update_property(this_ce, instance, ZEND_STRL("options"), &new_opts); zval_ptr_dtor(&new_opts); } else { - zval *old_opts, *add_opts, **opt; + zval old_opts_tmp, *old_opts, add_opts, *opt; - MAKE_STD_ZVAL(add_opts); - array_init(add_opts); + array_init(&add_opts); /* some options need extra attention -- thus cannot use array_merge() directly */ - FOREACH_KEYVAL(pos, opts, key, opt) { - if (key.type == HASH_KEY_IS_STRING) { -#define KEYMATCH(k, s) ((sizeof(s)==k.len) && !strcasecmp(k.str, s)) - if (Z_TYPE_PP(opt) == IS_ARRAY && (KEYMATCH(key, "ssl") || KEYMATCH(key, "cookies"))) { - php_http_client_options_set_subr(getThis(), key.str, key.len, *opt, 0 TSRMLS_CC); - } else if (is_client && (KEYMATCH(key, "recordHistory") || KEYMATCH(key, "responseMessageClass"))) { - zend_update_property(this_ce, getThis(), key.str, key.len-1, *opt TSRMLS_CC); - } else if (Z_TYPE_PP(opt) == IS_NULL) { - old_opts = zend_read_property(this_ce, getThis(), ZEND_STRL("options"), 0 TSRMLS_CC); + ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(opts), key.h, key.key, opt) + { + if (key.key) { + if (Z_TYPE_P(opt) == IS_ARRAY && (zend_string_equals_literal(key.key, "ssl") || zend_string_equals_literal(key.key, "cookies"))) { + php_http_client_options_set_subr(instance, key.key->val, key.key->len, opt, 0); + } else if (is_client && (zend_string_equals_literal(key.key, "recordHistory") || zend_string_equals_literal(key.key, "responseMessageClass"))) { + zend_update_property(this_ce, instance, key.key->val, key.key->len, opt); + } else if (Z_TYPE_P(opt) == IS_NULL) { + old_opts = zend_read_property(this_ce, instance, ZEND_STRL("options"), 0, &old_opts_tmp); if (Z_TYPE_P(old_opts) == IS_ARRAY) { - zend_symtable_del(Z_ARRVAL_P(old_opts), key.str, key.len); + zend_symtable_del(Z_ARRVAL_P(old_opts), key.key); } } else { - Z_ADDREF_P(*opt); - add_assoc_zval_ex(add_opts, key.str, key.len, *opt); + Z_TRY_ADDREF_P(opt); + add_assoc_zval_ex(&add_opts, key.key->val, key.key->len, opt); } } } + ZEND_HASH_FOREACH_END(); - old_opts = zend_read_property(this_ce, getThis(), ZEND_STRL("options"), 0 TSRMLS_CC); + old_opts = zend_read_property(this_ce, instance, ZEND_STRL("options"), 0, &old_opts_tmp); if (Z_TYPE_P(old_opts) == IS_ARRAY) { - array_copy(Z_ARRVAL_P(old_opts), Z_ARRVAL_P(new_opts)); + array_copy(Z_ARRVAL_P(old_opts), Z_ARRVAL(new_opts)); } - array_join(Z_ARRVAL_P(add_opts), Z_ARRVAL_P(new_opts), 0, 0); - zend_update_property(this_ce, getThis(), ZEND_STRL("options"), new_opts TSRMLS_CC); + array_join(Z_ARRVAL(add_opts), Z_ARRVAL(new_opts), 0, 0); + zend_update_property(this_ce, instance, ZEND_STRL("options"), &new_opts); zval_ptr_dtor(&new_opts); zval_ptr_dtor(&add_opts); } } -void php_http_client_options_get_subr(zval *this_ptr, char *key, size_t len, zval *return_value TSRMLS_DC) +void php_http_client_options_get_subr(zval *instance, char *key, size_t len, zval *return_value) { - zend_class_entry *this_ce = Z_OBJCE_P(getThis()); - zval **options, *opts = zend_read_property(this_ce, getThis(), ZEND_STRL("options"), 0 TSRMLS_CC); + zend_class_entry *this_ce = Z_OBJCE_P(instance); + zval *options, opts_tmp, *opts = zend_read_property(this_ce, instance, ZEND_STRL("options"), 0, &opts_tmp); - if ((Z_TYPE_P(opts) == IS_ARRAY) && (SUCCESS == zend_symtable_find(Z_ARRVAL_P(opts), key, len, (void *) &options))) { - RETVAL_ZVAL(*options, 1, 0); + if ((Z_TYPE_P(opts) == IS_ARRAY) && (options = zend_symtable_str_find(Z_ARRVAL_P(opts), key, len))) { + RETVAL_ZVAL(options, 1, 0); } } @@@ -167,7 -157,7 +167,7 @@@ static void queue_dtor(void *enqueued } } -php_http_client_t *php_http_client_init(php_http_client_t *h, php_http_client_ops_t *ops, php_resource_factory_t *rf, void *init_arg TSRMLS_DC) +php_http_client_t *php_http_client_init(php_http_client_t *h, php_http_client_ops_t *ops, php_resource_factory_t *rf, void *init_arg) { php_http_client_t *free_h = NULL; @@@ -184,11 -174,14 +184,11 @@@ } zend_llist_init(&h->requests, sizeof(php_http_client_enqueue_t), queue_dtor, 0); zend_llist_init(&h->responses, sizeof(void *), NULL, 0); - TSRMLS_SET_CTX(h->ts); if (h->ops->init) { if (!(h = h->ops->init(h, init_arg))) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not initialize client"); - if (free_h) { - efree(free_h); - } + php_error_docref(NULL, E_WARNING, "Could not initialize client"); + PTR_FREE(free_h); } } @@@ -211,6 -204,8 +211,8 @@@ void php_http_client_dtor(php_http_clie if (h->ops->dtor) { h->ops->dtor(h); } + h->callback.debug.func = NULL; + h->callback.debug.arg = NULL; php_resource_factory_free(&h->rf); } @@@ -225,9 -220,11 +227,9 @@@ void php_http_client_free(php_http_clie ZEND_RESULT_CODE php_http_client_enqueue(php_http_client_t *h, php_http_client_enqueue_t *enqueue) { - TSRMLS_FETCH_FROM_CTX(h->ts); - if (h->ops->enqueue) { if (php_http_client_enqueued(h, enqueue->request, NULL)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to enqueue request; request already in queue"); + php_error_docref(NULL, E_WARNING, "Failed to enqueue request; request already in queue"); return FAILURE; } return h->ops->enqueue(h, enqueue); @@@ -238,11 -235,13 +240,11 @@@ ZEND_RESULT_CODE php_http_client_dequeue(php_http_client_t *h, php_http_message_t *request) { - TSRMLS_FETCH_FROM_CTX(h->ts); - if (h->ops->dequeue) { php_http_client_enqueue_t *enqueue = php_http_client_enqueued(h, request, NULL); if (!enqueue) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to dequeue request; request not in queue"); + php_error_docref(NULL, E_WARNING, "Failed to dequeue request; request not in queue"); return FAILURE; } return h->ops->dequeue(h, enqueue); @@@ -324,98 -323,64 +326,107 @@@ ZEND_RESULT_CODE php_http_client_getopt return FAILURE; } -zend_class_entry *php_http_client_class_entry; static zend_object_handlers php_http_client_object_handlers; -void php_http_client_object_free(void *object TSRMLS_DC) +void php_http_client_object_free(zend_object *object) { - php_http_client_object_t *o = (php_http_client_object_t *) object; + php_http_client_object_t *o = PHP_HTTP_OBJ(object, NULL); + + PTR_FREE(o->gc); php_http_client_free(&o->client); + if (o->debug.fci.size > 0) { + zend_fcall_info_args_clear(&o->debug.fci, 1); + zval_ptr_dtor(&o->debug.fci.function_name); + o->debug.fci.size = 0; + } php_http_object_method_dtor(&o->notify); php_http_object_method_free(&o->update); - zend_object_std_dtor((zend_object *) o TSRMLS_CC); - efree(o); + zend_object_std_dtor(object); } -zend_object_value php_http_client_object_new_ex(zend_class_entry *ce, php_http_client_t *client, php_http_client_object_t **ptr TSRMLS_DC) +php_http_client_object_t *php_http_client_object_new_ex(zend_class_entry *ce, php_http_client_t *client) { php_http_client_object_t *o; - o = ecalloc(1, sizeof(php_http_client_object_t)); - zend_object_std_init((zend_object *) o, ce TSRMLS_CC); - object_properties_init((zend_object *) o, ce); + o = ecalloc(1, sizeof(*o) + zend_object_properties_size(ce)); + zend_object_std_init(&o->zo, ce); + object_properties_init(&o->zo, ce); o->client = client; - if (ptr) { - *ptr = o; - } + o->zo.handlers = &php_http_client_object_handlers; - o->zv.handle = zend_objects_store_put(o, NULL, php_http_client_object_free, NULL TSRMLS_CC); - o->zv.handlers = &php_http_client_object_handlers; + return o; +} - return o->zv; +zend_object *php_http_client_object_new(zend_class_entry *ce) +{ + return &php_http_client_object_new_ex(ce, NULL)->zo; } -zend_object_value php_http_client_object_new(zend_class_entry *ce TSRMLS_DC) +static HashTable *php_http_client_object_get_gc(zval *object, zval **table, int *n) { - return php_http_client_object_new_ex(ce, NULL, NULL TSRMLS_CC); + php_http_client_object_t *obj = PHP_HTTP_OBJ(NULL, object); + zend_llist_element *el = NULL; + HashTable *props = Z_OBJPROP_P(object); - uint32_t count = zend_hash_num_elements(props) + zend_llist_count(&obj->client->responses) + zend_llist_count(&obj->client->requests) + 1; ++ uint32_t count = zend_hash_num_elements(props) + zend_llist_count(&obj->client->responses) + zend_llist_count(&obj->client->requests) + 2; + zval *val; + + *n = 0; + *table = obj->gc = erealloc(obj->gc, sizeof(zval) * count); + +#if PHP_HTTP_HAVE_CURL + if (obj->client->ops == php_http_client_curl_get_ops()) { + php_http_client_curl_t *curl = obj->client->ctx; + + if (curl->ev_ops == php_http_client_curl_user_ops_get()) { + php_http_client_curl_user_context_t *ctx = curl->ev_ctx; + + ZVAL_COPY_VALUE(&obj->gc[(*n)++], &ctx->user); + } + } +#endif + ++ if (obj->debug.fci.size > 0) { ++ ZVAL_COPY_VALUE(&obj->gc[(*n)++], &obj->debug.fci.function_name); ++ } ++ + for (el = obj->client->responses.head; el; el = el->next) { + php_http_message_object_t *response_obj = *(php_http_message_object_t **) el->data; + ZVAL_OBJ(&obj->gc[(*n)++], &response_obj->zo); + } + + for (el = obj->client->requests.head; el; el = el->next) { + php_http_client_enqueue_t *q = (php_http_client_enqueue_t *) el->data; + php_http_message_object_t *request_obj = q->opaque; /* FIXME */ + ZVAL_OBJ(&obj->gc[(*n)++], &request_obj->zo); + } + + ZEND_HASH_FOREACH_VAL(props, val) + { + ZVAL_COPY_VALUE(&obj->gc[(*n)++], val); + } + ZEND_HASH_FOREACH_END(); + + return NULL; } -static void handle_history(zval *zclient, php_http_message_t *request, php_http_message_t *response TSRMLS_DC) +static void handle_history(zval *zclient, php_http_message_t *request, php_http_message_t *response) { - zval *new_hist, *old_hist = zend_read_property(php_http_client_class_entry, zclient, ZEND_STRL("history"), 0 TSRMLS_CC); - php_http_message_t *zipped = php_http_message_zip(response, request); - zend_object_value ov = php_http_message_object_new_ex(php_http_message_class_entry, zipped, NULL TSRMLS_CC); + zval new_hist, old_hist_tmp, *old_hist = zend_read_property(php_http_client_class_entry, zclient, ZEND_STRL("history"), 0, &old_hist_tmp); + php_http_message_t *req_copy = php_http_message_copy(request, NULL); + php_http_message_t *res_copy = php_http_message_copy(response, NULL); + php_http_message_t *zipped = php_http_message_zip(res_copy, req_copy); + php_http_message_object_t *obj = php_http_message_object_new_ex(php_http_message_get_class_entry(), zipped); - MAKE_STD_ZVAL(new_hist); - ZVAL_OBJVAL(new_hist, ov, 0); + ZVAL_OBJ(&new_hist, &obj->zo); if (Z_TYPE_P(old_hist) == IS_OBJECT) { - php_http_message_object_prepend(new_hist, old_hist, 1 TSRMLS_CC); + php_http_message_object_prepend(&new_hist, old_hist, 1); } - zend_update_property(php_http_client_class_entry, zclient, ZEND_STRL("history"), new_hist TSRMLS_CC); + zend_update_property(php_http_client_class_entry, zclient, ZEND_STRL("history"), &new_hist); zval_ptr_dtor(&new_hist); } @@@ -425,54 -390,61 +436,54 @@@ static ZEND_RESULT_CODE handle_response zval zclient; php_http_message_t *msg; php_http_client_progress_state_t *progress; - TSRMLS_FETCH_FROM_CTX(client->ts); - INIT_PZVAL(&zclient); - ZVAL_OBJVAL(&zclient, ((php_http_client_object_t*) arg)->zv, 0); + ZVAL_OBJ(&zclient, &((php_http_client_object_t*) arg)->zo); if ((msg = *response)) { php_http_message_object_t *msg_obj; - zval *info, *zresponse, *zrequest; + zval info, zresponse, zrequest, rec_hist_tmp; HashTable *info_ht; /* ensure the message is of type response (could be uninitialized in case of early error, like DNS) */ php_http_message_set_type(msg, PHP_HTTP_RESPONSE); - if (z_is_true(zend_read_property(php_http_client_class_entry, &zclient, ZEND_STRL("recordHistory"), 0 TSRMLS_CC))) { - handle_history(&zclient, e->request, *response TSRMLS_CC); + if (zend_is_true(zend_read_property(php_http_client_class_entry, &zclient, ZEND_STRL("recordHistory"), 0, &rec_hist_tmp))) { + handle_history(&zclient, e->request, *response); } /* hard detach, redirects etc. are in the history */ php_http_message_free(&msg->parent); *response = NULL; - MAKE_STD_ZVAL(zresponse); - ZVAL_OBJVAL(zresponse, php_http_message_object_new_ex(php_http_client_response_class_entry, msg, &msg_obj TSRMLS_CC), 0); + msg_obj = php_http_message_object_new_ex(php_http_get_client_response_class_entry(), msg); + ZVAL_OBJECT(&zresponse, &msg_obj->zo, 1); + ZVAL_OBJECT(&zrequest, &((php_http_message_object_t *) e->opaque)->zo, 1); - MAKE_STD_ZVAL(zrequest); - ZVAL_OBJVAL(zrequest, ((php_http_message_object_t *) e->opaque)->zv, 1); + php_http_message_object_prepend(&zresponse, &zrequest, 1); - php_http_message_object_prepend(zresponse, zrequest, 1 TSRMLS_CC); - - MAKE_STD_ZVAL(info); - object_init(info); - info_ht = HASH_OF(info); + object_init(&info); + info_ht = HASH_OF(&info); php_http_client_getopt(client, PHP_HTTP_CLIENT_OPT_TRANSFER_INFO, e->request, &info_ht); - zend_update_property(php_http_client_response_class_entry, zresponse, ZEND_STRL("transferInfo"), info TSRMLS_CC); + zend_update_property(php_http_get_client_response_class_entry(), &zresponse, ZEND_STRL("transferInfo"), &info); zval_ptr_dtor(&info); - zend_objects_store_add_ref_by_handle(msg_obj->zv.handle TSRMLS_CC); zend_llist_add_element(&client->responses, &msg_obj); if (e->closure.fci.size) { - zval *retval = NULL; + zval retval; zend_error_handling zeh; - zend_fcall_info_argn(&e->closure.fci TSRMLS_CC, 1, &zresponse); - zend_replace_error_handling(EH_NORMAL, NULL, &zeh TSRMLS_CC); - zend_fcall_info_call(&e->closure.fci, &e->closure.fcc, &retval, NULL TSRMLS_CC); - zend_restore_error_handling(&zeh TSRMLS_CC); - zend_fcall_info_argn(&e->closure.fci TSRMLS_CC, 0); + ZVAL_UNDEF(&retval); + zend_fcall_info_argn(&e->closure.fci, 1, &zresponse); + zend_replace_error_handling(EH_NORMAL, NULL, &zeh); + zend_fcall_info_call(&e->closure.fci, &e->closure.fcc, &retval, NULL); + zend_restore_error_handling(&zeh); + zend_fcall_info_argn(&e->closure.fci, 0); - if (retval) { - if (Z_TYPE_P(retval) == IS_BOOL) { - dequeue = Z_BVAL_P(retval); - } - zval_ptr_dtor(&retval); + if (Z_TYPE(retval) == IS_TRUE) { + dequeue = 1; } + zval_ptr_dtor(&retval); } zval_ptr_dtor(&zresponse); @@@ -494,35 -466,74 +505,59 @@@ static void handle_progress(void *arg, php_http_client_t *client, php_http_client_enqueue_t *e, php_http_client_progress_state_t *progress) { - zval *zrequest, *zprogress, *zclient, **args[2]; + zval zclient, args[2]; php_http_client_object_t *client_obj = arg; zend_error_handling zeh; - TSRMLS_FETCH_FROM_CTX(client->ts); - - MAKE_STD_ZVAL(zclient); - ZVAL_OBJVAL(zclient, client_obj->zv, 1); - - MAKE_STD_ZVAL(zrequest); - ZVAL_OBJVAL(zrequest, ((php_http_message_object_t *) e->opaque)->zv, 1); - args[0] = &zrequest; - - MAKE_STD_ZVAL(zprogress); - object_init(zprogress); - add_property_bool(zprogress, "started", progress->started); - add_property_bool(zprogress, "finished", progress->finished); - add_property_string(zprogress, "info", STR_PTR(progress->info), 1); - add_property_double(zprogress, "dltotal", progress->dl.total); - add_property_double(zprogress, "dlnow", progress->dl.now); - add_property_double(zprogress, "ultotal", progress->ul.total); - add_property_double(zprogress, "ulnow", progress->ul.now); - args[1] = &zprogress; - - zend_replace_error_handling(EH_NORMAL, NULL, &zeh TSRMLS_CC); - php_http_object_method_call(&client_obj->notify, zclient, NULL, 2, args TSRMLS_CC); - zend_restore_error_handling(&zeh TSRMLS_CC); + + ZVAL_OBJECT(&zclient, &client_obj->zo, 1); + ZVAL_OBJECT(&args[0], &((php_http_message_object_t *) e->opaque)->zo, 1); + object_init(&args[1]); + add_property_bool(&args[1], "started", progress->started); + add_property_bool(&args[1], "finished", progress->finished); + add_property_string(&args[1], "info", STR_PTR(progress->info)); + add_property_double(&args[1], "dltotal", progress->dl.total); + add_property_double(&args[1], "dlnow", progress->dl.now); + add_property_double(&args[1], "ultotal", progress->ul.total); + add_property_double(&args[1], "ulnow", progress->ul.now); + + zend_replace_error_handling(EH_NORMAL, NULL, &zeh); + php_http_object_method_call(&client_obj->notify, &zclient, NULL, 2, args); + zend_restore_error_handling(&zeh); zval_ptr_dtor(&zclient); - zval_ptr_dtor(&zrequest); - zval_ptr_dtor(&zprogress); + zval_ptr_dtor(&args[0]); + zval_ptr_dtor(&args[1]); } + static void handle_debug(void *arg, php_http_client_t *client, php_http_client_enqueue_t *e, unsigned type, const char *data, size_t size) + { - zval *ztype, *zdata, *zreq, *zclient; ++ zval ztype, zdata, zreq, zclient; + php_http_client_object_t *client_obj = arg; + zend_error_handling zeh; - TSRMLS_FETCH_FROM_CTX(client->ts); - - MAKE_STD_ZVAL(zclient); - ZVAL_OBJVAL(zclient, client_obj->zv, 1); - MAKE_STD_ZVAL(zreq); - ZVAL_OBJVAL(zreq, ((php_http_message_object_t *) e->opaque)->zv, 1); - MAKE_STD_ZVAL(ztype); - ZVAL_LONG(ztype, type); - MAKE_STD_ZVAL(zdata); - ZVAL_STRINGL(zdata, data, size, 1); - - zend_replace_error_handling(EH_NORMAL, NULL, &zeh TSRMLS_CC); - if (SUCCESS == zend_fcall_info_argn(&client_obj->debug.fci TSRMLS_CC, 4, &zclient, &zreq, &ztype, &zdata)) { - zend_fcall_info_call(&client_obj->debug.fci, &client_obj->debug.fcc, NULL, NULL TSRMLS_CC); ++ ++ ZVAL_OBJECT(&zclient, &client_obj->zo, 1); ++ ZVAL_OBJECT(&zreq, &((php_http_message_object_t *) e->opaque)->zo, 1); ++ ZVAL_LONG(&ztype, type); ++ ZVAL_STRINGL(&zdata, data, size); ++ ++ zend_replace_error_handling(EH_NORMAL, NULL, &zeh); ++ if (SUCCESS == zend_fcall_info_argn(&client_obj->debug.fci, 4, &zclient, &zreq, &ztype, &zdata)) { ++ zend_fcall_info_call(&client_obj->debug.fci, &client_obj->debug.fcc, NULL, NULL); + zend_fcall_info_args_clear(&client_obj->debug.fci, 0); + } - zend_restore_error_handling(&zeh TSRMLS_CC); ++ zend_restore_error_handling(&zeh); + + zval_ptr_dtor(&zclient); + zval_ptr_dtor(&zreq); + zval_ptr_dtor(&ztype); + zval_ptr_dtor(&zdata); - + } + static void response_dtor(void *data) { php_http_message_object_t *msg_obj = *(php_http_message_object_t **) data; - TSRMLS_FETCH_FROM_CTX(msg_obj->message->ts); - zend_objects_store_del_ref_by_handle_ex(msg_obj->zv.handle, msg_obj->zv.handlers TSRMLS_CC); + zend_object_release(&msg_obj->zo); } ZEND_BEGIN_ARG_INFO_EX(ai_HttpClient_construct, 0, 0, 0) @@@ -531,40 -542,45 +566,40 @@@ ZEND_END_ARG_INFO(); static PHP_METHOD(HttpClient, __construct) { - char *driver_str = NULL, *persistent_handle_str = NULL; - int driver_len = 0, persistent_handle_len = 0; - php_http_client_driver_t driver; + zend_string *driver_name = NULL, *persistent_handle_name = NULL; + php_http_client_driver_t *driver; php_resource_factory_t *rf = NULL; php_http_client_object_t *obj; - zval *os; + zval os; - php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ss", &driver_str, &driver_len, &persistent_handle_str, &persistent_handle_len), invalid_arg, return); + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "|S!S!", &driver_name, &persistent_handle_name), invalid_arg, return); - if (SUCCESS != php_http_client_driver_get(driver_str, driver_len, &driver)) { - php_http_throw(unexpected_val, "Failed to locate \"%s\" client request handler", driver_str); + if (!zend_hash_num_elements(&php_http_client_drivers)) { + php_http_throw(unexpected_val, "No http\\Client drivers available", NULL); + return; + } + if (!(driver = php_http_client_driver_get(driver_name))) { + php_http_throw(unexpected_val, "Failed to locate \"%s\" client request handler", driver_name ? driver_name->val : "default"); return; } - MAKE_STD_ZVAL(os); - object_init_ex(os, spl_ce_SplObjectStorage); - zend_update_property(php_http_client_class_entry, getThis(), ZEND_STRL("observers"), os TSRMLS_CC); + object_init_ex(&os, spl_ce_SplObjectStorage); + zend_update_property(php_http_client_class_entry, getThis(), ZEND_STRL("observers"), &os); zval_ptr_dtor(&os); - if (persistent_handle_len) { - char *name_str; - size_t name_len; + if (persistent_handle_name) { php_persistent_handle_factory_t *pf; - name_len = spprintf(&name_str, 0, "http\\Client\\%s", driver.name_str); - php_http_pretty_key(name_str + sizeof("http\\Client"), driver.name_len, 1, 1); - - if ((pf = php_persistent_handle_concede(NULL , name_str, name_len, persistent_handle_str, persistent_handle_len, NULL, NULL TSRMLS_CC))) { + if ((pf = php_persistent_handle_concede(NULL, driver->client_name, persistent_handle_name, NULL, NULL))) { rf = php_persistent_handle_resource_factory_init(NULL, pf); } - - efree(name_str); } - obj = zend_object_store_get_object(getThis() TSRMLS_CC); + obj = PHP_HTTP_OBJ(NULL, getThis()); - php_http_expect(obj->client = php_http_client_init(NULL, driver.client_ops, rf, NULL TSRMLS_CC), runtime, return); + php_http_expect(obj->client = php_http_client_init(NULL, driver->client_ops, rf, NULL), runtime, return); - php_http_object_method_init(&obj->notify, getThis(), ZEND_STRL("notify") TSRMLS_CC); + php_http_object_method_init(&obj->notify, getThis(), ZEND_STRL("notify")); obj->client->callback.response.func = handle_response; obj->client->callback.response.arg = obj; @@@ -581,7 -597,7 +616,7 @@@ static PHP_METHOD(HttpClient, reset php_http_client_object_t *obj; php_http_expect(SUCCESS == zend_parse_parameters_none(), invalid_arg, return); - obj = zend_object_store_get_object(getThis() TSRMLS_CC); + obj = PHP_HTTP_OBJ(NULL, getThis()); obj->iterator = 0; php_http_client_reset(obj->client); @@@ -589,19 -605,18 +624,19 @@@ RETVAL_ZVAL(getThis(), 1, 0); } -static HashTable *combined_options(zval *client, zval *request TSRMLS_DC) +static HashTable *combined_options(zval *client, zval *request) { HashTable *options; - int num_options = 0; - zval *z_roptions = NULL, *z_coptions = zend_read_property(php_http_client_class_entry, client, ZEND_STRL("options"), 0 TSRMLS_CC); + unsigned num_options = 0; + zval z_roptions, z_options_tmp, *z_coptions = zend_read_property(php_http_client_class_entry, client, ZEND_STRL("options"), 0, &z_options_tmp); if (Z_TYPE_P(z_coptions) == IS_ARRAY) { num_options = zend_hash_num_elements(Z_ARRVAL_P(z_coptions)); } - zend_call_method_with_0_params(&request, NULL, NULL, "getOptions", &z_roptions); - if (z_roptions && Z_TYPE_P(z_roptions) == IS_ARRAY) { - int num = zend_hash_num_elements(Z_ARRVAL_P(z_roptions)); + ZVAL_UNDEF(&z_roptions); + zend_call_method_with_0_params(request, NULL, NULL, "getOptions", &z_roptions); + if (Z_TYPE(z_roptions) == IS_ARRAY) { + unsigned num = zend_hash_num_elements(Z_ARRVAL(z_roptions)); if (num > num_options) { num_options = num; } @@@ -611,26 -626,28 +646,26 @@@ if (Z_TYPE_P(z_coptions) == IS_ARRAY) { array_copy(Z_ARRVAL_P(z_coptions), options); } - if (z_roptions) { - if (Z_TYPE_P(z_roptions) == IS_ARRAY) { - array_join(Z_ARRVAL_P(z_roptions), options, 0, 0); - } - zval_ptr_dtor(&z_roptions); + if (Z_TYPE(z_roptions) == IS_ARRAY) { + array_join(Z_ARRVAL(z_roptions), options, 0, 0); } + zval_ptr_dtor(&z_roptions); + return options; } static void msg_queue_dtor(php_http_client_enqueue_t *e) { php_http_message_object_t *msg_obj = e->opaque; - TSRMLS_FETCH_FROM_CTX(msg_obj->message->ts); - zend_objects_store_del_ref_by_handle_ex(msg_obj->zv.handle, msg_obj->zv.handlers TSRMLS_CC); + zend_object_release(&msg_obj->zo); zend_hash_destroy(e->options); FREE_HASHTABLE(e->options); if (e->closure.fci.size) { zval_ptr_dtor(&e->closure.fci.function_name); - if (e->closure.fci.object_ptr) { - zval_ptr_dtor(&e->closure.fci.object_ptr); + if (e->closure.fci.object) { + zend_object_release(e->closure.fci.object); } } } @@@ -648,10 -665,10 +683,10 @@@ static PHP_METHOD(HttpClient, enqueue php_http_message_object_t *msg_obj; php_http_client_enqueue_t q; - php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|f", &request, php_http_client_request_class_entry, &fci, &fcc), invalid_arg, return); + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "O|f", &request, php_http_get_client_request_class_entry(), &fci, &fcc), invalid_arg, return); - obj = zend_object_store_get_object(getThis() TSRMLS_CC); - msg_obj = zend_object_store_get_object(request TSRMLS_CC); + obj = PHP_HTTP_OBJ(NULL, getThis()); + msg_obj = PHP_HTTP_OBJ(NULL, request); if (php_http_client_enqueued(obj->client, msg_obj->message, NULL)) { php_http_throw(bad_method_call, "Failed to enqueue request; request already in queue", NULL); @@@ -659,20 -676,20 +694,20 @@@ } q.request = msg_obj->message; - q.options = combined_options(getThis(), request TSRMLS_CC); + q.options = combined_options(getThis(), request); q.dtor = msg_queue_dtor; q.opaque = msg_obj; q.closure.fci = fci; q.closure.fcc = fcc; if (fci.size) { - Z_ADDREF_P(fci.function_name); - if (fci.object_ptr) { - Z_ADDREF_P(fci.object_ptr); + Z_TRY_ADDREF(fci.function_name); + if (fci.object) { + ++GC_REFCOUNT(fci.object); } } - zend_objects_store_add_ref_by_handle(msg_obj->zv.handle TSRMLS_CC); + Z_ADDREF_P(request); php_http_expect(SUCCESS == php_http_client_enqueue(obj->client, &q), runtime, msg_queue_dtor(&q); @@@ -691,10 -708,10 +726,10 @@@ static PHP_METHOD(HttpClient, dequeue php_http_client_object_t *obj; php_http_message_object_t *msg_obj; - php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &request, php_http_client_request_class_entry), invalid_arg, return); + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "O", &request, php_http_get_client_request_class_entry()), invalid_arg, return); - obj = zend_object_store_get_object(getThis() TSRMLS_CC); - msg_obj = zend_object_store_get_object(request TSRMLS_CC); + obj = PHP_HTTP_OBJ(NULL, getThis()); + msg_obj = PHP_HTTP_OBJ(NULL, request); if (!php_http_client_enqueued(obj->client, msg_obj->message, NULL)) { php_http_throw(bad_method_call, "Failed to dequeue request; request not in queue", NULL); @@@ -719,30 -736,30 +754,30 @@@ static PHP_METHOD(HttpClient, requeue php_http_message_object_t *msg_obj; php_http_client_enqueue_t q; - php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O|f", &request, php_http_client_request_class_entry, &fci, &fcc), invalid_arg, return); + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "O|f", &request, php_http_get_client_request_class_entry(), &fci, &fcc), invalid_arg, return); - obj = zend_object_store_get_object(getThis() TSRMLS_CC); - msg_obj = zend_object_store_get_object(request TSRMLS_CC); + obj = PHP_HTTP_OBJ(NULL, getThis()); + msg_obj = PHP_HTTP_OBJ(NULL, request); if (php_http_client_enqueued(obj->client, msg_obj->message, NULL)) { php_http_expect(SUCCESS == php_http_client_dequeue(obj->client, msg_obj->message), runtime, return); } q.request = msg_obj->message; - q.options = combined_options(getThis(), request TSRMLS_CC); + q.options = combined_options(getThis(), request); q.dtor = msg_queue_dtor; q.opaque = msg_obj; q.closure.fci = fci; q.closure.fcc = fcc; if (fci.size) { - Z_ADDREF_P(fci.function_name); - if (fci.object_ptr) { - Z_ADDREF_P(fci.object_ptr); + Z_TRY_ADDREF(fci.function_name); + if (fci.object) { + ++GC_REFCOUNT(fci.object); } } - zend_objects_store_add_ref_by_handle(msg_obj->zv.handle TSRMLS_CC); + Z_ADDREF_P(request); php_http_expect(SUCCESS == php_http_client_enqueue(obj->client, &q), runtime, msg_queue_dtor(&q); @@@ -756,10 -773,10 +791,10 @@@ ZEND_BEGIN_ARG_INFO_EX(ai_HttpClient_co ZEND_END_ARG_INFO(); static PHP_METHOD(HttpClient, count) { - long count_mode = -1; + zend_long count_mode = -1; - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &count_mode)) { - php_http_client_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "|l", &count_mode)) { + php_http_client_object_t *obj = PHP_HTTP_OBJ(NULL, getThis()); RETVAL_LONG(zend_llist_count(&obj->client->requests)); } @@@ -773,20 -790,20 +808,20 @@@ static PHP_METHOD(HttpClient, getRespon zval *zrequest = NULL; php_http_client_object_t *obj; - php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|O", &zrequest, php_http_client_request_class_entry), invalid_arg, return); + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "|O", &zrequest, php_http_get_client_request_class_entry()), invalid_arg, return); - obj = zend_object_store_get_object(getThis() TSRMLS_CC); + obj = PHP_HTTP_OBJ(NULL, getThis()); if (zrequest) { /* lookup the response with the request */ zend_llist_element *el = NULL; - php_http_message_object_t *req_obj = zend_object_store_get_object(zrequest TSRMLS_CC); + php_http_message_object_t *req_obj = PHP_HTTP_OBJ(NULL, zrequest); for (el = obj->client->responses.head; el; el = el->next) { php_http_message_object_t *response_obj = *(php_http_message_object_t **) el->data; if (response_obj->message->parent == req_obj->message) { - RETURN_OBJVAL(response_obj->zv, 1); + RETURN_OBJECT(&response_obj->zo, 1); } } @@@ -801,7 -818,7 +836,7 @@@ /* pop off and go */ if (response_obj) { - RETVAL_OBJVAL(response_obj->zv, 1); + RETVAL_OBJECT(&response_obj->zo, 1); zend_llist_remove_tail(&obj->client->responses); } } @@@ -811,11 -828,11 +846,11 @@@ ZEND_BEGIN_ARG_INFO_EX(ai_HttpClient_ge ZEND_END_ARG_INFO(); static PHP_METHOD(HttpClient, getHistory) { - zval *zhistory; + zval zhistory_tmp, *zhistory; php_http_expect(SUCCESS == zend_parse_parameters_none(), invalid_arg, return); - zhistory = zend_read_property(php_http_client_class_entry, getThis(), ZEND_STRL("history"), 0 TSRMLS_CC); + zhistory = zend_read_property(php_http_client_class_entry, getThis(), ZEND_STRL("history"), 0, &zhistory_tmp); RETVAL_ZVAL(zhistory, 1, 0); } @@@ -827,7 -844,7 +862,7 @@@ static PHP_METHOD(HttpClient, send php_http_expect(SUCCESS == zend_parse_parameters_none(), invalid_arg, return); - obj = zend_object_store_get_object(getThis() TSRMLS_CC); + obj = PHP_HTTP_OBJ(NULL, getThis()); php_http_expect(SUCCESS == php_http_client_exec(obj->client), runtime, return); @@@ -839,7 -856,7 +874,7 @@@ ZEND_END_ARG_INFO() static PHP_METHOD(HttpClient, once) { if (SUCCESS == zend_parse_parameters_none()) { - php_http_client_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_http_client_object_t *obj = PHP_HTTP_OBJ(NULL, getThis()); RETURN_BOOL(0 < php_http_client_once(obj->client)); } @@@ -852,9 -869,9 +887,9 @@@ static PHP_METHOD(HttpClient, wait { double timeout = 0; - if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|d", &timeout)) { + if (SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "|d", &timeout)) { struct timeval timeout_val; - php_http_client_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_http_client_object_t *obj = PHP_HTTP_OBJ(NULL, getThis()); timeout_val.tv_sec = (time_t) timeout; timeout_val.tv_usec = PHP_HTTP_USEC(timeout) % PHP_HTTP_MCROSEC; @@@ -871,8 -888,8 +906,8 @@@ static PHP_METHOD(HttpClient, configure HashTable *settings = NULL; php_http_client_object_t *obj; - php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|H!", &settings), invalid_arg, return); - obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "|H!", &settings), invalid_arg, return); + obj = PHP_HTTP_OBJ(NULL, getThis()); php_http_expect(SUCCESS == php_http_client_setopt(obj->client, PHP_HTTP_CLIENT_OPT_CONFIGURATION, settings), unexpected_val, return); @@@ -887,9 -904,9 +922,9 @@@ static PHP_METHOD(HttpClient, enablePip zend_bool enable = 1; php_http_client_object_t *obj; - php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &enable), invalid_arg, return); + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "|b", &enable), invalid_arg, return); - obj = zend_object_store_get_object(getThis() TSRMLS_CC); + obj = PHP_HTTP_OBJ(NULL, getThis()); php_http_expect(SUCCESS == php_http_client_setopt(obj->client, PHP_HTTP_CLIENT_OPT_ENABLE_PIPELINING, &enable), unexpected_val, return); @@@ -904,9 -921,9 +939,9 @@@ static PHP_METHOD(HttpClient, enableEve zend_bool enable = 1; php_http_client_object_t *obj; - php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|b", &enable), invalid_arg, return); + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "|b", &enable), invalid_arg, return); - obj = zend_object_store_get_object(getThis() TSRMLS_CC); + obj = PHP_HTTP_OBJ(NULL, getThis()); php_http_expect(SUCCESS == php_http_client_setopt(obj->client, PHP_HTTP_CLIENT_OPT_USE_EVENTS, &enable), unexpected_val, return); @@@ -915,21 -932,20 +950,21 @@@ struct notify_arg { php_http_object_method_t *cb; - zval **args[3]; + zval args[3]; int argc; }; -static int notify(zend_object_iterator *iter, void *puser TSRMLS_DC) +static int notify(zend_object_iterator *iter, void *puser) { - zval **observer = NULL; + zval *observer; struct notify_arg *arg = puser; - iter->funcs->get_current_data(iter, &observer TSRMLS_CC); - if (observer) { - return php_http_object_method_call(arg->cb, *observer, NULL, arg->argc, arg->args TSRMLS_CC); + if ((observer = iter->funcs->get_current_data(iter))) { + if (SUCCESS == php_http_object_method_call(arg->cb, observer, NULL, arg->argc, arg->args)) { + return ZEND_HASH_APPLY_KEEP; + } } - return FAILURE; + return ZEND_HASH_APPLY_STOP; } ZEND_BEGIN_ARG_INFO_EX(ai_HttpClient_notify, 0, 0, 0) @@@ -937,14 -953,14 +972,14 @@@ ZEND_END_ARG_INFO(); static PHP_METHOD(HttpClient, notify) { - zval *request = NULL, *zprogress = NULL, *observers; + zval *request = NULL, *zprogress = NULL, observers_tmp, *observers; php_http_client_object_t *client_obj; struct notify_arg arg = {NULL}; - php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|O!o!", &request, php_http_client_request_class_entry, &zprogress), invalid_arg, return); + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "|O!o!", &request, php_http_get_client_request_class_entry(), &zprogress), invalid_arg, return); - client_obj = zend_object_store_get_object(getThis() TSRMLS_CC); - observers = zend_read_property(php_http_client_class_entry, getThis(), ZEND_STRL("observers"), 0 TSRMLS_CC); + client_obj = PHP_HTTP_OBJ(NULL, getThis()); + observers = zend_read_property(php_http_client_class_entry, getThis(), ZEND_STRL("observers"), 0, &observers_tmp); if (Z_TYPE_P(observers) != IS_OBJECT) { php_http_throw(unexpected_val, "Observer storage is corrupted", NULL); @@@ -953,26 -969,31 +988,26 @@@ if (client_obj->update) { arg.cb = client_obj->update; - - Z_ADDREF_P(getThis()); - arg.args[0] = &getThis(); + ZVAL_COPY(&arg.args[0], getThis()); arg.argc = 1; if (request) { - Z_ADDREF_P(request); - arg.args[1] = &request; + ZVAL_COPY(&arg.args[1], request); arg.argc += 1; } - if (zprogress) { - Z_ADDREF_P(zprogress); - arg.args[2] = &zprogress; + ZVAL_COPY(&arg.args[2], zprogress); arg.argc += 1; } - spl_iterator_apply(observers, notify, &arg TSRMLS_CC); + spl_iterator_apply(observers, notify, &arg); - zval_ptr_dtor(&getThis()); + zval_ptr_dtor(getThis()); if (request) { - zval_ptr_dtor(&request); + zval_ptr_dtor(request); } if (zprogress) { - zval_ptr_dtor(&zprogress); + zval_ptr_dtor(zprogress); } } @@@ -984,13 -1005,13 +1019,13 @@@ ZEND_BEGIN_ARG_INFO_EX(ai_HttpClient_at ZEND_END_ARG_INFO(); static PHP_METHOD(HttpClient, attach) { - zval *observers, *observer, *retval = NULL; + zval observers_tmp, *observers, *observer, retval; php_http_client_object_t *client_obj; - php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &observer, spl_ce_SplObserver), invalid_arg, return); + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "O", &observer, spl_ce_SplObserver), invalid_arg, return); - client_obj = zend_object_store_get_object(getThis() TSRMLS_CC); - observers = zend_read_property(php_http_client_class_entry, getThis(), ZEND_STRL("observers"), 0 TSRMLS_CC); + client_obj = PHP_HTTP_OBJ(NULL, getThis()); + observers = zend_read_property(php_http_client_class_entry, getThis(), ZEND_STRL("observers"), 0, &observers_tmp); if (Z_TYPE_P(observers) != IS_OBJECT) { php_http_throw(unexpected_val, "Observer storage is corrupted", NULL); @@@ -998,12 -1019,13 +1033,12 @@@ } if (!client_obj->update) { - client_obj->update = php_http_object_method_init(NULL, observer, ZEND_STRL("update") TSRMLS_CC); + client_obj->update = php_http_object_method_init(NULL, observer, ZEND_STRL("update")); } - zend_call_method_with_1_params(&observers, NULL, NULL, "attach", &retval, observer); - if (retval) { - zval_ptr_dtor(&retval); - } + ZVAL_UNDEF(&retval); + zend_call_method_with_1_params(observers, NULL, NULL, "attach", &retval, observer); + zval_ptr_dtor(&retval); RETVAL_ZVAL(getThis(), 1, 0); } @@@ -1013,20 -1035,21 +1048,20 @@@ ZEND_BEGIN_ARG_INFO_EX(ai_HttpClient_de ZEND_END_ARG_INFO(); static PHP_METHOD(HttpClient, detach) { - zval *observers, *observer, *retval = NULL; + zval observers_tmp, *observers, *observer, retval; - php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &observer, spl_ce_SplObserver), invalid_arg, return); + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "O", &observer, spl_ce_SplObserver), invalid_arg, return); - observers = zend_read_property(php_http_client_class_entry, getThis(), ZEND_STRL("observers"), 0 TSRMLS_CC); + observers = zend_read_property(php_http_client_class_entry, getThis(), ZEND_STRL("observers"), 0, &observers_tmp); if (Z_TYPE_P(observers) != IS_OBJECT) { php_http_throw(unexpected_val, "Observer storage is corrupted", NULL); return; } - zend_call_method_with_1_params(&observers, NULL, NULL, "detach", &retval, observer); - if (retval) { - zval_ptr_dtor(&retval); - } + ZVAL_UNDEF(&retval); + zend_call_method_with_1_params(observers, NULL, NULL, "detach", &retval, observer); + zval_ptr_dtor(&retval); RETVAL_ZVAL(getThis(), 1, 0); } @@@ -1035,11 -1058,11 +1070,11 @@@ ZEND_BEGIN_ARG_INFO_EX(ai_HttpClient_ge ZEND_END_ARG_INFO(); static PHP_METHOD(HttpClient, getObservers) { - zval *observers; + zval observers_tmp, *observers; php_http_expect(SUCCESS == zend_parse_parameters_none(), invalid_arg, return); - observers = zend_read_property(php_http_client_class_entry, getThis(), ZEND_STRL("observers"), 0 TSRMLS_CC); + observers = zend_read_property(php_http_client_class_entry, getThis(), ZEND_STRL("observers"), 0, &observers_tmp); if (Z_TYPE_P(observers) != IS_OBJECT) { php_http_throw(unexpected_val, "Observer storage is corrupted", NULL); @@@ -1059,17 -1082,17 +1094,17 @@@ static PHP_METHOD(HttpClient, getProgre php_http_message_object_t *req_obj; php_http_client_progress_state_t *progress; - php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &request, php_http_client_request_class_entry), invalid_arg, return); + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "O", &request, php_http_get_client_request_class_entry()), invalid_arg, return); - obj = zend_object_store_get_object(getThis() TSRMLS_CC); - req_obj = zend_object_store_get_object(request TSRMLS_CC); + obj = PHP_HTTP_OBJ(NULL, getThis()); + req_obj = PHP_HTTP_OBJ(NULL, request); php_http_expect(SUCCESS == php_http_client_getopt(obj->client, PHP_HTTP_CLIENT_OPT_PROGRESS_INFO, req_obj->message, &progress), unexpected_val, return); object_init(return_value); add_property_bool(return_value, "started", progress->started); add_property_bool(return_value, "finished", progress->finished); - add_property_string(return_value, "info", STR_PTR(progress->info), 1); + add_property_string(return_value, "info", STR_PTR(progress->info)); add_property_double(return_value, "dltotal", progress->dl.total); add_property_double(return_value, "dlnow", progress->dl.now); add_property_double(return_value, "ultotal", progress->ul.total); @@@ -1086,10 -1109,10 +1121,10 @@@ static PHP_METHOD(HttpClient, getTransf php_http_client_object_t *obj; php_http_message_object_t *req_obj; - php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "O", &request, php_http_client_request_class_entry), invalid_arg, return); + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "O", &request, php_http_get_client_request_class_entry()), invalid_arg, return); - obj = zend_object_store_get_object(getThis() TSRMLS_CC); - req_obj = zend_object_store_get_object(request TSRMLS_CC); + obj = PHP_HTTP_OBJ(NULL, getThis()); + req_obj = PHP_HTTP_OBJ(NULL, request); object_init(return_value); info = HASH_OF(return_value); @@@ -1103,9 -1126,9 +1138,9 @@@ static PHP_METHOD(HttpClient, setOption { zval *opts = NULL; - php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a!/", &opts), invalid_arg, return); + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "|a!/", &opts), invalid_arg, return); - php_http_client_options_set(getThis(), opts TSRMLS_CC); + php_http_client_options_set(getThis(), opts); RETVAL_ZVAL(getThis(), 1, 0); } @@@ -1115,7 -1138,7 +1150,7 @@@ ZEND_END_ARG_INFO() static PHP_METHOD(HttpClient, getOptions) { if (SUCCESS == zend_parse_parameters_none()) { - zval *options = zend_read_property(php_http_client_class_entry, getThis(), ZEND_STRL("options"), 0 TSRMLS_CC); + zval options_tmp, *options = zend_read_property(php_http_client_class_entry, getThis(), ZEND_STRL("options"), 0, &options_tmp); RETVAL_ZVAL(options, 1, 0); } } @@@ -1127,9 -1150,9 +1162,9 @@@ static PHP_METHOD(HttpClient, setSslOpt { zval *opts = NULL; - php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a!/", &opts), invalid_arg, return); + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "|a!/", &opts), invalid_arg, return); - php_http_client_options_set_subr(getThis(), ZEND_STRS("ssl"), opts, 1 TSRMLS_CC); + php_http_client_options_set_subr(getThis(), ZEND_STRL("ssl"), opts, 1); RETVAL_ZVAL(getThis(), 1, 0); } @@@ -1141,9 -1164,9 +1176,9 @@@ static PHP_METHOD(HttpClient, addSslOpt { zval *opts = NULL; - php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a!/", &opts), invalid_arg, return); + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "|a!/", &opts), invalid_arg, return); - php_http_client_options_set_subr(getThis(), ZEND_STRS("ssl"), opts, 0 TSRMLS_CC); + php_http_client_options_set_subr(getThis(), ZEND_STRL("ssl"), opts, 0); RETVAL_ZVAL(getThis(), 1, 0); } @@@ -1153,7 -1176,7 +1188,7 @@@ ZEND_END_ARG_INFO() static PHP_METHOD(HttpClient, getSslOptions) { if (SUCCESS == zend_parse_parameters_none()) { - php_http_client_options_get_subr(getThis(), ZEND_STRS("ssl"), return_value TSRMLS_CC); + php_http_client_options_get_subr(getThis(), ZEND_STRL("ssl"), return_value); } } @@@ -1164,9 -1187,9 +1199,9 @@@ static PHP_METHOD(HttpClient, setCookie { zval *opts = NULL; - php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a!/", &opts), invalid_arg, return); + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "|a!/", &opts), invalid_arg, return); - php_http_client_options_set_subr(getThis(), ZEND_STRS("cookies"), opts, 1 TSRMLS_CC); + php_http_client_options_set_subr(getThis(), ZEND_STRL("cookies"), opts, 1); RETVAL_ZVAL(getThis(), 1, 0); } @@@ -1178,9 -1201,9 +1213,9 @@@ static PHP_METHOD(HttpClient, addCookie { zval *opts = NULL; - php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|a!/", &opts), invalid_arg, return); + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "|a!/", &opts), invalid_arg, return); - php_http_client_options_set_subr(getThis(), ZEND_STRS("cookies"), opts, 0 TSRMLS_CC); + php_http_client_options_set_subr(getThis(), ZEND_STRL("cookies"), opts, 0); RETVAL_ZVAL(getThis(), 1, 0); } @@@ -1190,17 -1213,16 +1225,17 @@@ ZEND_END_ARG_INFO() static PHP_METHOD(HttpClient, getCookies) { if (SUCCESS == zend_parse_parameters_none()) { - php_http_client_options_get_subr(getThis(), ZEND_STRS("cookies"), return_value TSRMLS_CC); + php_http_client_options_get_subr(getThis(), ZEND_STRL("cookies"), return_value); } } ZEND_BEGIN_ARG_INFO_EX(ai_HttpClient_getAvailableDrivers, 0, 0, 0) ZEND_END_ARG_INFO(); -static PHP_METHOD(HttpClient, getAvailableDrivers) { +static PHP_METHOD(HttpClient, getAvailableDrivers) +{ if (SUCCESS == zend_parse_parameters_none()) { array_init(return_value); - php_http_client_driver_list(Z_ARRVAL_P(return_value) TSRMLS_CC); + php_http_client_driver_list(Z_ARRVAL_P(return_value)); } } @@@ -1209,7 -1231,7 +1244,7 @@@ ZEND_END_ARG_INFO() static PHP_METHOD(HttpClient, getAvailableOptions) { if (SUCCESS == zend_parse_parameters_none()) { - php_http_client_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_http_client_object_t *obj = PHP_HTTP_OBJ(NULL, getThis()); array_init(return_value); php_http_client_getopt(obj->client, PHP_HTTP_CLIENT_OPT_AVAILABLE_OPTIONS, NULL, &Z_ARRVAL_P(return_value)); @@@ -1221,13 -1243,45 +1256,45 @@@ ZEND_END_ARG_INFO() static PHP_METHOD(HttpClient, getAvailableConfiguration) { if (SUCCESS == zend_parse_parameters_none()) { - php_http_client_object_t *obj = zend_object_store_get_object(getThis() TSRMLS_CC); + php_http_client_object_t *obj = PHP_HTTP_OBJ(NULL, getThis()); array_init(return_value); php_http_client_getopt(obj->client, PHP_HTTP_CLIENT_OPT_AVAILABLE_CONFIGURATION, NULL, &Z_ARRVAL_P(return_value)); } } + ZEND_BEGIN_ARG_INFO_EX(ai_HttpClient_setDebug, 0, 0, 1) + ZEND_ARG_TYPE_INFO(0, callback, IS_CALLABLE, 1) + ZEND_END_ARG_INFO(); + static PHP_METHOD(HttpClient, setDebug) + { + zend_fcall_info fci; + zend_fcall_info_cache fcc; + php_http_client_object_t *client_obj; + + fci.size = 0; - php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|f", &fci, &fcc), invalid_arg, return); ++ php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "|f", &fci, &fcc), invalid_arg, return); + - client_obj = zend_object_store_get_object(getThis() TSRMLS_CC); ++ client_obj = PHP_HTTP_OBJ(NULL, getThis()); + + if (client_obj->debug.fci.size > 0) { + zval_ptr_dtor(&client_obj->debug.fci.function_name); + client_obj->debug.fci.size = 0; + } + if (fci.size > 0) { + memcpy(&client_obj->debug.fci, &fci, sizeof(fci)); + memcpy(&client_obj->debug.fcc, &fcc, sizeof(fcc)); - Z_ADDREF_P(fci.function_name); ++ Z_ADDREF_P(&fci.function_name); + client_obj->client->callback.debug.func = handle_debug; + client_obj->client->callback.debug.arg = client_obj; + } else { + client_obj->client->callback.debug.func = NULL; + client_obj->client->callback.debug.arg = NULL; + } + + RETVAL_ZVAL(getThis(), 1, 0); + } + static zend_function_entry php_http_client_methods[] = { PHP_ME(HttpClient, __construct, ai_HttpClient_construct, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR) PHP_ME(HttpClient, reset, ai_HttpClient_reset, ZEND_ACC_PUBLIC) @@@ -1260,6 -1314,7 +1327,7 @@@ PHP_ME(HttpClient, getAvailableDrivers, ai_HttpClient_getAvailableDrivers, ZEND_ACC_PUBLIC|ZEND_ACC_STATIC) PHP_ME(HttpClient, getAvailableOptions, ai_HttpClient_getAvailableOptions, ZEND_ACC_PUBLIC) PHP_ME(HttpClient, getAvailableConfiguration, ai_HttpClient_getAvailableConfiguration, ZEND_ACC_PUBLIC) + PHP_ME(HttpClient, setDebug, ai_HttpClient_setDebug, ZEND_ACC_PUBLIC) EMPTY_FUNCTION_ENTRY }; @@@ -1268,20 -1323,24 +1336,27 @@@ PHP_MINIT_FUNCTION(http_client zend_class_entry ce = {0}; INIT_NS_CLASS_ENTRY(ce, "http", "Client", php_http_client_methods); - php_http_client_class_entry = zend_register_internal_class_ex(&ce, NULL, NULL TSRMLS_CC); + php_http_client_class_entry = zend_register_internal_class_ex(&ce, NULL); php_http_client_class_entry->create_object = php_http_client_object_new; - zend_class_implements(php_http_client_class_entry TSRMLS_CC, 2, spl_ce_SplSubject, spl_ce_Countable); + zend_class_implements(php_http_client_class_entry, 2, spl_ce_SplSubject, spl_ce_Countable); memcpy(&php_http_client_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); + php_http_client_object_handlers.offset = XtOffsetOf(php_http_client_object_t, zo); + php_http_client_object_handlers.free_obj = php_http_client_object_free; php_http_client_object_handlers.clone_obj = NULL; - zend_declare_property_null(php_http_client_class_entry, ZEND_STRL("observers"), ZEND_ACC_PRIVATE TSRMLS_CC); - zend_declare_property_null(php_http_client_class_entry, ZEND_STRL("options"), ZEND_ACC_PROTECTED TSRMLS_CC); - zend_declare_property_null(php_http_client_class_entry, ZEND_STRL("history"), ZEND_ACC_PROTECTED TSRMLS_CC); - zend_declare_property_bool(php_http_client_class_entry, ZEND_STRL("recordHistory"), 0, ZEND_ACC_PUBLIC TSRMLS_CC); - - zend_declare_class_constant_long(php_http_client_class_entry, ZEND_STRL("DEBUG_INFO"), PHP_HTTP_CLIENT_DEBUG_INFO TSRMLS_CC); - zend_declare_class_constant_long(php_http_client_class_entry, ZEND_STRL("DEBUG_IN"), PHP_HTTP_CLIENT_DEBUG_IN TSRMLS_CC); - zend_declare_class_constant_long(php_http_client_class_entry, ZEND_STRL("DEBUG_OUT"), PHP_HTTP_CLIENT_DEBUG_OUT TSRMLS_CC); - zend_declare_class_constant_long(php_http_client_class_entry, ZEND_STRL("DEBUG_HEADER"), PHP_HTTP_CLIENT_DEBUG_HEADER TSRMLS_CC); - zend_declare_class_constant_long(php_http_client_class_entry, ZEND_STRL("DEBUG_BODY"), PHP_HTTP_CLIENT_DEBUG_BODY TSRMLS_CC); - zend_declare_class_constant_long(php_http_client_class_entry, ZEND_STRL("DEBUG_SSL"), PHP_HTTP_CLIENT_DEBUG_SSL TSRMLS_CC); - - zend_hash_init(&php_http_client_drivers, 2, NULL, NULL, 1); + php_http_client_object_handlers.get_gc = php_http_client_object_get_gc; + zend_declare_property_null(php_http_client_class_entry, ZEND_STRL("observers"), ZEND_ACC_PRIVATE); + zend_declare_property_null(php_http_client_class_entry, ZEND_STRL("options"), ZEND_ACC_PROTECTED); + zend_declare_property_null(php_http_client_class_entry, ZEND_STRL("history"), ZEND_ACC_PROTECTED); + zend_declare_property_bool(php_http_client_class_entry, ZEND_STRL("recordHistory"), 0, ZEND_ACC_PUBLIC); + ++ zend_declare_class_constant_long(php_http_client_class_entry, ZEND_STRL("DEBUG_INFO"), PHP_HTTP_CLIENT_DEBUG_INFO); ++ zend_declare_class_constant_long(php_http_client_class_entry, ZEND_STRL("DEBUG_IN"), PHP_HTTP_CLIENT_DEBUG_IN); ++ zend_declare_class_constant_long(php_http_client_class_entry, ZEND_STRL("DEBUG_OUT"), PHP_HTTP_CLIENT_DEBUG_OUT); ++ zend_declare_class_constant_long(php_http_client_class_entry, ZEND_STRL("DEBUG_HEADER"), PHP_HTTP_CLIENT_DEBUG_HEADER); ++ zend_declare_class_constant_long(php_http_client_class_entry, ZEND_STRL("DEBUG_BODY"), PHP_HTTP_CLIENT_DEBUG_BODY); ++ zend_declare_class_constant_long(php_http_client_class_entry, ZEND_STRL("DEBUG_SSL"), PHP_HTTP_CLIENT_DEBUG_SSL); ++ + zend_hash_init(&php_http_client_drivers, 2, NULL, php_http_client_driver_hash_dtor, 1); return SUCCESS; } diff --combined src/php_http_client.h index c206ccd,ecaa304..08743e6 --- a/src/php_http_client.h +++ b/src/php_http_client.h @@@ -65,14 -65,13 +65,14 @@@ typedef struct php_http_client_ops } php_http_client_ops_t; typedef struct php_http_client_driver { - const char *name_str; - size_t name_len; + zend_string *driver_name; + zend_string *client_name; + zend_string *request_name; php_http_client_ops_t *client_ops; } php_http_client_driver_t; PHP_HTTP_API ZEND_RESULT_CODE php_http_client_driver_add(php_http_client_driver_t *driver); -PHP_HTTP_API ZEND_RESULT_CODE php_http_client_driver_get(const char *name_str, size_t name_len, php_http_client_driver_t *driver); +PHP_HTTP_API php_http_client_driver_t *php_http_client_driver_get(zend_string *name); typedef struct php_http_client_progress_state { struct { @@@ -90,6 -89,14 +90,14 @@@ typedef ZEND_RESULT_CODE (*php_http_client_response_callback_t)(void *arg, struct php_http_client *client, php_http_client_enqueue_t *e, php_http_message_t **response); typedef void (*php_http_client_progress_callback_t)(void *arg, struct php_http_client *client, php_http_client_enqueue_t *e, php_http_client_progress_state_t *state); + typedef void (*php_http_client_debug_callback_t)(void *arg, struct php_http_client *client, php_http_client_enqueue_t *e, unsigned type, const char *data, size_t size); + + #define PHP_HTTP_CLIENT_DEBUG_INFO 0x00 + #define PHP_HTTP_CLIENT_DEBUG_IN 0x01 + #define PHP_HTTP_CLIENT_DEBUG_OUT 0x02 + #define PHP_HTTP_CLIENT_DEBUG_HEADER 0x10 + #define PHP_HTTP_CLIENT_DEBUG_BODY 0x20 + #define PHP_HTTP_CLIENT_DEBUG_SSL 0x40 typedef struct php_http_client { void *ctx; @@@ -105,24 -112,36 +113,32 @@@ php_http_client_progress_callback_t func; void *arg; } progress; + struct { + php_http_client_debug_callback_t func; + void *arg; + } debug; } callback; zend_llist requests; zend_llist responses; - -#ifdef ZTS - void ***ts; -#endif } php_http_client_t; -PHP_HTTP_API zend_class_entry *php_http_client_class_entry; +PHP_HTTP_API zend_class_entry *php_http_client_get_class_entry(); typedef struct php_http_client_object { - zend_object zo; - zend_object_value zv; php_http_client_t *client; - long iterator; php_http_object_method_t *update; php_http_object_method_t notify; + struct { + zend_fcall_info fci; + zend_fcall_info_cache fcc; + } debug; + long iterator; + zval *gc; + zend_object zo; } php_http_client_object_t; -PHP_HTTP_API php_http_client_t *php_http_client_init(php_http_client_t *h, php_http_client_ops_t *ops, php_resource_factory_t *rf, void *init_arg TSRMLS_DC); +PHP_HTTP_API php_http_client_t *php_http_client_init(php_http_client_t *h, php_http_client_ops_t *ops, php_resource_factory_t *rf, void *init_arg); PHP_HTTP_API php_http_client_t *php_http_client_copy(php_http_client_t *from, php_http_client_t *to); PHP_HTTP_API void php_http_client_dtor(php_http_client_t *h); PHP_HTTP_API void php_http_client_free(php_http_client_t **h); diff --combined src/php_http_client_curl.c index be17832,18d75d7..be04be8 --- a/src/php_http_client_curl.c +++ b/src/php_http_client_curl.c @@@ -45,15 -45,15 +45,15 @@@ typedef struct php_http_client_curl_han php_http_buffer_t cookies; php_http_buffer_t ranges; - long redirects; - unsigned range_request:1; - unsigned encode_cookies:1; - struct { uint count; double delay; } retry; + long redirects; + unsigned range_request:1; + unsigned encode_cookies:1; + } options; } php_http_client_curl_handler_t; @@@ -79,7 -79,7 +79,7 @@@ static inline php_http_curle_storage_t return st; } -static void *php_http_curle_ctor(void *opaque, void *init_arg TSRMLS_DC) +static void *php_http_curle_ctor(void *opaque, void *init_arg) { void *ch; @@@ -90,7 -90,7 +90,7 @@@ return NULL; } -static void *php_http_curle_copy(void *opaque, void *handle TSRMLS_DC) +static void *php_http_curle_copy(void *opaque, void *handle) { void *ch; @@@ -102,7 -102,7 +102,7 @@@ return NULL; } -static void php_http_curle_dtor(void *opaque, void *handle TSRMLS_DC) +static void php_http_curle_dtor(void *opaque, void *handle) { php_http_curle_storage_t *st = php_http_curle_get_storage(handle); @@@ -125,7 -125,7 +125,7 @@@ static php_resource_factory_ops_t php_h php_http_curle_dtor }; -static void *php_http_curlm_ctor(void *opaque, void *init_arg TSRMLS_DC) +static void *php_http_curlm_ctor(void *opaque, void *init_arg) { php_http_client_curl_handle_t *curl = calloc(1, sizeof(*curl)); @@@ -143,7 -143,7 +143,7 @@@ return curl; } -static void php_http_curlm_dtor(void *opaque, void *handle TSRMLS_DC) +static void php_http_curlm_dtor(void *opaque, void *handle) { php_http_client_curl_handle_t *curl = handle; @@@ -162,10 -162,15 +162,10 @@@ static php_resource_factory_ops_t php_h static size_t php_http_curle_read_callback(void *data, size_t len, size_t n, void *ctx) { - php_http_message_body_t *body = ctx; - - if (body && body->stream_id) { - php_stream *s = php_http_message_body_stream(body); + php_stream *s = php_http_message_body_stream(ctx); - if (s) { - TSRMLS_FETCH_FROM_CTX(body->ts); - return php_stream_read(s, data, len * n); - } else abort(); + if (s) { + return php_stream_read(s, data, len * n); } return 0; } @@@ -202,6 -207,7 +202,6 @@@ static int php_http_curle_progress_call static int php_http_curle_seek_callback(void *userdata, curl_off_t offset, int origin) { php_http_message_body_t *body = userdata; - TSRMLS_FETCH_FROM_CTX(body->ts); if (!body) { return 1; @@@ -215,6 -221,7 +215,7 @@@ static int php_http_curle_raw_callback(CURL *ch, curl_infotype type, char *data, size_t length, void *ctx) { php_http_client_curl_handler_t *h = ctx; + unsigned utype = PHP_HTTP_CLIENT_DEBUG_INFO; /* catch progress */ switch (type) { @@@ -258,20 -265,43 +259,43 @@@ h->client->callback.progress.func(h->client->callback.progress.arg, h->client, &h->queue, &h->progress); } break; + case CURLINFO_HEADER_OUT: - case CURLINFO_DATA_OUT: + utype |= PHP_HTTP_CLIENT_DEBUG_HEADER; + goto data_out; + case CURLINFO_SSL_DATA_OUT: + utype |= PHP_HTTP_CLIENT_DEBUG_SSL; + goto data_out; + + case CURLINFO_DATA_OUT: + data_out: + utype |= PHP_HTTP_CLIENT_DEBUG_OUT; h->progress.info = "send"; break; + case CURLINFO_HEADER_IN: - case CURLINFO_DATA_IN: + utype |= PHP_HTTP_CLIENT_DEBUG_HEADER; + goto data_in; + case CURLINFO_SSL_DATA_IN: + utype |= PHP_HTTP_CLIENT_DEBUG_SSL; + goto data_in; + + case CURLINFO_DATA_IN: + data_in: + utype |= PHP_HTTP_CLIENT_DEBUG_IN; h->progress.info = "receive"; break; + default: break; } + if (h->client->callback.debug.func) { + h->client->callback.debug.func(h->client->callback.debug.arg, h->client, &h->queue, utype, data, length); + } + #if 0 /* debug */ _dpf(type, data, length); @@@ -296,161 -326,131 +320,161 @@@ static int php_http_curle_body_callback static ZEND_RESULT_CODE php_http_curle_get_info(CURL *ch, HashTable *info) { - char *c; - long l; - double d; - struct curl_slist *s, *p; - zval *subarray, array; - INIT_PZVAL_ARRAY(&array, info); + char *c = NULL; + long l = 0; + double d = 0; + struct curl_slist *s = NULL, *p = NULL; + zval tmp = {{0}}; /* BEGIN::CURLINFO */ if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_EFFECTIVE_URL, &c)) { - add_assoc_string_ex(&array, "effective_url", sizeof("effective_url"), c ? c : "", 1); + ZVAL_STRING(&tmp, STR_PTR(c)); + zend_hash_str_update(info, "effective_url", lenof("effective_url"), &tmp); } if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_RESPONSE_CODE, &l)) { - add_assoc_long_ex(&array, "response_code", sizeof("response_code"), l); + ZVAL_LONG(&tmp, l); + zend_hash_str_update(info, "response_code", lenof("response_code"), &tmp); } if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_TOTAL_TIME, &d)) { - add_assoc_double_ex(&array, "total_time", sizeof("total_time"), d); + ZVAL_DOUBLE(&tmp, d); + zend_hash_str_update(info, "total_time", lenof("total_time"), &tmp); } if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_NAMELOOKUP_TIME, &d)) { - add_assoc_double_ex(&array, "namelookup_time", sizeof("namelookup_time"), d); + ZVAL_DOUBLE(&tmp, d); + zend_hash_str_update(info, "namelookup_time", lenof("namelookup_time"), &tmp); } if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_CONNECT_TIME, &d)) { - add_assoc_double_ex(&array, "connect_time", sizeof("connect_time"), d); + ZVAL_DOUBLE(&tmp, d); + zend_hash_str_update(info, "connect_time", lenof("connect_time"), &tmp); } if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_PRETRANSFER_TIME, &d)) { - add_assoc_double_ex(&array, "pretransfer_time", sizeof("pretransfer_time"), d); + ZVAL_DOUBLE(&tmp, d); + zend_hash_str_update(info, "pretransfer_time", lenof("pretransfer_time"), &tmp); } if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_SIZE_UPLOAD, &d)) { - add_assoc_double_ex(&array, "size_upload", sizeof("size_upload"), d); + ZVAL_DOUBLE(&tmp, d); + zend_hash_str_update(info, "size_upload", lenof("size_upload"), &tmp); } if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_SIZE_DOWNLOAD, &d)) { - add_assoc_double_ex(&array, "size_download", sizeof("size_download"), d); + ZVAL_DOUBLE(&tmp, d); + zend_hash_str_update(info, "size_download", lenof("size_download"), &tmp); } if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_SPEED_DOWNLOAD, &d)) { - add_assoc_double_ex(&array, "speed_download", sizeof("speed_download"), d); + ZVAL_DOUBLE(&tmp, d); + zend_hash_str_update(info, "speed_download", lenof("speed_download"), &tmp); } if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_SPEED_UPLOAD, &d)) { - add_assoc_double_ex(&array, "speed_upload", sizeof("speed_upload"), d); + ZVAL_DOUBLE(&tmp, d); + zend_hash_str_update(info, "speed_upload", lenof("speed_upload"), &tmp); } if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_HEADER_SIZE, &l)) { - add_assoc_long_ex(&array, "header_size", sizeof("header_size"), l); + ZVAL_LONG(&tmp, l); + zend_hash_str_update(info, "header_size", lenof("header_size"), &tmp); } if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_REQUEST_SIZE, &l)) { - add_assoc_long_ex(&array, "request_size", sizeof("request_size"), l); + ZVAL_LONG(&tmp, l); + zend_hash_str_update(info, "request_size", lenof("request_size"), &tmp); } if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_SSL_VERIFYRESULT, &l)) { - add_assoc_long_ex(&array, "ssl_verifyresult", sizeof("ssl_verifyresult"), l); + ZVAL_LONG(&tmp, l); + zend_hash_str_update(info, "ssl_verifyresult", lenof("ssl_verifyresult"), &tmp); } if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_FILETIME, &l)) { - add_assoc_long_ex(&array, "filetime", sizeof("filetime"), l); + ZVAL_LONG(&tmp, l); + zend_hash_str_update(info, "filetime", lenof("filetime"), &tmp); } if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &d)) { - add_assoc_double_ex(&array, "content_length_download", sizeof("content_length_download"), d); + ZVAL_DOUBLE(&tmp, d); + zend_hash_str_update(info, "content_length_download", lenof("content_length_download"), &tmp); } if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_CONTENT_LENGTH_UPLOAD, &d)) { - add_assoc_double_ex(&array, "content_length_upload", sizeof("content_length_upload"), d); + ZVAL_DOUBLE(&tmp, d); + zend_hash_str_update(info, "content_length_upload", lenof("content_length_upload"), &tmp); } if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_STARTTRANSFER_TIME, &d)) { - add_assoc_double_ex(&array, "starttransfer_time", sizeof("starttransfer_time"), d); + ZVAL_DOUBLE(&tmp, d); + zend_hash_str_update(info, "starttransfer_time", lenof("starttransfer_time"), &tmp); } if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_CONTENT_TYPE, &c)) { - add_assoc_string_ex(&array, "content_type", sizeof("content_type"), c ? c : "", 1); + ZVAL_STRING(&tmp, STR_PTR(c)); + zend_hash_str_update(info, "content_type", lenof("content_type"), &tmp); } if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_REDIRECT_TIME, &d)) { - add_assoc_double_ex(&array, "redirect_time", sizeof("redirect_time"), d); + ZVAL_DOUBLE(&tmp, d); + zend_hash_str_update(info, "redirect_time", lenof("redirect_time"), &tmp); } if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_REDIRECT_COUNT, &l)) { - add_assoc_long_ex(&array, "redirect_count", sizeof("redirect_count"), l); + ZVAL_LONG(&tmp, l); + zend_hash_str_update(info, "redirect_count", lenof("redirect_count"), &tmp); } if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_HTTP_CONNECTCODE, &l)) { - add_assoc_long_ex(&array, "connect_code", sizeof("connect_code"), l); + ZVAL_LONG(&tmp, l); + zend_hash_str_update(info, "connect_code", lenof("connect_code"), &tmp); } if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_HTTPAUTH_AVAIL, &l)) { - add_assoc_long_ex(&array, "httpauth_avail", sizeof("httpauth_avail"), l); + ZVAL_LONG(&tmp, l); + zend_hash_str_update(info, "httpauth_avail", lenof("httpauth_avail"), &tmp); } if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_PROXYAUTH_AVAIL, &l)) { - add_assoc_long_ex(&array, "proxyauth_avail", sizeof("proxyauth_avail"), l); + ZVAL_LONG(&tmp, l); + zend_hash_str_update(info, "proxyauth_avail", lenof("proxyauth_avail"), &tmp); } if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_OS_ERRNO, &l)) { - add_assoc_long_ex(&array, "os_errno", sizeof("os_errno"), l); + ZVAL_LONG(&tmp, l); + zend_hash_str_update(info, "os_errno", lenof("os_errno"), &tmp); } if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_NUM_CONNECTS, &l)) { - add_assoc_long_ex(&array, "num_connects", sizeof("num_connects"), l); + ZVAL_LONG(&tmp, l); + zend_hash_str_update(info, "num_connects", lenof("num_connects"), &tmp); } if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_SSL_ENGINES, &s)) { - MAKE_STD_ZVAL(subarray); - array_init(subarray); + array_init(&tmp); for (p = s; p; p = p->next) { if (p->data) { - add_next_index_string(subarray, p->data, 1); + add_next_index_string(&tmp, p->data); } } - add_assoc_zval_ex(&array, "ssl_engines", sizeof("ssl_engines"), subarray); + zend_hash_str_update(info, "ssl_engines", lenof("ssl_engines"), &tmp); curl_slist_free_all(s); } if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_REDIRECT_URL, &c)) { - add_assoc_string_ex(&array, "redirect_url", sizeof("redirect_url"), c ? c : "", 1); + ZVAL_STRING(&tmp, STR_PTR(c)); + zend_hash_str_update(info, "redirect_url", lenof("redirect_url"), &tmp); } #if PHP_HTTP_CURL_VERSION(7,19,0) if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_PRIMARY_IP, &c)) { - add_assoc_string_ex(&array, "primary_ip", sizeof("primary_ip"), c ? c : "", 1); + ZVAL_STRING(&tmp, STR_PTR(c)); + zend_hash_str_update(info, "primary_ip", lenof("primary_ip"), &tmp); } #endif #if PHP_HTTP_CURL_VERSION(7,19,0) if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_APPCONNECT_TIME, &d)) { - add_assoc_double_ex(&array, "appconnect_time", sizeof("appconnect_time"), d); + ZVAL_DOUBLE(&tmp, d); + zend_hash_str_update(info, "appconnect_time", lenof("appconnect_time"), &tmp); } #endif #if PHP_HTTP_CURL_VERSION(7,19,4) if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_CONDITION_UNMET, &l)) { - add_assoc_long_ex(&array, "condition_unmet", sizeof("condition_unmet"), l); + ZVAL_LONG(&tmp, l); + zend_hash_str_update(info, "condition_unmet", lenof("condition_unmet"), &tmp); } #endif #if PHP_HTTP_CURL_VERSION(7,21,0) if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_PRIMARY_PORT, &l)) { - add_assoc_long_ex(&array, "primary_port", sizeof("primary_port"), l); + ZVAL_LONG(&tmp, l); + zend_hash_str_update(info, "primary_port", lenof("primary_port"), &tmp); } #endif #if PHP_HTTP_CURL_VERSION(7,21,0) if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_LOCAL_IP, &c)) { - add_assoc_string_ex(&array, "local_ip", sizeof("local_ip"), c ? c : "", 1); + ZVAL_STRING(&tmp, STR_PTR(c)); + zend_hash_str_update(info, "local_ip", lenof("local_ip"), &tmp); } #endif #if PHP_HTTP_CURL_VERSION(7,21,0) if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_LOCAL_PORT, &l)) { - add_assoc_long_ex(&array, "local_port", sizeof("local_port"), l); + ZVAL_LONG(&tmp, l); + zend_hash_str_update(info, "local_port", lenof("local_port"), &tmp); } #endif @@@ -458,14 -458,16 +482,14 @@@ #if PHP_HTTP_CURL_VERSION(7,34,0) { - zval *ti_array; + zval ti_array, subarray; struct curl_tlssessioninfo *ti; if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_TLS_SESSION, &ti)) { - const char *backend; + char *backend; - MAKE_STD_ZVAL(subarray); - ZVAL_NULL(subarray); - MAKE_STD_ZVAL(ti_array); - array_init(ti_array); + ZVAL_NULL(&subarray); + array_init(&ti_array); switch (ti->backend) { case CURLSSLBACKEND_NONE: @@@ -477,13 -479,13 +501,13 @@@ { SSL_CTX *ctx = ti->internals; - array_init(subarray); - add_assoc_long_ex(subarray, ZEND_STRS("number"), SSL_CTX_sess_number(ctx)); - add_assoc_long_ex(subarray, ZEND_STRS("connect"), SSL_CTX_sess_connect(ctx)); - add_assoc_long_ex(subarray, ZEND_STRS("connect_good"), SSL_CTX_sess_connect_good(ctx)); - add_assoc_long_ex(subarray, ZEND_STRS("connect_renegotiate"), SSL_CTX_sess_connect_renegotiate(ctx)); - add_assoc_long_ex(subarray, ZEND_STRS("hits"), SSL_CTX_sess_hits(ctx)); - add_assoc_long_ex(subarray, ZEND_STRS("cache_full"), SSL_CTX_sess_cache_full(ctx)); + array_init(&subarray); + add_assoc_long_ex(&subarray, ZEND_STRL("number"), SSL_CTX_sess_number(ctx)); + add_assoc_long_ex(&subarray, ZEND_STRL("connect"), SSL_CTX_sess_connect(ctx)); + add_assoc_long_ex(&subarray, ZEND_STRL("connect_good"), SSL_CTX_sess_connect_good(ctx)); + add_assoc_long_ex(&subarray, ZEND_STRL("connect_renegotiate"), SSL_CTX_sess_connect_renegotiate(ctx)); + add_assoc_long_ex(&subarray, ZEND_STRL("hits"), SSL_CTX_sess_hits(ctx)); + add_assoc_long_ex(&subarray, ZEND_STRL("cache_full"), SSL_CTX_sess_cache_full(ctx)); } #endif break; @@@ -494,12 -496,12 +518,12 @@@ gnutls_session_t sess = ti->internals; char *desc; - array_init(subarray); + array_init(&subarray); if ((desc = gnutls_session_get_desc(sess))) { - add_assoc_string_ex(subarray, ZEND_STRS("desc"), desc, 1); + add_assoc_string_ex(&subarray, ZEND_STRL("desc"), desc); gnutls_free(desc); } - add_assoc_bool_ex(subarray, ZEND_STRS("resumed"), gnutls_session_is_resumed(sess)); + add_assoc_bool_ex(&subarray, ZEND_STRL("resumed"), gnutls_session_is_resumed(sess)); } #endif break; @@@ -530,9 -532,9 +554,9 @@@ default: backend = "unknown"; } - add_assoc_string_ex(ti_array, ZEND_STRS("backend"), estrdup(backend), 0); - add_assoc_zval_ex(ti_array, ZEND_STRS("internals"), subarray); - add_assoc_zval_ex(&array, "tls_session", sizeof("tls_session"), ti_array); + add_assoc_string_ex(&ti_array, ZEND_STRL("backend"), backend); + add_assoc_zval_ex(&ti_array, ZEND_STRL("internals"), &subarray); + zend_hash_str_update(info, "tls_session", lenof("tls_session"), &ti_array); } } #endif @@@ -540,41 -542,41 +564,41 @@@ #if (PHP_HTTP_CURL_VERSION(7,19,1) && defined(PHP_HTTP_HAVE_OPENSSL)) || (PHP_HTTP_CURL_VERSION(7,34,0) && defined(PHP_HTTP_HAVE_NSS)) || (PHP_HTTP_CURL_VERSION(7,42,0) && defined(PHP_HTTP_HAVE_GNUTLS)) || (PHP_HTTP_CURL_VERSION(7,39,0) && defined(PHP_HTTP_HAVE_GSKIT)) { int i; - zval *ci_array; + zval ci_array, subarray; struct curl_certinfo *ci; char *colon, *keyname; if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_CERTINFO, &ci)) { - MAKE_STD_ZVAL(ci_array); - array_init(ci_array); + array_init(&ci_array); for (i = 0; i < ci->num_of_certs; ++i) { s = ci->certinfo[i]; - MAKE_STD_ZVAL(subarray); - array_init(subarray); + array_init(&subarray); for (p = s; p; p = p->next) { if (p->data) { if ((colon = strchr(p->data, ':'))) { keyname = estrndup(p->data, colon - p->data); - add_assoc_string_ex(subarray, keyname, colon - p->data + 1, colon + 1, 1); + add_assoc_string_ex(&subarray, keyname, colon - p->data, colon + 1); efree(keyname); } else { - add_next_index_string(subarray, p->data, 1); + add_next_index_string(&subarray, p->data); } } } - add_next_index_zval(ci_array, subarray); + add_next_index_zval(&ci_array, &subarray); } - add_assoc_zval_ex(&array, "certinfo", sizeof("certinfo"), ci_array); + zend_hash_str_update(info, "certinfo", lenof("certinfo"), &ci_array); } } #endif { php_http_curle_storage_t *st = php_http_curle_get_storage(ch); - add_assoc_long_ex(&array, "curlcode", sizeof("curlcode"), st->errorcode); - add_assoc_string_ex(&array, "error", sizeof("error"), st->errorbuffer, 1); + ZVAL_LONG(&tmp, st->errorcode); + zend_hash_str_update(info, "curlcode", lenof("curlcode"), &tmp); + ZVAL_STRING(&tmp, st->errorbuffer); + zend_hash_str_update(info, "error", lenof("error"), &tmp); } return SUCCESS; @@@ -585,14 -587,14 +609,14 @@@ static int compare_queue(php_http_clien return handle == ((php_http_client_curl_handler_t *) e->opaque)->handle; } -static php_http_message_t *php_http_curlm_responseparser(php_http_client_curl_handler_t *h TSRMLS_DC) +static php_http_message_t *php_http_curlm_responseparser(php_http_client_curl_handler_t *h) { php_http_message_t *response; php_http_header_parser_t parser; - zval *zh; + zval *zh, tmp; - response = php_http_message_init(NULL, 0, h->response.body TSRMLS_CC); - php_http_header_parser_init(&parser TSRMLS_CC); + response = php_http_message_init(NULL, 0, h->response.body); + php_http_header_parser_init(&parser); while (h->response.headers.used) { php_http_header_parser_state_t st = php_http_header_parser_parse(&parser, &h->response.headers, PHP_HTTP_HEADER_PARSER_CLEANUP, &response->hdrs, @@@ -617,24 -619,20 +641,24 @@@ php_http_message_body_addref(h->response.body); /* let's update the response headers */ - if ((zh = php_http_message_header(response, ZEND_STRL("Content-Length"), 1))) { - zend_hash_update(&response->hdrs, "X-Original-Content-Length", sizeof("X-Original-Content-Length"), &zh, sizeof(zval *), NULL); + if ((zh = php_http_message_header(response, ZEND_STRL("Content-Length")))) { + ZVAL_COPY(&tmp, zh); + zend_hash_str_update(&response->hdrs, "X-Original-Content-Length", lenof("X-Original-Content-Length"), &tmp); } - if ((zh = php_http_message_header(response, ZEND_STRL("Transfer-Encoding"), 0))) { - zend_hash_update(&response->hdrs, "X-Original-Transfer-Encoding", sizeof("X-Original-Transfer-Encoding"), (void *) &zh, sizeof(zval *), NULL); - zend_hash_del(&response->hdrs, "Transfer-Encoding", sizeof("Transfer-Encoding")); + if ((zh = php_http_message_header(response, ZEND_STRL("Transfer-Encoding")))) { + ZVAL_COPY(&tmp, zh); + zend_hash_str_del(&response->hdrs, "Transfer-Encoding", lenof("Transfer-Encoding")); + zend_hash_str_update(&response->hdrs, "X-Original-Transfer-Encoding", lenof("X-Original-Transfer-Encoding"), &tmp); } - if ((zh = php_http_message_header(response, ZEND_STRL("Content-Range"), 0))) { - zend_hash_update(&response->hdrs, "X-Original-Content-Range", sizeof("X-Original-Content-Range"), &zh, sizeof(zval *), NULL); - zend_hash_del(&response->hdrs, "Content-Range", sizeof("Content-Range")); + if ((zh = php_http_message_header(response, ZEND_STRL("Content-Range")))) { + ZVAL_COPY(&tmp, zh); + zend_hash_str_del(&response->hdrs, "Content-Range", lenof("Content-Range")); + zend_hash_str_update(&response->hdrs, "X-Original-Content-Range", lenof("X-Original-Content-Range"), &tmp); } - if ((zh = php_http_message_header(response, ZEND_STRL("Content-Encoding"), 0))) { - zend_hash_update(&response->hdrs, "X-Original-Content-Encoding", sizeof("X-Original-Content-Encoding"), &zh, sizeof(zval *), NULL); - zend_hash_del(&response->hdrs, "Content-Encoding", sizeof("Content-Encoding")); + if ((zh = php_http_message_header(response, ZEND_STRL("Content-Encoding")))) { + ZVAL_COPY(&tmp, zh); + zend_hash_str_del(&response->hdrs, "Content-Encoding", lenof("Content-Encoding")); + zend_hash_str_update(&response->hdrs, "X-Original-Content-Encoding", lenof("X-Original-Content-Encoding"), &tmp); } php_http_message_update_headers(response); @@@ -647,6 -645,7 +671,6 @@@ void php_http_client_curl_responsehandl php_http_curle_storage_t *st, *err = NULL; php_http_client_enqueue_t *enqueue; php_http_client_curl_t *curl = context->ctx; - TSRMLS_FETCH_FROM_CTX(context->ts); do { CURLMsg *msg = curl_multi_info_read(curl->handle->multi, &remaining); @@@ -669,7 -668,7 +693,7 @@@ if ((enqueue = php_http_client_enqueued(context, msg->easy_handle, compare_queue))) { php_http_client_curl_handler_t *handler = enqueue->opaque; - php_http_message_t *response = php_http_curlm_responseparser(handler TSRMLS_CC); + php_http_message_t *response = php_http_curlm_responseparser(handler); if (response) { context->callback.response.func(context->callback.response.arg, context, &handler->queue, &response); @@@ -683,7 -682,7 +707,7 @@@ int i = 0; do { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s; %s (%s)", curl_easy_strerror(err[i].errorcode), err[i].errorbuffer, STR_PTR(err[i].url)); + php_error_docref(NULL, E_WARNING, "%s; %s (%s)", curl_easy_strerror(err[i].errorcode), err[i].errorbuffer, STR_PTR(err[i].url)); if (err[i].url) { efree(err[i].url); } @@@ -697,6 -696,7 +721,6 @@@ void php_http_client_curl_loop(php_http { CURLMcode rc; php_http_client_curl_t *curl = client->ctx; - TSRMLS_FETCH_FROM_CTX(client->ts); #if DBG_EVENTS fprintf(stderr, "H"); @@@ -707,7 -707,7 +731,7 @@@ } while (CURLM_CALL_MULTI_PERFORM == rc); if (CURLM_OK != rc) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", curl_multi_strerror(rc)); + php_error_docref(NULL, E_WARNING, "%s", curl_multi_strerror(rc)); } php_http_client_curl_responsehandler(client); @@@ -726,7 -726,7 +750,7 @@@ static ZEND_RESULT_CODE php_http_curle_ php_http_client_curl_handler_t *curl = userdata; CURL *ch = curl->handle; - if (CURLE_OK != curl_easy_setopt(ch, CURLOPT_SSL_VERIFYHOST, Z_BVAL_P(val) ? 2 : 0)) { + if (CURLE_OK != curl_easy_setopt(ch, CURLOPT_SSL_VERIFYHOST, Z_TYPE_P(val) == IS_TRUE ? 2 : 0)) { return FAILURE; } return SUCCESS; @@@ -737,10 -737,10 +761,10 @@@ static ZEND_RESULT_CODE php_http_curle_ php_http_client_curl_handler_t *curl = userdata; CURL *ch = curl->handle; - if (CURLE_OK != curl_easy_setopt(ch, CURLOPT_COOKIESESSION, (long) Z_BVAL_P(val))) { + if (CURLE_OK != curl_easy_setopt(ch, CURLOPT_COOKIESESSION, (long) (Z_TYPE_P(val) == IS_TRUE))) { return FAILURE; } - if (Z_BVAL_P(val)) { + if (Z_TYPE_P(val) == IS_TRUE) { if (CURLE_OK != curl_easy_setopt(ch, CURLOPT_COOKIELIST, "SESS")) { return FAILURE; } @@@ -758,7 -758,7 +782,7 @@@ static ZEND_RESULT_CODE php_http_curle_ if (storage->cookiestore) { pefree(storage->cookiestore, 1); } - if (val && Z_STRLEN_P(val)) { + if (val && Z_TYPE_P(val) == IS_STRING && Z_STRLEN_P(val)) { storage->cookiestore = pestrndup(Z_STRVAL_P(val), Z_STRLEN_P(val), 1); } else { storage->cookiestore = NULL; @@@ -776,12 -776,11 +800,12 @@@ static ZEND_RESULT_CODE php_http_curle_ { php_http_client_curl_handler_t *curl = userdata; CURL *ch = curl->handle; - TSRMLS_FETCH_FROM_CTX(curl->client->ts); if (val && Z_TYPE_P(val) != IS_NULL) { + HashTable *ht = HASH_OF(val); + if (curl->options.encode_cookies) { - if (SUCCESS == php_http_url_encode_hash_ex(HASH_OF(val), &curl->options.cookies, ZEND_STRL(";"), ZEND_STRL("="), NULL, 0 TSRMLS_CC)) { + if (SUCCESS == php_http_url_encode_hash_ex(ht, &curl->options.cookies, ZEND_STRL(";"), ZEND_STRL("="), NULL, 0)) { php_http_buffer_fix(&curl->options.cookies); if (CURLE_OK != curl_easy_setopt(ch, CURLOPT_COOKIE, curl->options.cookies.data)) { return FAILURE; @@@ -790,20 -789,19 +814,20 @@@ return FAILURE; } } else { - HashPosition pos; - php_http_array_hashkey_t cookie_key = php_http_array_hashkey_init(0); - zval **cookie_val; + php_http_arrkey_t cookie_key; + zval *cookie_val; - FOREACH_KEYVAL(pos, val, cookie_key, cookie_val) { - zval *zv = php_http_ztyp(IS_STRING, *cookie_val); + ZEND_HASH_FOREACH_KEY_VAL(ht, cookie_key.h, cookie_key.key, cookie_val) + { + zend_string *zs = zval_get_string(cookie_val); - php_http_array_hashkey_stringify(&cookie_key); - php_http_buffer_appendf(&curl->options.cookies, "%s=%s; ", cookie_key.str, Z_STRVAL_P(zv)); - php_http_array_hashkey_stringfree(&cookie_key); + php_http_arrkey_stringify(&cookie_key, NULL); + php_http_buffer_appendf(&curl->options.cookies, "%s=%s; ", cookie_key.key->val, zs->val); + php_http_arrkey_dtor(&cookie_key); - zval_ptr_dtor(&zv); + zend_string_release(zs); } + ZEND_HASH_FOREACH_END(); php_http_buffer_fix(&curl->options.cookies); if (curl->options.cookies.used) { @@@ -825,7 -823,7 +849,7 @@@ static ZEND_RESULT_CODE php_http_curle_ { php_http_client_curl_handler_t *curl = userdata; - curl->options.encode_cookies = Z_BVAL_P(val); + curl->options.encode_cookies = Z_TYPE_P(val) == IS_TRUE; return SUCCESS; } @@@ -833,6 -831,7 +857,6 @@@ static ZEND_RESULT_CODE php_http_curle_ { php_http_client_curl_handler_t *curl = userdata; CURL *ch = curl->handle; - TSRMLS_FETCH_FROM_CTX(curl->client->ts); if (Z_LVAL_P(val)) { if (Z_LVAL_P(val) > 0) { @@@ -840,7 -839,7 +864,7 @@@ return FAILURE; } } else { - if (CURLE_OK != curl_easy_setopt(ch, CURLOPT_TIMEVALUE, (long) sapi_get_request_time(TSRMLS_C) + Z_LVAL_P(val))) { + if (CURLE_OK != curl_easy_setopt(ch, CURLOPT_TIMEVALUE, (long) sapi_get_request_time() + Z_LVAL_P(val))) { return FAILURE; } } @@@ -865,7 -864,7 +889,7 @@@ static ZEND_RESULT_CODE php_http_curle_ #if !PHP_HTTP_CURL_VERSION(7,21,6) # define CURLOPT_ACCEPT_ENCODING CURLOPT_ENCODING #endif - if (CURLE_OK != curl_easy_setopt(ch, CURLOPT_ACCEPT_ENCODING, Z_BVAL_P(val) ? "" : NULL)) { + if (CURLE_OK != curl_easy_setopt(ch, CURLOPT_ACCEPT_ENCODING, Z_TYPE_P(val) == IS_TRUE ? "" : NULL)) { return FAILURE; } return SUCCESS; @@@ -876,7 -875,7 +900,7 @@@ static ZEND_RESULT_CODE php_http_curle_ php_http_client_curl_handler_t *curl = userdata; php_http_buffer_t header; - if (Z_STRLEN_P(val)) { + if (val && Z_TYPE_P(val) == IS_STRING && Z_STRLEN_P(val)) { zend_bool is_quoted = !((Z_STRVAL_P(val)[0] != '"') || (Z_STRVAL_P(val)[Z_STRLEN_P(val)-1] != '"')); php_http_buffer_init(&header); php_http_buffer_appendf(&header, is_quoted?"%s: %s":"%s: \"%s\"", curl->options.range_request?"If-Match":"If-None-Match", Z_STRVAL_P(val)); @@@ -891,29 -890,32 +915,29 @@@ static ZEND_RESULT_CODE php_http_curle_ { php_http_client_curl_handler_t *curl = userdata; CURL *ch = curl->handle; - TSRMLS_FETCH_FROM_CTX(curl->client->ts); php_http_buffer_reset(&curl->options.ranges); if (val && Z_TYPE_P(val) != IS_NULL) { - HashPosition pos; - zval **rr, **rb, **re; - - FOREACH_VAL(pos, val, rr) { - if (Z_TYPE_PP(rr) == IS_ARRAY) { - if (2 == php_http_array_list(Z_ARRVAL_PP(rr) TSRMLS_CC, 2, &rb, &re)) { - if ( ((Z_TYPE_PP(rb) == IS_LONG) || ((Z_TYPE_PP(rb) == IS_STRING) && is_numeric_string(Z_STRVAL_PP(rb), Z_STRLEN_PP(rb), NULL, NULL, 1))) && - ((Z_TYPE_PP(re) == IS_LONG) || ((Z_TYPE_PP(re) == IS_STRING) && is_numeric_string(Z_STRVAL_PP(re), Z_STRLEN_PP(re), NULL, NULL, 1)))) { - zval *rbl = php_http_ztyp(IS_LONG, *rb); - zval *rel = php_http_ztyp(IS_LONG, *re); - - if ((Z_LVAL_P(rbl) >= 0) && (Z_LVAL_P(rel) >= 0)) { - php_http_buffer_appendf(&curl->options.ranges, "%ld-%ld,", Z_LVAL_P(rbl), Z_LVAL_P(rel)); + zval *rr, *rb, *re; + zend_long rbl, rel; + HashTable *ht = HASH_OF(val); + + ZEND_HASH_FOREACH_VAL(ht, rr) + { + if (Z_TYPE_P(rr) == IS_ARRAY) { + if (2 == php_http_array_list(Z_ARRVAL_P(rr), 2, &rb, &re)) { + if ( ((Z_TYPE_P(rb) == IS_LONG) || ((Z_TYPE_P(rb) == IS_STRING) && is_numeric_string(Z_STRVAL_P(rb), Z_STRLEN_P(rb), &rbl, NULL, 1))) && + ((Z_TYPE_P(re) == IS_LONG) || ((Z_TYPE_P(re) == IS_STRING) && is_numeric_string(Z_STRVAL_P(re), Z_STRLEN_P(re), &rel, NULL, 1)))) { + if ((rbl >= 0) && (rel >= 0)) { + php_http_buffer_appendf(&curl->options.ranges, "%ld-%ld,", rbl, rel); } - zval_ptr_dtor(&rbl); - zval_ptr_dtor(&rel); } } } } + ZEND_HASH_FOREACH_END(); if (curl->options.ranges.used) { curl->options.range_request = 1; @@@ -976,16 -978,26 +1000,16 @@@ static ZEND_RESULT_CODE php_http_curle_ php_http_client_curl_handler_t *curl = userdata; CURL *ch = curl->handle; long localport = 0, localportrange = 0; - TSRMLS_FETCH_FROM_CTX(curl->client->ts); if (val && Z_TYPE_P(val) != IS_NULL) { - zval **z_port_start, *zps_copy = NULL, **z_port_end, *zpe_copy = NULL; + zval *zps, *zpe; - switch (php_http_array_list(Z_ARRVAL_P(val) TSRMLS_CC, 2, &z_port_start, &z_port_end)) { + switch (php_http_array_list(Z_ARRVAL_P(val), 2, &zps, &zpe)) { case 2: - zps_copy = php_http_ztyp(IS_LONG, *z_port_start); - zpe_copy = php_http_ztyp(IS_LONG, *z_port_end); - localportrange = labs(Z_LVAL_P(zps_copy)-Z_LVAL_P(zpe_copy))+1L; + localportrange = labs(zval_get_long(zps)-zval_get_long(zpe))+1L; /* no break */ case 1: - if (!zps_copy) { - zps_copy = php_http_ztyp(IS_LONG, *z_port_start); - } - localport = (zpe_copy && Z_LVAL_P(zpe_copy) > 0) ? MIN(Z_LVAL_P(zps_copy), Z_LVAL_P(zpe_copy)) : Z_LVAL_P(zps_copy); - zval_ptr_dtor(&zps_copy); - if (zpe_copy) { - zval_ptr_dtor(&zpe_copy); - } + localport = (zval_get_long(zpe) > 0) ? MIN(zval_get_long(zps), zval_get_long(zpe)) : zval_get_long(zps); break; default: break; @@@ -1003,28 -1015,26 +1027,28 @@@ static ZEND_RESULT_CODE php_http_curle_option_set_proxyheader(php_http_option_t *opt, zval *val, void *userdata) { php_http_client_curl_handler_t *curl = userdata; - TSRMLS_FETCH_FROM_CTX(curl->client->ts); if (val && Z_TYPE_P(val) != IS_NULL) { - php_http_array_hashkey_t header_key = php_http_array_hashkey_init(0); - zval **header_val, *header_cpy; - HashPosition pos; + php_http_arrkey_t header_key; + zval *header_val; php_http_buffer_t header; php_http_buffer_init(&header); - FOREACH_KEYVAL(pos, val, header_key, header_val) { - if (header_key.type == HASH_KEY_IS_STRING) { - header_cpy = php_http_ztyp(IS_STRING, *header_val); - php_http_buffer_appendf(&header, "%s: %s", header_key.str, Z_STRVAL_P(header_cpy)); + ZEND_HASH_FOREACH_KEY_VAL(Z_ARRVAL_P(val), header_key.h, header_key.key, header_val) + { + if (header_key.key) { + zend_string *zs = zval_get_string(header_val); + + php_http_buffer_appendf(&header, "%s: %s", header_key.key->val, zs->val); + zend_string_release(zs); + php_http_buffer_fix(&header); curl->options.proxyheaders = curl_slist_append(curl->options.proxyheaders, header.data); php_http_buffer_reset(&header); - zval_ptr_dtor(&header_cpy); } } + ZEND_HASH_FOREACH_END(); php_http_buffer_dtor(&header); } if (CURLE_OK != curl_easy_setopt(curl->handle, CURLOPT_PROXYHEADER, curl->options.proxyheaders)) { @@@ -1043,18 -1053,18 +1067,18 @@@ static ZEND_RESULT_CODE php_http_curle_ { php_http_client_curl_handler_t *curl = userdata; CURL *ch = curl->handle; - TSRMLS_FETCH_FROM_CTX(curl->client->ts); if (val && Z_TYPE_P(val) != IS_NULL) { - php_http_array_hashkey_t key = php_http_array_hashkey_init(0); - HashPosition pos; - zval **data; - - FOREACH_KEYVAL(pos, val, key, data) { - zval *cpy = php_http_ztyp(IS_STRING, *data); - curl->options.resolve = curl_slist_append(curl->options.resolve, Z_STRVAL_P(cpy)); - zval_ptr_dtor(&cpy); + HashTable *ht = HASH_OF(val); + zval *data; + + ZEND_HASH_FOREACH_VAL(ht, data) + { + zend_string *zs = zval_get_string(data); + curl->options.resolve = curl_slist_append(curl->options.resolve, zs->val); + zend_string_release(zs); } + ZEND_HASH_FOREACH_END(); if (CURLE_OK != curl_easy_setopt(ch, CURLOPT_RESOLVE, curl->options.resolve)) { return FAILURE; @@@ -1092,13 -1102,13 +1116,13 @@@ static ZEND_RESULT_CODE php_http_curle_ } #endif -static void php_http_curle_options_init(php_http_options_t *registry TSRMLS_DC) +static void php_http_curle_options_init(php_http_options_t *registry) { php_http_option_t *opt; /* url options */ #if PHP_HTTP_CURL_VERSION(7,42,0) - php_http_option_register(registry, ZEND_STRL("path_as_is"), CURLOPT_PATH_AS_IS, IS_BOOL); + php_http_option_register(registry, ZEND_STRL("path_as_is"), CURLOPT_PATH_AS_IS, _IS_BOOL); #endif /* proxy */ @@@ -1111,7 -1121,7 +1135,7 @@@ if ((opt = php_http_option_register(registry, ZEND_STRL("proxyauthtype"), CURLOPT_PROXYAUTH, IS_LONG))) { Z_LVAL(opt->defval) = CURLAUTH_ANYSAFE; } - php_http_option_register(registry, ZEND_STRL("proxytunnel"), CURLOPT_HTTPPROXYTUNNEL, IS_BOOL); + php_http_option_register(registry, ZEND_STRL("proxytunnel"), CURLOPT_HTTPPROXYTUNNEL, _IS_BOOL); #if PHP_HTTP_CURL_VERSION(7,19,4) php_http_option_register(registry, ZEND_STRL("noproxy"), CURLOPT_NOPROXY, IS_STRING); #endif @@@ -1182,8 -1192,8 +1206,8 @@@ Z_LVAL(opt->defval) = 5; } */ - php_http_option_register(registry, ZEND_STRL("fresh_connect"), CURLOPT_FRESH_CONNECT, IS_BOOL); - php_http_option_register(registry, ZEND_STRL("forbid_reuse"), CURLOPT_FORBID_REUSE, IS_BOOL); + php_http_option_register(registry, ZEND_STRL("fresh_connect"), CURLOPT_FRESH_CONNECT, _IS_BOOL); + php_http_option_register(registry, ZEND_STRL("forbid_reuse"), CURLOPT_FORBID_REUSE, _IS_BOOL); /* outgoing interface */ php_http_option_register(registry, ZEND_STRL("interface"), CURLOPT_INTERFACE, IS_STRING); @@@ -1217,7 -1227,7 +1241,7 @@@ if ((opt = php_http_option_register(registry, ZEND_STRL("redirect"), CURLOPT_FOLLOWLOCATION, IS_LONG))) { opt->setter = php_http_curle_option_set_redirect; } - php_http_option_register(registry, ZEND_STRL("unrestricted_auth"), CURLOPT_UNRESTRICTED_AUTH, IS_BOOL); + php_http_option_register(registry, ZEND_STRL("unrestricted_auth"), CURLOPT_UNRESTRICTED_AUTH, _IS_BOOL); #if PHP_HTTP_CURL_VERSION(7,19,1) php_http_option_register(registry, ZEND_STRL("postredir"), CURLOPT_POSTREDIR, IS_LONG); #endif @@@ -1234,17 -1244,18 +1258,17 @@@ if ((opt = php_http_option_register(registry, ZEND_STRL("referer"), CURLOPT_REFERER, IS_STRING))) { opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN; } - if ((opt = php_http_option_register(registry, ZEND_STRL("autoreferer"), CURLOPT_AUTOREFERER, IS_BOOL))) { + if ((opt = php_http_option_register(registry, ZEND_STRL("autoreferer"), CURLOPT_AUTOREFERER, _IS_BOOL))) { ZVAL_BOOL(&opt->defval, 1); } /* useragent */ if ((opt = php_http_option_register(registry, ZEND_STRL("useragent"), CURLOPT_USERAGENT, IS_STRING))) { /* don't check strlen, to allow sending no useragent at all */ - ZVAL_STRING(&opt->defval, + ZVAL_PSTRING(&opt->defval, "PECL_HTTP/" PHP_PECL_HTTP_VERSION " " "PHP/" PHP_VERSION " " - "libcurl/" LIBCURL_VERSION - , 0); + "libcurl/" LIBCURL_VERSION); } /* resume */ @@@ -1263,7 -1274,7 +1287,7 @@@ } /* compression */ - if ((opt = php_http_option_register(registry, ZEND_STRL("compress"), 0, IS_BOOL))) { + if ((opt = php_http_option_register(registry, ZEND_STRL("compress"), 0, _IS_BOOL))) { opt->setter = php_http_curle_option_set_compress; } @@@ -1273,7 -1284,7 +1297,7 @@@ } /* cookies */ - if ((opt = php_http_option_register(registry, ZEND_STRL("encodecookies"), 0, IS_BOOL))) { + if ((opt = php_http_option_register(registry, ZEND_STRL("encodecookies"), 0, _IS_BOOL))) { opt->setter = php_http_curle_option_set_encodecookies; ZVAL_BOOL(&opt->defval, 1); } @@@ -1282,7 -1293,7 +1306,7 @@@ } /* cookiesession, don't load session cookies from cookiestore */ - if ((opt = php_http_option_register(registry, ZEND_STRL("cookiesession"), CURLOPT_COOKIESESSION, IS_BOOL))) { + if ((opt = php_http_option_register(registry, ZEND_STRL("cookiesession"), CURLOPT_COOKIESESSION, _IS_BOOL))) { opt->setter = php_http_curle_option_set_cookiesession; } /* cookiestore, read initial cookies from that file and store cookies back into that file */ @@@ -1314,9 -1325,9 +1338,9 @@@ #endif /* tcp */ - php_http_option_register(registry, ZEND_STRL("tcp_nodelay"), CURLOPT_TCP_NODELAY, IS_BOOL); + php_http_option_register(registry, ZEND_STRL("tcp_nodelay"), CURLOPT_TCP_NODELAY, _IS_BOOL); #if PHP_HTTP_CURL_VERSION(7,25,0) - php_http_option_register(registry, ZEND_STRL("tcp_keepalive"), CURLOPT_TCP_KEEPALIVE, IS_BOOL); + php_http_option_register(registry, ZEND_STRL("tcp_keepalive"), CURLOPT_TCP_KEEPALIVE, _IS_BOOL); if ((opt = php_http_option_register(registry, ZEND_STRL("tcp_keepidle"), CURLOPT_TCP_KEEPIDLE, IS_LONG))) { Z_LVAL(opt->defval) = 60; } @@@ -1336,7 -1347,7 +1360,7 @@@ } if ((opt = php_http_option_register(registry, ZEND_STRL("certtype"), CURLOPT_SSLCERTTYPE, IS_STRING))) { opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN; - ZVAL_STRING(&opt->defval, "PEM", 0); + ZVAL_PSTRING(&opt->defval, "PEM"); } if ((opt = php_http_option_register(registry, ZEND_STRL("key"), CURLOPT_SSLKEY, IS_STRING))) { opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN; @@@ -1344,36 -1355,36 +1368,36 @@@ } if ((opt = php_http_option_register(registry, ZEND_STRL("keytype"), CURLOPT_SSLKEYTYPE, IS_STRING))) { opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN; - ZVAL_STRING(&opt->defval, "PEM", 0); + ZVAL_PSTRING(&opt->defval, "PEM"); } if ((opt = php_http_option_register(registry, ZEND_STRL("keypasswd"), CURLOPT_SSLKEYPASSWD, IS_STRING))) { opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN; } php_http_option_register(registry, ZEND_STRL("engine"), CURLOPT_SSLENGINE, IS_STRING); php_http_option_register(registry, ZEND_STRL("version"), CURLOPT_SSLVERSION, IS_LONG); - if ((opt = php_http_option_register(registry, ZEND_STRL("verifypeer"), CURLOPT_SSL_VERIFYPEER, IS_BOOL))) { + if ((opt = php_http_option_register(registry, ZEND_STRL("verifypeer"), CURLOPT_SSL_VERIFYPEER, _IS_BOOL))) { ZVAL_BOOL(&opt->defval, 1); } - if ((opt = php_http_option_register(registry, ZEND_STRL("verifyhost"), CURLOPT_SSL_VERIFYHOST, IS_BOOL))) { + if ((opt = php_http_option_register(registry, ZEND_STRL("verifyhost"), CURLOPT_SSL_VERIFYHOST, _IS_BOOL))) { ZVAL_BOOL(&opt->defval, 1); opt->setter = php_http_curle_option_set_ssl_verifyhost; } #if PHP_HTTP_CURL_VERSION(7,41,0) && (defined(PHP_HTTP_HAVE_OPENSSL) || defined(PHP_HTTP_HAVE_NSS) || defined(PHP_HTTP_HAVE_GNUTLS)) - php_http_option_register(registry, ZEND_STRL("verifystatus"), CURLOPT_SSL_VERIFYSTATUS, IS_BOOL); + php_http_option_register(registry, ZEND_STRL("verifystatus"), CURLOPT_SSL_VERIFYSTATUS, _IS_BOOL); #endif php_http_option_register(registry, ZEND_STRL("cipher_list"), CURLOPT_SSL_CIPHER_LIST, IS_STRING); if ((opt = php_http_option_register(registry, ZEND_STRL("cainfo"), CURLOPT_CAINFO, IS_STRING))) { opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN; opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_BASEDIR; #ifdef PHP_HTTP_CURL_CAINFO - ZVAL_STRING(&opt->defval, PHP_HTTP_CURL_CAINFO, 0); + ZVAL_PSTRING(&opt->defval, PHP_HTTP_CURL_CAINFO); #endif } if ((opt = php_http_option_register(registry, ZEND_STRL("capath"), CURLOPT_CAPATH, IS_STRING))) { opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_STRLEN; opt->flags |= PHP_HTTP_CURLE_OPTION_CHECK_BASEDIR; #ifdef PHP_HTTP_CURL_CAPATH - ZVAL_STRING(&opt->defval, PHP_HTTP_CURL_CAPATH, 0); + ZVAL_PSTRING(&opt->defval, PHP_HTTP_CURL_CAPATH); #endif } if ((opt = php_http_option_register(registry, ZEND_STRL("random_file"), CURLOPT_RANDOM_FILE, IS_STRING))) { @@@ -1397,15 -1408,13 +1421,15 @@@ # endif #endif #if (PHP_HTTP_CURL_VERSION(7,19,1) && defined(PHP_HTTP_HAVE_OPENSSL)) || (PHP_HTTP_CURL_VERSION(7,34,0) && defined(PHP_HTTP_HAVE_NSS)) || (PHP_HTTP_CURL_VERSION(7,42,0) && defined(PHP_HTTP_HAVE_GNUTLS)) || (PHP_HTTP_CURL_VERSION(7,39,0) && defined(PHP_HTTP_HAVE_GSKIT)) - php_http_option_register(registry, ZEND_STRL("certinfo"), CURLOPT_CERTINFO, IS_BOOL); + if ((opt = php_http_option_register(registry, ZEND_STRL("certinfo"), CURLOPT_CERTINFO, _IS_BOOL))) { + ZVAL_FALSE(&opt->defval); + } #endif #if PHP_HTTP_CURL_VERSION(7,36,0) - if ((opt = php_http_option_register(registry, ZEND_STRL("enable_npn"), CURLOPT_SSL_ENABLE_NPN, IS_BOOL))) { + if ((opt = php_http_option_register(registry, ZEND_STRL("enable_npn"), CURLOPT_SSL_ENABLE_NPN, _IS_BOOL))) { ZVAL_BOOL(&opt->defval, 1); } - if ((opt = php_http_option_register(registry, ZEND_STRL("enable_alpn"), CURLOPT_SSL_ENABLE_ALPN, IS_BOOL))) { + if ((opt = php_http_option_register(registry, ZEND_STRL("enable_alpn"), CURLOPT_SSL_ENABLE_ALPN, _IS_BOOL))) { ZVAL_BOOL(&opt->defval, 1); } #endif @@@ -1428,7 -1437,7 +1452,7 @@@ } #endif #if PHP_HTTP_CURL_VERSION(7,42,0) && (defined(PHP_HTTP_HAVE_NSS) || defined(PHP_HTTP_HAVE_DARWINSSL)) - php_http_option_register(registry, ZEND_STRL("falsestart"), CURLOPT_SSL_FALSESTART, IS_BOOL); + php_http_option_register(registry, ZEND_STRL("falsestart"), CURLOPT_SSL_FALSESTART, _IS_BOOL); #endif } } @@@ -1440,12 -1449,8 +1464,12 @@@ static zval *php_http_curle_get_option( zval *option; if ((option = php_http_option_get(opt, options, NULL))) { - option = php_http_ztyp(opt->type, option); - zend_hash_quick_update(&curl->options.cache, opt->name.s, opt->name.l, opt->name.h, &option, sizeof(zval *), NULL); + zval zopt; + + ZVAL_DUP(&zopt, option); + convert_to_explicit_type(&zopt, opt->type); + zend_hash_update(&curl->options.cache, opt->name, &zopt); + return zend_hash_find(&curl->options.cache, opt->name); } return option; } @@@ -1457,16 -1462,17 +1481,16 @@@ static ZEND_RESULT_CODE php_http_curle_ zval tmp; CURLcode rc = CURLE_UNKNOWN_OPTION; ZEND_RESULT_CODE rv = SUCCESS; - TSRMLS_FETCH_FROM_CTX(curl->client->ts); if (!val) { val = &opt->defval; } switch (opt->type) { - case IS_BOOL: + case _IS_BOOL: if (opt->setter) { rv = opt->setter(opt, val, curl); - } else if (CURLE_OK != curl_easy_setopt(ch, opt->option, (long) Z_BVAL_P(val))) { + } else if (CURLE_OK != curl_easy_setopt(ch, opt->option, (long) (Z_TYPE_P(val) == IS_TRUE))) { rv = FAILURE; } break; @@@ -1482,15 -1488,11 +1506,15 @@@ case IS_STRING: if (opt->setter) { rv = opt->setter(opt, val, curl); + } else if (!val || Z_TYPE_P(val) == IS_NULL) { + if (CURLE_OK != (rc = curl_easy_setopt(ch, opt->option, NULL))) { + rv = FAILURE; + } } else if ((opt->flags & PHP_HTTP_CURLE_OPTION_CHECK_STRLEN) && !Z_STRLEN_P(val)) { if (CURLE_OK != (rc = curl_easy_setopt(ch, opt->option, NULL))) { rv = FAILURE; } - } else if ((opt->flags & PHP_HTTP_CURLE_OPTION_CHECK_BASEDIR) && Z_STRVAL_P(val) && SUCCESS != php_check_open_basedir(Z_STRVAL_P(val) TSRMLS_CC)) { + } else if ((opt->flags & PHP_HTTP_CURLE_OPTION_CHECK_BASEDIR) && Z_STRVAL_P(val) && SUCCESS != php_check_open_basedir(Z_STRVAL_P(val))) { if (CURLE_OK != (rc = curl_easy_setopt(ch, opt->option, NULL))) { rv = FAILURE; } @@@ -1529,7 -1531,7 +1553,7 @@@ break; } if (rv != SUCCESS) { - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Could not set option %s (%s)", opt->name.s, curl_easy_strerror(rc)); + php_error_docref(NULL, E_NOTICE, "Could not set option %s (%s)", opt->name->val, curl_easy_strerror(rc)); } return rv; } @@@ -1542,10 -1544,12 +1566,10 @@@ static ZEND_RESULT_CODE php_http_curlm_ CURLM *ch = curl->handle->multi; HashTable tmp_ht; char **bl = NULL; - TSRMLS_FETCH_FROM_CTX(client->ts); /* array of char *, ending with a NULL */ if (value && Z_TYPE_P(value) != IS_NULL) { - zval **entry; - HashPosition pos; + zval *entry; HashTable *ht = HASH_OF(value); int c = zend_hash_num_elements(ht); char **ptr = ecalloc(c + 1, sizeof(char *)); @@@ -1555,11 -1559,9 +1579,11 @@@ zend_hash_init(&tmp_ht, c, NULL, ZVAL_PTR_DTOR, 0); array_join(ht, &tmp_ht, 0, ARRAY_JOIN_STRINGIFY); - FOREACH_HASH_VAL(pos, &tmp_ht, entry) { - *ptr++ = Z_STRVAL_PP(entry); + ZEND_HASH_FOREACH_VAL(&tmp_ht, entry) + { + *ptr++ = Z_STRVAL_P(entry); } + ZEND_HASH_FOREACH_END(); } if (CURLM_OK != curl_multi_setopt(ch, opt->option, bl)) { @@@ -1605,11 -1607,12 +1629,11 @@@ static ZEND_RESULT_CODE php_http_curlm_ { php_http_client_t *client = userdata; php_http_client_curl_ops_t *ev_ops = NULL; - TSRMLS_FETCH_FROM_CTX(client->ts); - if (Z_TYPE_P(value) == IS_OBJECT && instanceof_function(Z_OBJCE_P(value), php_http_client_curl_user_class_entry TSRMLS_CC)) { + if (Z_TYPE_P(value) == IS_OBJECT && instanceof_function(Z_OBJCE_P(value), php_http_client_curl_user_get_class_entry())) { ev_ops = php_http_client_curl_user_ops_get(); #if PHP_HTTP_HAVE_EVENT - } else if (value && z_is_true(value)) { + } else if (value && zend_is_true(value)) { ev_ops = php_http_client_curl_event_ops_get(); #endif } @@@ -1623,14 -1626,15 +1647,14 @@@ static ZEND_RESULT_CODE php_http_curlm_ php_http_client_curl_t *curl = client->ctx; CURLSHcode rc; - if (Z_BVAL_P(value)) { + if (Z_TYPE_P(value) == IS_TRUE) { rc = curl_share_setopt(curl->handle->share, CURLSHOPT_SHARE, CURL_LOCK_DATA_COOKIE); } else { rc = curl_share_setopt(curl->handle->share, CURLSHOPT_UNSHARE, CURL_LOCK_DATA_COOKIE); } if (CURLSHE_OK != rc) { - TSRMLS_FETCH_FROM_CTX(client->ts); - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Could not set option %s (%s)", opt->name.s, curl_share_strerror(rc)); + php_error_docref(NULL, E_NOTICE, "Could not set option %s (%s)", opt->name->val, curl_share_strerror(rc)); return FAILURE; } return SUCCESS; @@@ -1643,21 -1647,22 +1667,21 @@@ static ZEND_RESULT_CODE php_http_curlm_ php_http_client_curl_t *curl = client->ctx; CURLSHcode rc; - if (Z_BVAL_P(value)) { + if (Z_TYPE_P(value) == IS_TRUE) { rc = curl_share_setopt(curl->handle->share, CURLSHOPT_SHARE, CURL_LOCK_DATA_SSL_SESSION); } else { rc = curl_share_setopt(curl->handle->share, CURLSHOPT_UNSHARE, CURL_LOCK_DATA_SSL_SESSION); } if (CURLSHE_OK != rc) { - TSRMLS_FETCH_FROM_CTX(client->ts); - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Could not set option %s (%s)", opt->name.s, curl_share_strerror(rc)); + php_error_docref(NULL, E_NOTICE, "Could not set option %s (%s)", opt->name->val, curl_share_strerror(rc)); return FAILURE; } return SUCCESS; } #endif -static void php_http_curlm_options_init(php_http_options_t *registry TSRMLS_DC) +static void php_http_curlm_options_init(php_http_options_t *registry) { php_http_option_t *opt; @@@ -1681,7 -1686,7 +1705,7 @@@ php_http_option_register(registry, ZEND_STRL("max_total_connections"), CURLMOPT_MAX_TOTAL_CONNECTIONS, IS_LONG); #endif /* enable/disable HTTP pipelining */ - php_http_option_register(registry, ZEND_STRL("pipelining"), CURLMOPT_PIPELINING, IS_BOOL); + php_http_option_register(registry, ZEND_STRL("pipelining"), CURLMOPT_PIPELINING, _IS_BOOL); /* chunk length threshold for pipelining */ #if PHP_HTTP_CURL_VERSION(7,30,0) php_http_option_register(registry, ZEND_STRL("chunk_length_penalty_size"), CURLMOPT_CHUNK_LENGTH_PENALTY_SIZE, IS_LONG); @@@ -1707,14 -1712,14 +1731,14 @@@ opt->setter = php_http_curlm_option_set_use_eventloop; } /* share */ - if ((opt = php_http_option_register(registry, ZEND_STRL("share_cookies"), 0, IS_BOOL))) { + if ((opt = php_http_option_register(registry, ZEND_STRL("share_cookies"), 0, _IS_BOOL))) { opt->setter = php_http_curlm_option_set_share_cookies; - ZVAL_BOOL(&opt->defval, 1); + ZVAL_TRUE(&opt->defval); } #if PHP_HTTP_CURL_VERSION(7,23,0) - if ((opt = php_http_option_register(registry, ZEND_STRL("share_ssl"), 0, IS_BOOL))) { + if ((opt = php_http_option_register(registry, ZEND_STRL("share_ssl"), 0, _IS_BOOL))) { opt->setter = php_http_curlm_option_set_share_ssl; - ZVAL_BOOL(&opt->defval, 1); + ZVAL_TRUE(&opt->defval); } #endif } @@@ -1727,43 -1732,39 +1751,43 @@@ static ZEND_RESULT_CODE php_http_curlm_ zval *orig = val; CURLMcode rc = CURLM_UNKNOWN_OPTION; ZEND_RESULT_CODE rv = SUCCESS; - TSRMLS_FETCH_FROM_CTX(client->ts); if (!val) { val = &opt->defval; } else if (opt->type && Z_TYPE_P(val) != opt->type && !(Z_TYPE_P(val) == IS_NULL && opt->type == IS_ARRAY)) { - val = php_http_ztyp(opt->type, val); + zval zopt; + + ZVAL_DUP(&zopt, val); + convert_to_explicit_type(&zopt, opt->type); + + val = &zopt; } if (opt->setter) { rv = opt->setter(opt, val, client); } else { switch (opt->type) { - case IS_BOOL: - if (CURLM_OK != (rc = curl_multi_setopt(ch, opt->option, (long) Z_BVAL_P(val)))) { + case _IS_BOOL: + if (CURLM_OK != (rc = curl_multi_setopt(ch, opt->option, (long) zend_is_true(val)))) { rv = FAILURE; - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Could not set option %s (%s)", opt->name.s, curl_multi_strerror(rc)); + php_error_docref(NULL, E_NOTICE, "Could not set option %s (%s)", opt->name->val, curl_multi_strerror(rc)); } break; case IS_LONG: if (CURLM_OK != (rc = curl_multi_setopt(ch, opt->option, Z_LVAL_P(val)))) { rv = FAILURE; - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Could not set option %s (%s)", opt->name.s, curl_multi_strerror(rc)); + php_error_docref(NULL, E_NOTICE, "Could not set option %s (%s)", opt->name->val, curl_multi_strerror(rc)); } break; default: rv = FAILURE; - php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Could not set option %s", opt->name.s); + php_error_docref(NULL, E_NOTICE, "Could not set option %s", opt->name->val); break; } } if (val && val != orig && val != &opt->defval) { - zval_ptr_dtor(&val); + zval_ptr_dtor(val); } return rv; @@@ -1832,9 -1833,10 +1856,9 @@@ static php_http_client_curl_handler_t * void *handle; php_http_client_curl_t *curl = h->ctx; php_http_client_curl_handler_t *handler; - TSRMLS_FETCH_FROM_CTX(h->ts); - if (!(handle = php_resource_factory_handle_ctor(rf, NULL TSRMLS_CC))) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to initialize curl handle->multi"); + if (!(handle = php_resource_factory_handle_ctor(rf, NULL))) { + php_error_docref(NULL, E_WARNING, "Failed to initialize curl handle"); return NULL; } @@@ -1842,7 -1844,7 +1866,7 @@@ handler->rf = rf; handler->client = h; handler->handle = handle; - handler->response.body = php_http_message_body_init(NULL, NULL TSRMLS_CC); + handler->response.body = php_http_message_body_init(NULL, NULL); php_http_buffer_init(&handler->response.headers); php_http_buffer_init(&handler->options.cookies); php_http_buffer_init(&handler->options.ranges); @@@ -1884,10 -1886,11 +1908,10 @@@ static ZEND_RESULT_CODE php_http_client size_t body_size; php_http_message_t *msg = enqueue->request; php_http_curle_storage_t *storage = php_http_curle_get_storage(curl->handle); - TSRMLS_FETCH_FROM_CTX(curl->client->ts); /* request url */ if (!PHP_HTTP_INFO(msg).request.url) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot request empty URL"); + php_error_docref(NULL, E_WARNING, "Cannot request empty URL"); return FAILURE; } storage->errorbuffer[0] = '\0'; @@@ -1903,33 -1906,34 +1927,33 @@@ /* request headers */ php_http_message_update_headers(msg); if (zend_hash_num_elements(&msg->hdrs)) { - php_http_array_hashkey_t header_key = php_http_array_hashkey_init(0); - zval **header_val, *header_cpy; - HashPosition pos; + php_http_arrkey_t header_key; + zval *header_val; + zend_string *header_str; php_http_buffer_t header; #if !PHP_HTTP_CURL_VERSION(7,23,0) - zval **ct = NULL; - - zend_hash_find(&msg->hdrs, ZEND_STRS("Content-Length"), (void *) &ct); + zval *ct = zend_hash_str_find(&msg->hdrs, ZEND_STRL("Content-Length")); #endif php_http_buffer_init(&header); - FOREACH_HASH_KEYVAL(pos, &msg->hdrs, header_key, header_val) { - if (header_key.type == HASH_KEY_IS_STRING) { + ZEND_HASH_FOREACH_KEY_VAL(&msg->hdrs, header_key.h, header_key.key, header_val) + { + if (header_key.key) { #if !PHP_HTTP_CURL_VERSION(7,23,0) /* avoid duplicate content-length header */ - if (ct && *ct == *header_val) { + if (ct && ct == header_val) { continue; } #endif - header_cpy = php_http_ztyp(IS_STRING, *header_val); - php_http_buffer_appendf(&header, "%s: %s", header_key.str, Z_STRVAL_P(header_cpy)); + header_str = zval_get_string(header_val); + php_http_buffer_appendf(&header, "%s: %s", header_key.key->val, header_str->val); php_http_buffer_fix(&header); curl->options.headers = curl_slist_append(curl->options.headers, header.data); php_http_buffer_reset(&header); - - zval_ptr_dtor(&header_cpy); + zend_string_release(header_str); } } + ZEND_HASH_FOREACH_END(); php_http_buffer_dtor(&header); } curl_easy_setopt(curl->handle, CURLOPT_HTTPHEADER, curl->options.headers); @@@ -1979,7 -1983,7 +2003,7 @@@ curl_easy_setopt(curl->handle, CURLOPT_CUSTOMREQUEST, PHP_HTTP_INFO(msg).request.method); } } else { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot use empty request method"); + php_error_docref(NULL, E_WARNING, "Cannot use empty request method"); return FAILURE; } @@@ -2002,9 -2006,11 +2026,9 @@@ static void php_http_client_curl_handle static void php_http_client_curl_handler_dtor(php_http_client_curl_handler_t *handler) { - TSRMLS_FETCH_FROM_CTX(handler->client->ts); - php_http_client_curl_handler_clear(handler); - php_resource_factory_handle_dtor(handler->rf, handler->handle TSRMLS_CC); + php_resource_factory_handle_dtor(handler->rf, handler->handle); php_resource_factory_free(&handler->rf); php_http_message_body_free(&handler->response.body); @@@ -2013,32 -2019,21 +2037,32 @@@ php_http_buffer_dtor(&handler->options.cookies); zend_hash_destroy(&handler->options.cache); +#if PHP_HTTP_CURL_VERSION(7,21,3) + if (handler->options.resolve) { + curl_slist_free_all(handler->options.resolve); + handler->options.resolve = NULL; + } +#endif + if (handler->options.headers) { curl_slist_free_all(handler->options.headers); handler->options.headers = NULL; } + if (handler->options.proxyheaders) { + curl_slist_free_all(handler->options.proxyheaders); + handler->options.proxyheaders = NULL; + } + efree(handler); } static php_http_client_t *php_http_client_curl_init(php_http_client_t *h, void *handle) { php_http_client_curl_t *curl; - TSRMLS_FETCH_FROM_CTX(h->ts); - if (!handle && !(handle = php_resource_factory_handle_ctor(h->rf, NULL TSRMLS_CC))) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to initialize curl handle->multi"); + if (!handle && !(handle = php_resource_factory_handle_ctor(h->rf, NULL))) { + php_error_docref(NULL, E_WARNING, "Failed to initialize curl handle"); return NULL; } @@@ -2053,13 -2048,15 +2077,14 @@@ static void php_http_client_curl_dtor(php_http_client_t *h) { php_http_client_curl_t *curl = h->ctx; - TSRMLS_FETCH_FROM_CTX(h->ts); if (curl->ev_ops) { curl->ev_ops->dtor(&curl->ev_ctx); + curl->ev_ops = NULL; } curl->unfinished = 0; - php_resource_factory_handle_dtor(h->rf, curl->handle TSRMLS_CC); + php_resource_factory_handle_dtor(h->rf, curl->handle); efree(curl); h->ctx = NULL; @@@ -2076,38 -2073,37 +2101,38 @@@ static void queue_dtor(php_http_client_ php_http_client_curl_handler_dtor(handler); } -static php_resource_factory_t *create_rf(php_http_client_t *h, php_http_client_enqueue_t *enqueue TSRMLS_DC) +static php_resource_factory_t *create_rf(php_http_client_t *h, php_http_client_enqueue_t *enqueue) { php_persistent_handle_factory_t *pf = NULL; php_resource_factory_t *rf = NULL; php_http_url_t *url = enqueue->request->http.info.request.url; if (!url || (!url->host && !url->path)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Cannot request empty URL"); + php_error_docref(NULL, E_WARNING, "Cannot request empty URL"); return NULL; } /* only if the client itself is setup for persistence */ if (php_resource_factory_is_persistent(h->rf)) { + zend_string *id; char *id_str = NULL; size_t id_len; int port = url->port ? url->port : 80; - zval **zport; + zval *zport; php_persistent_handle_factory_t *phf = h->rf->data; - if (SUCCESS == zend_hash_find(enqueue->options, ZEND_STRS("port"), (void *) &zport)) { - zval *zcpy = php_http_ztyp(IS_LONG, *zport); + if ((zport = zend_hash_str_find(enqueue->options, ZEND_STRL("port")))) { + zend_long lport = zval_get_long(zport); - if (Z_LVAL_P(zcpy)) { - port = Z_LVAL_P(zcpy); + if (lport > 0) { + port = lport; } - zval_ptr_dtor(&zcpy); } - id_len = spprintf(&id_str, 0, "%.*s:%s:%d", (int) phf->ident.len, phf->ident.str, STR_PTR(url->host), port); - pf = php_persistent_handle_concede(NULL, ZEND_STRL("http\\Client\\Curl\\Request"), id_str, id_len, NULL, NULL TSRMLS_CC); - efree(id_str); + id_len = spprintf(&id_str, 0, "%.*s:%s:%d", (int) phf->ident->len, phf->ident->val, STR_PTR(url->host), port); + id = php_http_cs2zs(id_str, id_len); + pf = php_persistent_handle_concede(NULL, PHP_HTTP_G->client.curl.driver.request_name, id, NULL, NULL); + zend_string_release(id); } if (pf) { @@@ -2126,8 -2122,9 +2151,8 @@@ static ZEND_RESULT_CODE php_http_client php_http_client_curl_handler_t *handler; php_http_client_progress_state_t *progress; php_resource_factory_t *rf; - TSRMLS_FETCH_FROM_CTX(h->ts); - rf = create_rf(h, enqueue TSRMLS_CC); + rf = create_rf(h, enqueue); if (!rf) { return FAILURE; } @@@ -2148,7 -2145,7 +2173,7 @@@ if (CURLM_OK != (rs = curl_multi_add_handle(curl->handle->multi, handler->handle))) { php_http_client_curl_handler_dtor(handler); - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not enqueue request: %s", curl_multi_strerror(rs)); + php_error_docref(NULL, E_WARNING, "Could not enqueue request: %s", curl_multi_strerror(rs)); return FAILURE; } @@@ -2169,13 -2166,14 +2194,13 @@@ static ZEND_RESULT_CODE php_http_client CURLMcode rs; php_http_client_curl_t *curl = h->ctx; php_http_client_curl_handler_t *handler = enqueue->opaque; - TSRMLS_FETCH_FROM_CTX(h->ts); php_http_client_curl_handler_clear(handler); if (CURLM_OK == (rs = curl_multi_remove_handle(curl->handle->multi, handler->handle))) { zend_llist_del_element(&h->requests, handler->handle, (int (*)(void *, void *)) compare_queue); return SUCCESS; } else { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not dequeue request: %s", curl_multi_strerror(rs)); + php_error_docref(NULL, E_WARNING, "Could not dequeue request: %s", curl_multi_strerror(rs)); } return FAILURE; @@@ -2248,6 -2246,7 +2273,6 @@@ static int php_http_client_curl_once(ph static ZEND_RESULT_CODE php_http_client_curl_exec(php_http_client_t *h) { php_http_client_curl_t *curl = h->ctx; - TSRMLS_FETCH_FROM_CTX(h->ts); if (curl->ev_ops) { return curl->ev_ops->exec(curl->ev_ctx); @@@ -2257,9 -2256,9 +2282,9 @@@ if (SUCCESS != php_http_client_curl_wait(h, NULL)) { #ifdef PHP_WIN32 /* see http://msdn.microsoft.com/library/en-us/winsock/winsock/windows_sockets_error_codes_2.asp */ - php_error_docref(NULL TSRMLS_CC, E_WARNING, "WinSock error: %d", WSAGetLastError()); + php_error_docref(NULL, E_WARNING, "WinSock error: %d", WSAGetLastError()); #else - php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", strerror(errno)); + php_error_docref(NULL, E_WARNING, "%s", strerror(errno)); #endif return FAILURE; } @@@ -2297,31 -2296,34 +2322,31 @@@ static ZEND_RESULT_CODE php_http_client return SUCCESS; } -static int apply_available_options(void *pDest TSRMLS_DC, int num_args, va_list args, zend_hash_key *hash_key) +static int apply_available_options(zval *pDest, int num_args, va_list args, zend_hash_key *hash_key) { - php_http_option_t *opt = pDest; + php_http_option_t *opt = Z_PTR_P(pDest); HashTable *ht; - zval *entry; + zval entry; int c; ht = va_arg(args, HashTable*); - MAKE_STD_ZVAL(entry); - if ((c = zend_hash_num_elements(&opt->suboptions.options))) { - array_init_size(entry, c); - zend_hash_apply_with_arguments(&opt->suboptions.options TSRMLS_CC, apply_available_options, 1, Z_ARRVAL_P(entry)); + array_init_size(&entry, c); + zend_hash_apply_with_arguments(&opt->suboptions.options, apply_available_options, 1, Z_ARRVAL(entry)); } else { /* catch deliberate NULL options */ if (Z_TYPE(opt->defval) == IS_STRING && !Z_STRVAL(opt->defval)) { - ZVAL_NULL(entry); + ZVAL_NULL(&entry); } else { - ZVAL_COPY_VALUE(entry, &opt->defval); - zval_copy_ctor(entry); + ZVAL_ZVAL(&entry, &opt->defval, 1, 0); } } - if (hash_key->nKeyLength) { - zend_hash_quick_update(ht, hash_key->arKey, hash_key->nKeyLength, hash_key->h, (void *) &entry, sizeof(zval *), NULL); + if (hash_key->key) { + zend_hash_update(ht, hash_key->key, &entry); } else { - zend_hash_index_update(ht, hash_key->h, (void *) &entry, sizeof(zval *), NULL); + zend_hash_index_update(ht, hash_key->h, &entry); } return ZEND_HASH_APPLY_KEEP; @@@ -2330,6 -2332,7 +2355,6 @@@ static ZEND_RESULT_CODE php_http_client_curl_getopt(php_http_client_t *h, php_http_client_getopt_opt_t opt, void *arg, void **res) { php_http_client_enqueue_t *enqueue; - TSRMLS_FETCH_FROM_CTX(h->ts); switch (opt) { case PHP_HTTP_CLIENT_OPT_PROGRESS_INFO: @@@ -2351,11 -2354,11 +2376,11 @@@ break; case PHP_HTTP_CLIENT_OPT_AVAILABLE_OPTIONS: - zend_hash_apply_with_arguments(&php_http_curle_options.options TSRMLS_CC, apply_available_options, 1, *(HashTable **) res); + zend_hash_apply_with_arguments(&php_http_curle_options.options, apply_available_options, 1, *(HashTable **) res); break; case PHP_HTTP_CLIENT_OPT_AVAILABLE_CONFIGURATION: - zend_hash_apply_with_arguments(&php_http_curlm_options.options TSRMLS_CC, apply_available_options, 1, *(HashTable **) res); + zend_hash_apply_with_arguments(&php_http_curlm_options.options, apply_available_options, 1, *(HashTable **) res); break; default: @@@ -2390,20 -2393,19 +2415,20 @@@ PHP_MINIT_FUNCTION(http_client_curl { curl_version_info_data *info; php_http_options_t *options; - php_http_client_driver_t driver = { - ZEND_STRL("curl"), - &php_http_client_curl_ops - }; - if (SUCCESS != php_http_client_driver_add(&driver)) { + PHP_HTTP_G->client.curl.driver.driver_name = zend_string_init(ZEND_STRL("curl"), 1); + PHP_HTTP_G->client.curl.driver.client_name = zend_string_init(ZEND_STRL("http\\Client\\Curl"), 1); + PHP_HTTP_G->client.curl.driver.request_name = zend_string_init(ZEND_STRL("http\\Client\\Curl\\Request"), 1); + PHP_HTTP_G->client.curl.driver.client_ops = &php_http_client_curl_ops; + + if (SUCCESS != php_http_client_driver_add(&PHP_HTTP_G->client.curl.driver)) { return FAILURE; } - if (SUCCESS != php_persistent_handle_provide(ZEND_STRL("http\\Client\\Curl"), &php_http_curlm_resource_factory_ops, NULL, NULL TSRMLS_CC)) { + if (SUCCESS != php_persistent_handle_provide(PHP_HTTP_G->client.curl.driver.client_name, &php_http_curlm_resource_factory_ops, NULL, NULL)) { return FAILURE; } - if (SUCCESS != php_persistent_handle_provide(ZEND_STRL("http\\Client\\Curl\\Request"), &php_http_curle_resource_factory_ops, NULL, NULL TSRMLS_CC)) { + if (SUCCESS != php_persistent_handle_provide(PHP_HTTP_G->client.curl.driver.request_name, &php_http_curle_resource_factory_ops, NULL, NULL)) { return FAILURE; } @@@ -2411,13 -2413,13 +2436,13 @@@ options->getter = php_http_curle_get_option; options->setter = php_http_curle_set_option; - php_http_curle_options_init(options TSRMLS_CC); + php_http_curle_options_init(options); } if ((options = php_http_options_init(&php_http_curlm_options, 1))) { options->getter = php_http_option_get; options->setter = php_http_curlm_set_option; - php_http_curlm_options_init(options TSRMLS_CC); + php_http_curlm_options_init(options); } if ((info = curl_version_info(CURLVERSION_NOW))) { @@@ -2556,11 -2558,8 +2581,11 @@@ PHP_MSHUTDOWN_FUNCTION(http_client_curl) { - php_persistent_handle_cleanup(ZEND_STRL("http\\Client\\Curl"), NULL, 0 TSRMLS_CC); - php_persistent_handle_cleanup(ZEND_STRL("http\\Client\\Curl\\Request"), NULL, 0 TSRMLS_CC); + php_persistent_handle_cleanup(PHP_HTTP_G->client.curl.driver.client_name, NULL); + php_persistent_handle_cleanup(PHP_HTTP_G->client.curl.driver.request_name, NULL); + zend_string_release(PHP_HTTP_G->client.curl.driver.client_name); + zend_string_release(PHP_HTTP_G->client.curl.driver.request_name); + zend_string_release(PHP_HTTP_G->client.curl.driver.driver_name); php_http_options_dtor(&php_http_curle_options); php_http_options_dtor(&php_http_curlm_options);