From: Michael Wallner Date: Wed, 10 Aug 2016 13:41:09 +0000 (+0200) Subject: Merge branch 'v2.6.x' X-Git-Tag: RELEASE_3_1_0_BETA1~3 X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-http;a=commitdiff_plain;h=512de8cdaf8a02b4329e0ceb8368cb8f15eba7cb;hp=-c Merge branch 'v2.6.x' --- 512de8cdaf8a02b4329e0ceb8368cb8f15eba7cb diff --combined src/php_http_client.c index b719d2f,05414b5..d0e6e80 --- 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 TSRMLS_CC); + zend_hash_apply_with_argument(&php_http_client_drivers, apply_driver_list, ht); } -void php_http_client_options_set_subr(zval *this_ptr, char *key, size_t len, zval *opts, int overwrite TSRMLS_DC) +static zend_class_entry *php_http_client_class_entry; +zend_class_entry *php_http_client_get_class_entry(void) +{ + return php_http_client_class_entry; +} + +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); } } @@@ -227,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); @@@ -240,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); @@@ -326,13 -323,12 +326,13 @@@ 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) { @@@ -342,91 -338,49 +342,91 @@@ } 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) + 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); } @@@ -436,54 -390,63 +436,56 @@@ 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); - - MAKE_STD_ZVAL(zrequest); - ZVAL_OBJVAL(zrequest, ((php_http_message_object_t *) e->opaque)->zv, 1); + 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); - php_http_message_object_prepend(zresponse, zrequest, 1 TSRMLS_CC); + php_http_message_object_prepend(&zresponse, &zrequest, 1); - 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); + ZVAL_UNDEF(&retval); + zend_fcall_info_argn(&e->closure.fci, 1, &zresponse); + zend_replace_error_handling(EH_NORMAL, NULL, &zeh); + ++client->callback.depth; - zend_fcall_info_call(&e->closure.fci, &e->closure.fcc, &retval, NULL TSRMLS_CC); + zend_fcall_info_call(&e->closure.fci, &e->closure.fcc, &retval, NULL); + --client->callback.depth; - zend_restore_error_handling(&zeh TSRMLS_CC); - zend_fcall_info_argn(&e->closure.fci TSRMLS_CC, 0); + 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); @@@ -505,47 -468,64 +507,51 @@@ 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); + + 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); + ++client->callback.depth; - php_http_object_method_call(&client_obj->notify, zclient, NULL, 2, args TSRMLS_CC); + php_http_object_method_call(&client_obj->notify, &zclient, NULL, 2, args); + --client->callback.depth; - zend_restore_error_handling(&zeh TSRMLS_CC); + 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)) { - ++client_obj->client->callback.depth; - zend_fcall_info_call(&client_obj->debug.fci, &client_obj->debug.fcc, NULL, NULL TSRMLS_CC); - --client_obj->client->callback.depth; + + 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)) { ++ ++client->callback.depth; + zend_fcall_info_call(&client_obj->debug.fci, &client_obj->debug.fcc, NULL, NULL); ++ --client->callback.depth; 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); @@@ -556,8 -536,9 +562,8 @@@ 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) @@@ -566,40 -547,45 +572,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; @@@ -616,7 -602,7 +622,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); @@@ -624,19 -610,18 +630,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; } @@@ -646,26 -631,28 +652,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); } } } @@@ -683,10 -670,10 +689,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); @@@ -694,20 -681,20 +700,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); @@@ -726,10 -713,10 +732,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); @@@ -754,30 -741,30 +760,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); @@@ -791,10 -778,10 +797,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)); } @@@ -808,20 -795,20 +814,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); } } @@@ -836,7 -823,7 +842,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); } } @@@ -846,11 -833,11 +852,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); } @@@ -862,7 -849,7 +868,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); @@@ -874,7 -861,7 +880,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)); } @@@ -887,9 -874,9 +893,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; @@@ -906,8 -893,8 +912,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); @@@ -922,9 -909,9 +928,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); @@@ -939,9 -926,9 +945,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); @@@ -950,21 -937,20 +956,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) @@@ -972,14 -958,14 +978,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); @@@ -988,26 -974,31 +994,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); } } @@@ -1019,13 -1010,13 +1025,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); @@@ -1033,12 -1024,13 +1039,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); } @@@ -1048,20 -1040,21 +1054,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); } @@@ -1070,11 -1063,11 +1076,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); @@@ -1094,17 -1087,17 +1100,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); @@@ -1121,10 -1114,10 +1127,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); @@@ -1138,9 -1131,9 +1144,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); } @@@ -1150,7 -1143,7 +1156,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); } } @@@ -1162,9 -1155,9 +1168,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); } @@@ -1176,9 -1169,9 +1182,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); } @@@ -1188,7 -1181,7 +1194,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); } } @@@ -1199,9 -1192,9 +1205,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); } @@@ -1213,9 -1206,9 +1219,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); } @@@ -1225,17 -1218,16 +1231,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)); } } @@@ -1244,7 -1236,7 +1250,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)); @@@ -1256,7 -1248,7 +1262,7 @@@ 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)); @@@ -1273,9 -1265,9 +1279,9 @@@ static PHP_METHOD(HttpClient, setDebug 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); @@@ -1284,7 -1276,7 +1290,7 @@@ 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 { @@@ -1336,27 -1328,24 +1342,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 08743e6,8c526bd..0edd1bb --- 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 { @@@ -117,28 -116,33 +117,29 @@@ typedef struct php_http_client php_http_client_debug_callback_t func; void *arg; } debug; + unsigned depth; } 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 be04be8,1ec6624..1e92fbe --- 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; } @@@ -177,22 -182,19 +177,19 @@@ static int php_http_curle_progress_call #endif { php_http_client_curl_handler_t *h = ctx; - zend_bool update = 0; if (h->progress.dl.total != dltotal || h->progress.dl.now != dlnow || h->progress.ul.total != ultotal || h->progress.ul.now != ulnow ) { - update = 1; - h->progress.dl.total = dltotal; h->progress.dl.now = dlnow; h->progress.ul.total = ultotal; h->progress.ul.now = ulnow; } - if (update && h->client->callback.progress.func) { + if (h->client->callback.progress.func) { h->client->callback.progress.func(h->client->callback.progress.arg, h->client, &h->queue, &h->progress); } @@@ -202,6 -204,7 +199,6 @@@ 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; @@@ -320,161 -323,131 +317,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 @@@ -482,14 -455,16 +479,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: @@@ -501,13 -476,13 +498,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; @@@ -518,12 -493,12 +515,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; @@@ -554,9 -529,9 +551,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 @@@ -564,41 -539,41 +561,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; @@@ -609,14 -584,14 +606,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, @@@ -641,24 -616,20 +638,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); @@@ -671,6 -642,7 +668,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); @@@ -693,7 -665,7 +690,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); @@@ -707,7 -679,7 +704,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); } @@@ -721,6 -693,7 +718,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"); @@@ -731,7 -704,7 +728,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); @@@ -750,7 -723,7 +747,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; @@@ -761,10 -734,10 +758,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; } @@@ -782,7 -755,7 +779,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; @@@ -800,12 -773,11 +797,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; @@@ -814,20 -786,19 +811,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) { @@@ -849,7 -820,7 +846,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; } @@@ -857,6 -828,7 +854,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) { @@@ -864,7 -836,7 +861,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; } } @@@ -889,7 -861,7 +886,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; @@@ -900,7 -872,7 +897,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)); @@@ -915,29 -887,32 +912,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; @@@ -1000,16 -975,26 +997,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; @@@ -1027,28 -1012,26 +1024,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)) { @@@ -1067,18 -1050,18 +1064,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; @@@ -1116,13 -1099,13 +1113,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 */ @@@ -1135,7 -1118,7 +1132,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 @@@ -1206,8 -1189,8 +1203,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); @@@ -1241,7 -1224,7 +1238,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 @@@ -1258,17 -1241,18 +1255,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 */ @@@ -1287,7 -1271,7 +1284,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; } @@@ -1297,7 -1281,7 +1294,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); } @@@ -1306,7 -1290,7 +1303,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 */ @@@ -1338,9 -1322,9 +1335,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; } @@@ -1360,7 -1344,7 +1357,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; @@@ -1368,36 -1352,36 +1365,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))) { @@@ -1421,15 -1405,13 +1418,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 @@@ -1452,7 -1434,7 +1449,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 } } @@@ -1464,12 -1446,8 +1461,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; } @@@ -1481,16 -1459,17 +1478,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; @@@ -1506,15 -1485,11 +1503,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; } @@@ -1553,7 -1528,7 +1550,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; } @@@ -1566,10 -1541,12 +1563,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 *)); @@@ -1579,11 -1556,9 +1576,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)) { @@@ -1629,11 -1604,12 +1626,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 } @@@ -1647,14 -1623,15 +1644,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; @@@ -1667,21 -1644,22 +1664,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; @@@ -1705,7 -1683,7 +1702,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); @@@ -1731,14 -1709,14 +1728,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 } @@@ -1751,43 -1729,39 +1748,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; @@@ -1856,9 -1830,10 +1853,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; } @@@ -1866,7 -1841,7 +1863,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); @@@ -1908,10 -1883,11 +1905,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'; @@@ -1927,33 -1903,34 +1924,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); @@@ -2003,7 -1980,7 +2000,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; } @@@ -2026,9 -2003,11 +2023,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); @@@ -2037,32 -2016,21 +2034,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; } @@@ -2077,6 -2045,7 +2074,6 @@@ 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); @@@ -2084,7 -2053,7 +2081,7 @@@ } 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; @@@ -2101,38 -2070,37 +2098,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) { @@@ -2151,8 -2119,9 +2148,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; } @@@ -2173,7 -2142,7 +2170,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; } @@@ -2194,13 -2163,19 +2191,18 @@@ 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); + if (h->callback.depth) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not dequeue request while executing callbacks"); ++ php_error_docref(NULL, E_WARNING, "Could not dequeue request while executing callbacks"); + return FAILURE; + } + 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; @@@ -2273,6 -2248,7 +2275,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); @@@ -2282,9 -2258,9 +2284,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; } @@@ -2322,31 -2298,34 +2324,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; @@@ -2355,6 -2334,7 +2357,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: @@@ -2376,11 -2356,11 +2378,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: @@@ -2415,20 -2395,19 +2417,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; } @@@ -2436,13 -2415,13 +2438,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))) { @@@ -2581,11 -2560,8 +2583,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); diff --combined src/php_http_url.c index 8352608,9140c68..1520ae9 --- a/src/php_http_url.c +++ b/src/php_http_url.c @@@ -61,7 -61,7 +61,7 @@@ static inline char *localhostname(void #define url(buf) ((php_http_url_t *) (buf).data) -static php_http_url_t *php_http_url_from_env(TSRMLS_D) +static php_http_url_t *php_http_url_from_env(void) { zval *https, *zhost, *zport; long port; @@@ -73,7 -73,7 +73,7 @@@ /* scheme */ url(buf)->scheme = &buf.data[buf.used]; - https = php_http_env_get_server_var(ZEND_STRL("HTTPS"), 1 TSRMLS_CC); + https = php_http_env_get_server_var(ZEND_STRL("HTTPS"), 1); if (https && !strcasecmp(Z_STRVAL_P(https), "ON")) { php_http_buffer_append(&buf, "https", sizeof("https")); } else { @@@ -82,9 -82,9 +82,9 @@@ /* host */ url(buf)->host = &buf.data[buf.used]; - if ((((zhost = php_http_env_get_server_var(ZEND_STRL("HTTP_HOST"), 1 TSRMLS_CC)) || - (zhost = php_http_env_get_server_var(ZEND_STRL("SERVER_NAME"), 1 TSRMLS_CC)) || - (zhost = php_http_env_get_server_var(ZEND_STRL("SERVER_ADDR"), 1 TSRMLS_CC)))) && Z_STRLEN_P(zhost)) { + if ((((zhost = php_http_env_get_server_var(ZEND_STRL("HTTP_HOST"), 1)) || + (zhost = php_http_env_get_server_var(ZEND_STRL("SERVER_NAME"), 1)) || + (zhost = php_http_env_get_server_var(ZEND_STRL("SERVER_ADDR"), 1)))) && Z_STRLEN_P(zhost)) { size_t stop_at = strspn(Z_STRVAL_P(zhost), "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ-."); php_http_buffer_append(&buf, Z_STRVAL_P(zhost), stop_at); @@@ -97,7 -97,7 +97,7 @@@ } /* port */ - zport = php_http_env_get_server_var(ZEND_STRL("SERVER_PORT"), 1 TSRMLS_CC); + zport = php_http_env_get_server_var(ZEND_STRL("SERVER_PORT"), 1); if (zport && IS_LONG == is_numeric_string(Z_STRVAL_P(zport), Z_STRLEN_P(zport), &port, NULL, 0)) { url(buf)->port = port; } @@@ -154,7 -154,7 +154,7 @@@ } \ } while (0) -php_http_url_t *php_http_url_mod(const php_http_url_t *old_url, const php_http_url_t *new_url, unsigned flags TSRMLS_DC) +php_http_url_t *php_http_url_mod(const php_http_url_t *old_url, const php_http_url_t *new_url, unsigned flags) { php_http_url_t *tmp_url = NULL; php_http_buffer_t buf; @@@ -165,9 -165,9 +165,9 @@@ /* set from env if requested */ if (flags & PHP_HTTP_URL_FROM_ENV) { - php_http_url_t *env_url = php_http_url_from_env(TSRMLS_C); + php_http_url_t *env_url = php_http_url_from_env(); - old_url = tmp_url = php_http_url_mod(env_url, old_url, flags ^ PHP_HTTP_URL_FROM_ENV TSRMLS_CC); + old_url = tmp_url = php_http_url_mod(env_url, old_url, flags ^ PHP_HTTP_URL_FROM_ENV); php_http_url_free(&env_url); } @@@ -228,17 -228,17 +228,17 @@@ if ((flags & PHP_HTTP_URL_JOIN_QUERY) && url_isset(new_url, query) && url_isset(old_url, query)) { zval qarr, qstr; - INIT_PZVAL(&qstr); - INIT_PZVAL(&qarr); array_init(&qarr); - ZVAL_STRING(&qstr, old_url->query, 0); - php_http_querystring_update(&qarr, &qstr, NULL TSRMLS_CC); - ZVAL_STRING(&qstr, new_url->query, 0); - php_http_querystring_update(&qarr, &qstr, NULL TSRMLS_CC); + ZVAL_STRING(&qstr, old_url->query); + php_http_querystring_update(&qarr, &qstr, NULL); + zval_ptr_dtor(&qstr); + ZVAL_STRING(&qstr, new_url->query); + php_http_querystring_update(&qarr, &qstr, NULL); + zval_ptr_dtor(&qstr); ZVAL_NULL(&qstr); - php_http_querystring_update(&qarr, NULL, &qstr TSRMLS_CC); + php_http_querystring_update(&qarr, NULL, &qstr); url(buf)->query = &buf.data[buf.used]; url_append(&buf, php_http_buffer_append(&buf, Z_STRVAL(qstr), Z_STRLEN(qstr) + 1)); @@@ -423,9 -423,9 +423,9 @@@ char *php_http_url_authority_to_string( return buf.data; } -php_http_url_t *php_http_url_from_zval(zval *value, unsigned flags TSRMLS_DC) +php_http_url_t *php_http_url_from_zval(zval *value, unsigned flags) { - zval *zcpy; + zend_string *zs; php_http_url_t *purl; switch (Z_TYPE_P(value)) { @@@ -435,9 -435,9 +435,9 @@@ break; default: - zcpy = php_http_ztyp(IS_STRING, value); - purl = php_http_url_parse(Z_STRVAL_P(zcpy), Z_STRLEN_P(zcpy), flags TSRMLS_CC); - zval_ptr_dtor(&zcpy); + zs = zval_get_string(value); + purl = php_http_url_parse(zs->val, zs->len, flags); + zend_string_release(zs); } return purl; @@@ -445,66 -445,67 +445,66 @@@ php_http_url_t *php_http_url_from_struct(HashTable *ht) { - zval **e; + zval *e; php_http_buffer_t buf; php_http_buffer_init_ex(&buf, MAX(PHP_HTTP_BUFFER_DEFAULT_SIZE, sizeof(php_http_url_t)<<2), PHP_HTTP_BUFFER_INIT_PREALLOC); php_http_buffer_account(&buf, sizeof(php_http_url_t)); memset(buf.data, 0, buf.used); - if (SUCCESS == zend_hash_find(ht, "scheme", sizeof("scheme"), (void *) &e)) { - zval *cpy = php_http_ztyp(IS_STRING, *e); + if ((e = zend_hash_str_find_ind(ht, ZEND_STRL("scheme")))) { + zend_string *zs = zval_get_string(e); url(buf)->scheme = &buf.data[buf.used]; - url_append(&buf, php_http_buffer_append(&buf, Z_STRVAL_P(cpy), Z_STRLEN_P(cpy) + 1)); - zval_ptr_dtor(&cpy); + url_append(&buf, php_http_buffer_append(&buf, zs->val, zs->len + 1)); + zend_string_release(zs); } - if (SUCCESS == zend_hash_find(ht, "user", sizeof("user"), (void *) &e)) { - zval *cpy = php_http_ztyp(IS_STRING, *e); + if ((e = zend_hash_str_find_ind(ht, ZEND_STRL("user")))) { + zend_string *zs = zval_get_string(e); url(buf)->user = &buf.data[buf.used]; - url_append(&buf, php_http_buffer_append(&buf, Z_STRVAL_P(cpy), Z_STRLEN_P(cpy) + 1)); - zval_ptr_dtor(&cpy); + url_append(&buf, php_http_buffer_append(&buf, zs->val, zs->len + 1)); + zend_string_release(zs); } - if (SUCCESS == zend_hash_find(ht, "pass", sizeof("pass"), (void *) &e)) { - zval *cpy = php_http_ztyp(IS_STRING, *e); + if ((e = zend_hash_str_find_ind(ht, ZEND_STRL("pass")))) { + zend_string *zs = zval_get_string(e); url(buf)->pass = &buf.data[buf.used]; - url_append(&buf, php_http_buffer_append(&buf, Z_STRVAL_P(cpy), Z_STRLEN_P(cpy) + 1)); - zval_ptr_dtor(&cpy); + url_append(&buf, php_http_buffer_append(&buf, zs->val, zs->len + 1)); + zend_string_release(zs); } - if (SUCCESS == zend_hash_find(ht, "host", sizeof("host"), (void *) &e)) { - zval *cpy = php_http_ztyp(IS_STRING, *e); + if ((e = zend_hash_str_find_ind(ht, ZEND_STRL("host")))) { + zend_string *zs = zval_get_string(e); url(buf)->host = &buf.data[buf.used]; - url_append(&buf, php_http_buffer_append(&buf, Z_STRVAL_P(cpy), Z_STRLEN_P(cpy) + 1)); - zval_ptr_dtor(&cpy); + url_append(&buf, php_http_buffer_append(&buf, zs->val, zs->len + 1)); + zend_string_release(zs); } - if (SUCCESS == zend_hash_find(ht, "port", sizeof("port"), (void *) &e)) { - zval *cpy = php_http_ztyp(IS_LONG, *e); - url(buf)->port = (unsigned short) Z_LVAL_P(cpy); - zval_ptr_dtor(&cpy); + if ((e = zend_hash_str_find_ind(ht, ZEND_STRL("port")))) { + url(buf)->port = (unsigned short) zval_get_long(e); } - if (SUCCESS == zend_hash_find(ht, "path", sizeof("path"), (void *) &e)) { - zval *cpy = php_http_ztyp(IS_STRING, *e); + if ((e = zend_hash_str_find_ind(ht, ZEND_STRL("path")))) { + zend_string *zs = zval_get_string(e); url(buf)->path = &buf.data[buf.used]; - url_append(&buf, php_http_buffer_append(&buf, Z_STRVAL_P(cpy), Z_STRLEN_P(cpy) + 1)); - zval_ptr_dtor(&cpy); + url_append(&buf, php_http_buffer_append(&buf, zs->val, zs->len + 1)); + zend_string_release(zs); } - if (SUCCESS == zend_hash_find(ht, "query", sizeof("query"), (void *) &e)) { - zval *cpy = php_http_ztyp(IS_STRING, *e); + if ((e = zend_hash_str_find_ind(ht, ZEND_STRL("query")))) { + zend_string *zs = zval_get_string(e); url(buf)->query = &buf.data[buf.used]; - url_append(&buf, php_http_buffer_append(&buf, Z_STRVAL_P(cpy), Z_STRLEN_P(cpy) + 1)); - zval_ptr_dtor(&cpy); + url_append(&buf, php_http_buffer_append(&buf, zs->val, zs->len + 1)); + zend_string_release(zs); } - if (SUCCESS == zend_hash_find(ht, "fragment", sizeof("fragment"), (void *) &e)) { - zval *cpy = php_http_ztyp(IS_STRING, *e); + if ((e = zend_hash_str_find_ind(ht, ZEND_STRL("fragment")))) { + zend_string *zs = zval_get_string(e); url(buf)->fragment = &buf.data[buf.used]; - url_append(&buf, php_http_buffer_append(&buf, Z_STRVAL_P(cpy), Z_STRLEN_P(cpy) + 1)); - zval_ptr_dtor(&cpy); + url_append(&buf, php_http_buffer_append(&buf, zs->val, zs->len + 1)); + zend_string_release(zs); } return url(buf); } -HashTable *php_http_url_to_struct(const php_http_url_t *url, zval *strct TSRMLS_DC) +HashTable *php_http_url_to_struct(const php_http_url_t *url, zval *strct) { - zval arr; + HashTable *ht; + zval tmp; if (strct) { switch (Z_TYPE_P(strct)) { @@@ -514,69 -515,53 +514,69 @@@ /* no break */ case IS_ARRAY: case IS_OBJECT: - INIT_PZVAL_ARRAY((&arr), HASH_OF(strct)); + ht = HASH_OF(strct); break; } } else { - INIT_PZVAL(&arr); - array_init(&arr); + ALLOC_HASHTABLE(ht); + zend_hash_init(ht, 8, NULL, ZVAL_PTR_DTOR, 0); + } + +#define url_struct_add(part) \ + if (Z_TYPE_P(strct) == IS_ARRAY) { \ + zend_hash_str_update(Z_ARRVAL_P(strct), part, lenof(part), &tmp); \ + } else { \ + zend_update_property(Z_OBJCE_P(strct), strct, part, lenof(part), &tmp); \ + zval_ptr_dtor(&tmp); \ } if (url) { if (url->scheme) { - add_assoc_string(&arr, "scheme", url->scheme, 1); + ZVAL_STRING(&tmp, url->scheme); + url_struct_add("scheme"); } if (url->user) { - add_assoc_string(&arr, "user", url->user, 1); + ZVAL_STRING(&tmp, url->user); + url_struct_add("user"); } if (url->pass) { - add_assoc_string(&arr, "pass", url->pass, 1); + ZVAL_STRING(&tmp, url->pass); + url_struct_add("pass"); } if (url->host) { - add_assoc_string(&arr, "host", url->host, 1); + ZVAL_STRING(&tmp, url->host); + url_struct_add("host"); } if (url->port) { - add_assoc_long(&arr, "port", (long) url->port); + ZVAL_LONG(&tmp, url->port); + url_struct_add("port"); } if (url->path) { - add_assoc_string(&arr, "path", url->path, 1); + ZVAL_STRING(&tmp, url->path); + url_struct_add("path"); } if (url->query) { - add_assoc_string(&arr, "query", url->query, 1); + ZVAL_STRING(&tmp, url->query); + url_struct_add("query"); } if (url->fragment) { - add_assoc_string(&arr, "fragment", url->fragment, 1); + ZVAL_STRING(&tmp, url->fragment); + url_struct_add("fragment"); } } - return Z_ARRVAL(arr); + return ht; } -ZEND_RESULT_CODE php_http_url_encode_hash(HashTable *hash, const char *pre_encoded_str, size_t pre_encoded_len, char **encoded_str, size_t *encoded_len TSRMLS_DC) +ZEND_RESULT_CODE php_http_url_encode_hash(HashTable *hash, const char *pre_encoded_str, size_t pre_encoded_len, char **encoded_str, size_t *encoded_len) { const char *arg_sep_str = "&"; size_t arg_sep_len = 1; php_http_buffer_t *qstr = php_http_buffer_new(); - php_http_url_argsep(&arg_sep_str, &arg_sep_len TSRMLS_CC); + php_http_url_argsep(&arg_sep_str, &arg_sep_len); - if (SUCCESS != php_http_url_encode_hash_ex(hash, qstr, arg_sep_str, arg_sep_len, "=", 1, pre_encoded_str, pre_encoded_len TSRMLS_CC)) { + if (SUCCESS != php_http_url_encode_hash_ex(hash, qstr, arg_sep_str, arg_sep_len, "=", 1, pre_encoded_str, pre_encoded_len)) { php_http_buffer_free(&qstr); return FAILURE; } @@@ -587,13 -572,13 +587,13 @@@ return SUCCESS; } -ZEND_RESULT_CODE php_http_url_encode_hash_ex(HashTable *hash, php_http_buffer_t *qstr, const char *arg_sep_str, size_t arg_sep_len, const char *val_sep_str, size_t val_sep_len, const char *pre_encoded_str, size_t pre_encoded_len TSRMLS_DC) +ZEND_RESULT_CODE php_http_url_encode_hash_ex(HashTable *hash, php_http_buffer_t *qstr, const char *arg_sep_str, size_t arg_sep_len, const char *val_sep_str, size_t val_sep_len, const char *pre_encoded_str, size_t pre_encoded_len) { if (pre_encoded_len && pre_encoded_str) { php_http_buffer_append(qstr, pre_encoded_str, pre_encoded_len); } - if (!php_http_params_to_string(qstr, hash, arg_sep_str, arg_sep_len, "", 0, val_sep_str, val_sep_len, PHP_HTTP_PARAMS_QUERY TSRMLS_CC)) { + if (!php_http_params_to_string(qstr, hash, arg_sep_str, arg_sep_len, "", 0, val_sep_str, val_sep_len, PHP_HTTP_PARAMS_QUERY)) { return FAILURE; } @@@ -602,6 -587,9 +602,6 @@@ struct parse_state { php_http_url_t url; -#ifdef ZTS - void ***ts; -#endif const char *ptr; const char *end; size_t maxlen; @@@ -760,12 -748,13 +760,12 @@@ static size_t parse_mb(struct parse_sta } if (!silent) { - TSRMLS_FETCH_FROM_CTX(state->ts); if (consumed) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, + php_error_docref(NULL, E_WARNING, "Failed to parse %s; unexpected multibyte sequence 0x%x at pos %u in '%s'", parse_what[what], wchar, (unsigned) (ptr - begin), begin); } else { - php_error_docref(NULL TSRMLS_CC, E_WARNING, + php_error_docref(NULL, E_WARNING, "Failed to parse %s; unexpected byte 0x%02x at pos %u in '%s'", parse_what[what], (unsigned char) *ptr, (unsigned) (ptr - begin), begin); } @@@ -778,6 -767,7 +778,6 @@@ static ZEND_RESULT_CODE parse_userinfo( { size_t mb; const char *password = NULL, *end = state->ptr, *tmp = ptr; - TSRMLS_FETCH_FROM_CTX(state->ts); state->url.user = &state->buffer[state->offset]; @@@ -785,7 -775,7 +785,7 @@@ switch (*ptr) { case ':': if (password) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, + php_error_docref(NULL, E_WARNING, "Failed to parse password; duplicate ':' at pos %u in '%s'", (unsigned) (ptr - tmp), tmp); return FAILURE; @@@ -797,7 -787,7 +797,7 @@@ case '%': if (ptr[1] != '%' && (end - ptr <= 2 || !isxdigit(*(ptr+1)) || !isxdigit(*(ptr+2)))) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, + php_error_docref(NULL, E_WARNING, "Failed to parse userinfo; invalid percent encoding at pos %u in '%s'", (unsigned) (ptr - tmp), tmp); return FAILURE; @@@ -840,7 -830,7 +840,7 @@@ #if defined(PHP_WIN32) || defined(HAVE_UIDNA_IDNTOASCII) typedef size_t (*parse_mb_func)(unsigned *wc, const char *ptr, const char *end); -static ZEND_RESULT_CODE to_utf16(parse_mb_func fn, const char *u8, uint16_t **u16, size_t *len TSRMLS_DC) +static ZEND_RESULT_CODE to_utf16(parse_mb_func fn, const char *u8, uint16_t **u16, size_t *len) { size_t offset = 0, u8_len = strlen(u8); @@@ -854,7 -844,7 +854,7 @@@ if (!consumed) { efree(*u16); - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to parse UTF-8 at pos %zu of '%s'", offset, u8); + php_error_docref(NULL, E_WARNING, "Failed to parse UTF-8 at pos %zu of '%s'", offset, u8); return FAILURE; } else { offset += consumed; @@@ -870,7 -860,7 +870,7 @@@ case 0: default: efree(*u16); - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to convert UTF-32 'U+%X' to UTF-16", wc); + php_error_docref(NULL, E_WARNING, "Failed to convert UTF-32 'U+%X' to UTF-16", wc); return FAILURE; } } @@@ -888,6 -878,7 +888,6 @@@ static ZEND_RESULT_CODE parse_idn2(stru { char *idn = NULL; int rv = -1; - TSRMLS_FETCH_FROM_CTX(state->ts); if (state->flags & PHP_HTTP_URL_PARSE_MBUTF8) { rv = idn2_lookup_u8((const unsigned char *) state->url.host, (unsigned char **) &idn, IDN2_NFC_INPUT); @@@ -898,7 -889,7 +898,7 @@@ } # endif if (rv != IDN2_OK) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to parse IDN; %s", idn2_strerror(rv)); + php_error_docref(NULL, E_WARNING, "Failed to parse IDN; %s", idn2_strerror(rv)); return FAILURE; } else { size_t idnlen = strlen(idn); @@@ -913,6 -904,7 +913,6 @@@ static ZEND_RESULT_CODE parse_idn(struc { char *idn = NULL; int rv = -1; - TSRMLS_FETCH_FROM_CTX(state->ts); if (state->flags & PHP_HTTP_URL_PARSE_MBUTF8) { rv = idna_to_ascii_8z(state->url.host, &idn, IDNA_ALLOW_UNASSIGNED|IDNA_USE_STD3_ASCII_RULES); @@@ -923,7 -915,7 +923,7 @@@ } # endif if (rv != IDNA_SUCCESS) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to parse IDN; %s", idna_strerror(rv)); + php_error_docref(NULL, E_WARNING, "Failed to parse IDN; %s", idna_strerror(rv)); return FAILURE; } else { size_t idnlen = strlen(idn); @@@ -949,19 -941,20 +949,19 @@@ static ZEND_RESULT_CODE parse_uidn(stru uint16_t *uhost_str, ahost_str[MAXHOSTNAMELEN], *ahost_ptr; size_t uhost_len, ahost_len; UErrorCode error = U_ZERO_ERROR; - TSRMLS_FETCH_FROM_CTX(state->ts); if (state->flags & PHP_HTTP_URL_PARSE_MBUTF8) { - if (SUCCESS != to_utf16(parse_mb_utf8, state->url.host, &uhost_str, &uhost_len TSRMLS_CC)) { + if (SUCCESS != to_utf16(parse_mb_utf8, state->url.host, &uhost_str, &uhost_len)) { return FAILURE; } #ifdef PHP_HTTP_HAVE_WCHAR } else if (state->flags & PHP_HTTP_URL_PARSE_MBLOC) { - if (SUCCESS != to_utf16(parse_mb_loc, state->url.host, &uhost_str, &uhost_len TSRMLS_CC)) { + if (SUCCESS != to_utf16(parse_mb_loc, state->url.host, &uhost_str, &uhost_len)) { return FAILURE; } #endif } else { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to parse IDN; codepage not specified"); + php_error_docref(NULL, E_WARNING, "Failed to parse IDN; codepage not specified"); return FAILURE; } @@@ -969,7 -962,7 +969,7 @@@ efree(uhost_str); if (error != U_ZERO_ERROR) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to parse IDN; ICU error %d", error); + php_error_docref(NULL, E_WARNING, "Failed to parse IDN; ICU error %d", error); return FAILURE; } @@@ -990,27 -983,28 +990,27 @@@ static ZEND_RESULT_CODE parse_widn(stru char *host_ptr; uint16_t *uhost_str, ahost_str[MAXHOSTNAMELEN], *ahost_ptr; size_t uhost_len; - TSRMLS_FETCH_FROM_CTX(state->ts); if (state->flags & PHP_HTTP_URL_PARSE_MBUTF8) { if (SUCCESS != to_utf16(parse_mb_utf8, state->url.host, &uhost_str, &uhost_len)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to parse IDN"); + php_error_docref(NULL, E_WARNING, "Failed to parse IDN"); return FAILURE; } #ifdef PHP_HTTP_HAVE_WCHAR } else if (state->flags & PHP_HTTP_URL_PARSE_MBLOC) { if (SUCCESS != to_utf16(parse_mb_loc, state->url.host, &uhost_str, &uhost_len)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to parse IDN"); + php_error_docref(NULL, E_WARNING, "Failed to parse IDN"); return FAILURE; } #endif } else { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to parse IDN"); + php_error_docref(NULL, E_WARNING, "Failed to parse IDN"); return FAILURE; } if (!IdnToAscii(IDN_ALLOW_UNASSIGNED|IDN_USE_STD3_ASCII_RULES, uhost_str, uhost_len, ahost_str, MAXHOSTNAMELEN)) { efree(uhost_str); - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to parse IDN"); + php_error_docref(NULL, E_WARNING, "Failed to parse IDN"); return FAILURE; } @@@ -1031,6 -1025,7 +1031,6 @@@ static const char *parse_ip6(struct parse_state *state, const char *ptr) { const char *error = NULL, *end = state->ptr, *tmp = memchr(ptr, ']', end - ptr); - TSRMLS_FETCH_FROM_CTX(state->ts); if (tmp) { size_t addrlen = tmp - ptr + 1; @@@ -1056,7 -1051,7 +1056,7 @@@ } if (error) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to parse hostinfo; %s", error); + php_error_docref(NULL, E_WARNING, "Failed to parse hostinfo; %s", error); return NULL; } @@@ -1068,6 -1063,7 +1068,6 @@@ static ZEND_RESULT_CODE parse_hostinfo( { size_t mb, len; const char *end = state->ptr, *tmp = ptr, *port = NULL, *label = NULL; - TSRMLS_FETCH_FROM_CTX(state->ts); #ifdef HAVE_INET_PTON if (*ptr == '[' && !(ptr = parse_ip6(state, ptr))) { @@@ -1079,7 -1075,7 +1079,7 @@@ switch (*ptr) { case ':': if (port) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, + php_error_docref(NULL, E_WARNING, "Failed to parse port; unexpected ':' at pos %u in '%s'", (unsigned) (ptr - tmp), tmp); return FAILURE; @@@ -1089,7 -1085,7 +1089,7 @@@ case '%': if (ptr[1] != '%' && (end - ptr <= 2 || !isxdigit(*(ptr+1)) || !isxdigit(*(ptr+2)))) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, + php_error_docref(NULL, E_WARNING, "Failed to parse hostinfo; invalid percent encoding at pos %u in '%s'", (unsigned) (ptr - tmp), tmp); return FAILURE; @@@ -1104,7 -1100,7 +1104,7 @@@ /* sort of a compromise, just ensure we don't end up * with a dot at the beginning or two consecutive dots */ - php_error_docref(NULL TSRMLS_CC, E_WARNING, + php_error_docref(NULL, E_WARNING, "Failed to parse %s; unexpected '%c' at pos %u in '%s'", port ? "port" : "host", (unsigned char) *ptr, (unsigned) (ptr - tmp), tmp); @@@ -1119,7 -1115,7 +1119,7 @@@ /* sort of a compromise, just ensure we don't end up * with a hyphen at the beginning */ -- php_error_docref(NULL TSRMLS_CC, E_WARNING, ++ php_error_docref(NULL, E_WARNING, "Failed to parse %s; unexpected '%c' at pos %u in '%s'", port ? "port" : "host", (unsigned char) *ptr, (unsigned) (ptr - tmp), tmp); @@@ -1138,7 -1134,7 +1138,7 @@@ case 'o': case 'p': case 'q': case 'r': case 's': case 't': case 'u': case 'v': case 'w': case 'x': case 'y': case 'z': if (port) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, + php_error_docref(NULL, E_WARNING, "Failed to parse port; unexpected char '%c' at pos %u in '%s'", (unsigned char) *ptr, (unsigned) (ptr - tmp), tmp); return FAILURE; @@@ -1160,7 -1156,7 +1160,7 @@@ if (ptr == end) { break; } else if (port) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, + php_error_docref(NULL, E_WARNING, "Failed to parse port; unexpected byte 0x%02x at pos %u in '%s'", (unsigned char) *ptr, (unsigned) (ptr - tmp), tmp); return FAILURE; @@@ -1204,7 -1200,8 +1204,7 @@@ static const char *parse_authority(stru case '@': /* userinfo delimiter */ if (host) { - TSRMLS_FETCH_FROM_CTX(state->ts); - php_error_docref(NULL TSRMLS_CC, E_WARNING, + php_error_docref(NULL, E_WARNING, "Failed to parse userinfo; unexpected '@'"); return NULL; } @@@ -1236,6 -1233,7 +1236,6 @@@ static const char *parse_path(struct pa { size_t mb; const char *tmp; - TSRMLS_FETCH_FROM_CTX(state->ts); /* is there actually a path to parse? */ if (!*state->ptr) { @@@ -1252,7 -1250,7 +1252,7 @@@ case '%': if (state->ptr[1] != '%' && (state->end - state->ptr <= 2 || !isxdigit(*(state->ptr+1)) || !isxdigit(*(state->ptr+2)))) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, + php_error_docref(NULL, E_WARNING, "Failed to parse path; invalid percent encoding at pos %u in '%s'", (unsigned) (state->ptr - tmp), tmp); return NULL; @@@ -1303,6 -1301,7 +1303,6 @@@ static const char *parse_query(struct p { size_t mb; const char *tmp = state->ptr + !!*state->ptr; - TSRMLS_FETCH_FROM_CTX(state->ts); /* is there actually a query to parse? */ if (*state->ptr != '?') { @@@ -1320,7 -1319,7 +1320,7 @@@ case '%': if (state->ptr[1] != '%' && (state->end - state->ptr <= 2 || !isxdigit(*(state->ptr+1)) || !isxdigit(*(state->ptr+2)))) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, + php_error_docref(NULL, E_WARNING, "Failed to parse query; invalid percent encoding at pos %u in '%s'", (unsigned) (state->ptr - tmp), tmp); return NULL; @@@ -1381,6 -1380,7 +1381,6 @@@ static const char *parse_fragment(struc { size_t mb; const char *tmp; - TSRMLS_FETCH_FROM_CTX(state->ts); /* is there actually a fragment to parse? */ if (*state->ptr != '#') { @@@ -1395,7 -1395,7 +1395,7 @@@ switch (*state->ptr) { case '%': if (state->ptr[1] != '%' && (state->end - state->ptr <= 2 || !isxdigit(*(state->ptr+1)) || !isxdigit(*(state->ptr+2)))) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, + php_error_docref(NULL, E_WARNING, "Failed to parse fragment; invalid percent encoding at pos %u in '%s'", (unsigned) (state->ptr - tmp), tmp); return NULL; @@@ -1509,7 -1509,7 +1509,7 @@@ softfail return state->ptr = tmp; } -php_http_url_t *php_http_url_parse(const char *str, size_t len, unsigned flags TSRMLS_DC) +php_http_url_t *php_http_url_parse(const char *str, size_t len, unsigned flags) { size_t maxlen = 3 * len + 8 /* null bytes for all components */; struct parse_state *state = ecalloc(1, sizeof(*state) + maxlen); @@@ -1518,9 -1518,10 +1518,9 @@@ state->ptr = str; state->flags = flags; state->maxlen = maxlen; - TSRMLS_SET_CTX(state->ts); if (!parse_scheme(state)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to parse URL scheme: '%s'", state->ptr); + php_error_docref(NULL, E_WARNING, "Failed to parse URL scheme: '%s'", state->ptr); efree(state); return NULL; } @@@ -1531,13 -1532,13 +1531,13 @@@ } if (!parse_query(state)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to parse URL query: '%s'", state->ptr); + php_error_docref(NULL, E_WARNING, "Failed to parse URL query: '%s'", state->ptr); efree(state); return NULL; } if (!parse_fragment(state)) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, "Failed to parse URL fragment: '%s'", state->ptr); + php_error_docref(NULL, E_WARNING, "Failed to parse URL fragment: '%s'", state->ptr); efree(state); return NULL; } @@@ -1545,7 -1546,7 +1545,7 @@@ return (php_http_url_t *) state; } -php_http_url_t *php_http_url_parse_authority(const char *str, size_t len, unsigned flags TSRMLS_DC) +php_http_url_t *php_http_url_parse_authority(const char *str, size_t len, unsigned flags) { size_t maxlen = 3 * len; struct parse_state *state = ecalloc(1, sizeof(*state) + maxlen); @@@ -1554,6 -1555,7 +1554,6 @@@ state->ptr = str; state->flags = flags; state->maxlen = maxlen; - TSRMLS_SET_CTX(state->ts); if (!(state->ptr = parse_authority(state))) { efree(state); @@@ -1561,7 -1563,7 +1561,7 @@@ } if (state->ptr != state->end) { - php_error_docref(NULL TSRMLS_CC, E_WARNING, + php_error_docref(NULL, E_WARNING, "Failed to parse URL authority, unexpected character at pos %u in '%s'", (unsigned) (state->ptr - str), str); efree(state); @@@ -1571,19 -1573,6 +1571,19 @@@ return (php_http_url_t *) state; } +static zend_class_entry *php_http_url_class_entry; +static zend_class_entry *php_http_env_url_class_entry; + +zend_class_entry *php_http_url_get_class_entry(void) +{ + return php_http_url_class_entry; +} + +zend_class_entry *php_http_get_env_url_class_entry(void) +{ + return php_http_env_url_class_entry; +} + ZEND_BEGIN_ARG_INFO_EX(ai_HttpUrl___construct, 0, 0, 0) ZEND_ARG_INFO(0, old_url) ZEND_ARG_INFO(0, new_url) @@@ -1592,40 -1581,35 +1592,40 @@@ ZEND_END_ARG_INFO() PHP_METHOD(HttpUrl, __construct) { zval *new_url = NULL, *old_url = NULL; - long flags = PHP_HTTP_URL_FROM_ENV; + zend_long flags = 0; zend_error_handling zeh; - php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|z!z!l", &old_url, &new_url, &flags), invalid_arg, return); + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "|z!z!l", &old_url, &new_url, &flags), invalid_arg, return); - zend_replace_error_handling(EH_THROW, php_http_exception_bad_url_class_entry, &zeh TSRMLS_CC); + /* always set http\Url::FROM_ENV for instances of http\Env\Url */ + if (instanceof_function(Z_OBJCE_P(getThis()), php_http_env_url_class_entry)) { + flags |= PHP_HTTP_URL_FROM_ENV; + } + + zend_replace_error_handling(EH_THROW, php_http_get_exception_bad_url_class_entry(), &zeh); { php_http_url_t *res_purl, *new_purl = NULL, *old_purl = NULL; if (new_url) { - new_purl = php_http_url_from_zval(new_url, flags TSRMLS_CC); + new_purl = php_http_url_from_zval(new_url, flags); if (!new_purl) { - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_restore_error_handling(&zeh); return; } } if (old_url) { - old_purl = php_http_url_from_zval(old_url, flags TSRMLS_CC); + old_purl = php_http_url_from_zval(old_url, flags); if (!old_purl) { if (new_purl) { php_http_url_free(&new_purl); } - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_restore_error_handling(&zeh); return; } } - res_purl = php_http_url_mod(old_purl, new_purl, flags TSRMLS_CC); - php_http_url_to_struct(res_purl, getThis() TSRMLS_CC); + res_purl = php_http_url_mod(old_purl, new_purl, flags); + php_http_url_to_struct(res_purl, getThis()); php_http_url_free(&res_purl); if (old_purl) { @@@ -1635,7 -1619,7 +1635,7 @@@ php_http_url_free(&new_purl); } } - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_restore_error_handling(&zeh); } ZEND_BEGIN_ARG_INFO_EX(ai_HttpUrl_mod, 0, 0, 1) @@@ -1645,19 -1629,19 +1645,19 @@@ ZEND_END_ARG_INFO() PHP_METHOD(HttpUrl, mod) { zval *new_url = NULL; - long flags = PHP_HTTP_URL_JOIN_PATH | PHP_HTTP_URL_JOIN_QUERY | PHP_HTTP_URL_SANITIZE_PATH; + zend_long flags = PHP_HTTP_URL_JOIN_PATH | PHP_HTTP_URL_JOIN_QUERY | PHP_HTTP_URL_SANITIZE_PATH; zend_error_handling zeh; - php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z!|l", &new_url, &flags), invalid_arg, return); + php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "z!|l", &new_url, &flags), invalid_arg, return); - zend_replace_error_handling(EH_THROW, php_http_exception_bad_url_class_entry, &zeh TSRMLS_CC); + zend_replace_error_handling(EH_THROW, php_http_get_exception_bad_url_class_entry(), &zeh); { php_http_url_t *new_purl = NULL, *old_purl = NULL; if (new_url) { - new_purl = php_http_url_from_zval(new_url, flags TSRMLS_CC); + new_purl = php_http_url_from_zval(new_url, flags); if (!new_purl) { - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_restore_error_handling(&zeh); return; } } @@@ -1665,10 -1649,10 +1665,10 @@@ if ((old_purl = php_http_url_from_struct(HASH_OF(getThis())))) { php_http_url_t *res_purl; - ZVAL_OBJVAL(return_value, zend_objects_clone_obj(getThis() TSRMLS_CC), 0); + ZVAL_OBJ(return_value, zend_objects_clone_obj(getThis())); - res_purl = php_http_url_mod(old_purl, new_purl, flags TSRMLS_CC); - php_http_url_to_struct(res_purl, return_value TSRMLS_CC); + res_purl = php_http_url_mod(old_purl, new_purl, flags); + php_http_url_to_struct(res_purl, return_value); php_http_url_free(&res_purl); php_http_url_free(&old_purl); @@@ -1677,7 -1661,7 +1677,7 @@@ php_http_url_free(&new_purl); } } - zend_restore_error_handling(&zeh TSRMLS_CC); + zend_restore_error_handling(&zeh); } ZEND_BEGIN_ARG_INFO_EX(ai_HttpUrl_toString, 0, 0, 0) @@@ -1693,7 -1677,7 +1693,7 @@@ PHP_METHOD(HttpUrl, toString php_http_url_to_string(purl, &str, &len, 0); php_http_url_free(&purl); - RETURN_STRINGL(str, len, 0); + RETURN_STR(php_http_cs2zs(str, len)); } } RETURN_EMPTY_STRING(); @@@ -1711,7 -1695,7 +1711,7 @@@ PHP_METHOD(HttpUrl, toArray /* strip any non-URL properties */ purl = php_http_url_from_struct(HASH_OF(getThis())); - php_http_url_to_struct(purl, return_value TSRMLS_CC); + php_http_url_to_struct(purl, return_value); php_http_url_free(&purl); } @@@ -1724,47 -1708,46 +1724,47 @@@ static zend_function_entry php_http_url EMPTY_FUNCTION_ENTRY }; -zend_class_entry *php_http_url_class_entry; - PHP_MINIT_FUNCTION(http_url) { zend_class_entry ce = {0}; INIT_NS_CLASS_ENTRY(ce, "http", "Url", php_http_url_methods); - php_http_url_class_entry = zend_register_internal_class(&ce TSRMLS_CC); - - zend_declare_property_null(php_http_url_class_entry, ZEND_STRL("scheme"), ZEND_ACC_PUBLIC TSRMLS_CC); - zend_declare_property_null(php_http_url_class_entry, ZEND_STRL("user"), ZEND_ACC_PUBLIC TSRMLS_CC); - zend_declare_property_null(php_http_url_class_entry, ZEND_STRL("pass"), ZEND_ACC_PUBLIC TSRMLS_CC); - zend_declare_property_null(php_http_url_class_entry, ZEND_STRL("host"), ZEND_ACC_PUBLIC TSRMLS_CC); - zend_declare_property_null(php_http_url_class_entry, ZEND_STRL("port"), ZEND_ACC_PUBLIC TSRMLS_CC); - zend_declare_property_null(php_http_url_class_entry, ZEND_STRL("path"), ZEND_ACC_PUBLIC TSRMLS_CC); - zend_declare_property_null(php_http_url_class_entry, ZEND_STRL("query"), ZEND_ACC_PUBLIC TSRMLS_CC); - zend_declare_property_null(php_http_url_class_entry, ZEND_STRL("fragment"), ZEND_ACC_PUBLIC TSRMLS_CC); - - zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("REPLACE"), PHP_HTTP_URL_REPLACE TSRMLS_CC); - zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("JOIN_PATH"), PHP_HTTP_URL_JOIN_PATH TSRMLS_CC); - zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("JOIN_QUERY"), PHP_HTTP_URL_JOIN_QUERY TSRMLS_CC); - zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("STRIP_USER"), PHP_HTTP_URL_STRIP_USER TSRMLS_CC); - zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("STRIP_PASS"), PHP_HTTP_URL_STRIP_PASS TSRMLS_CC); - zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("STRIP_AUTH"), PHP_HTTP_URL_STRIP_AUTH TSRMLS_CC); - zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("STRIP_PORT"), PHP_HTTP_URL_STRIP_PORT TSRMLS_CC); - zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("STRIP_PATH"), PHP_HTTP_URL_STRIP_PATH TSRMLS_CC); - zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("STRIP_QUERY"), PHP_HTTP_URL_STRIP_QUERY TSRMLS_CC); - zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("STRIP_FRAGMENT"), PHP_HTTP_URL_STRIP_FRAGMENT TSRMLS_CC); - zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("STRIP_ALL"), PHP_HTTP_URL_STRIP_ALL TSRMLS_CC); - zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("FROM_ENV"), PHP_HTTP_URL_FROM_ENV TSRMLS_CC); - zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("SANITIZE_PATH"), PHP_HTTP_URL_SANITIZE_PATH TSRMLS_CC); + php_http_url_class_entry = zend_register_internal_class(&ce); + + zend_declare_property_null(php_http_url_class_entry, ZEND_STRL("scheme"), ZEND_ACC_PUBLIC); + zend_declare_property_null(php_http_url_class_entry, ZEND_STRL("user"), ZEND_ACC_PUBLIC); + zend_declare_property_null(php_http_url_class_entry, ZEND_STRL("pass"), ZEND_ACC_PUBLIC); + zend_declare_property_null(php_http_url_class_entry, ZEND_STRL("host"), ZEND_ACC_PUBLIC); + zend_declare_property_null(php_http_url_class_entry, ZEND_STRL("port"), ZEND_ACC_PUBLIC); + zend_declare_property_null(php_http_url_class_entry, ZEND_STRL("path"), ZEND_ACC_PUBLIC); + zend_declare_property_null(php_http_url_class_entry, ZEND_STRL("query"), ZEND_ACC_PUBLIC); + zend_declare_property_null(php_http_url_class_entry, ZEND_STRL("fragment"), ZEND_ACC_PUBLIC); + + zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("REPLACE"), PHP_HTTP_URL_REPLACE); + zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("JOIN_PATH"), PHP_HTTP_URL_JOIN_PATH); + zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("JOIN_QUERY"), PHP_HTTP_URL_JOIN_QUERY); + zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("STRIP_USER"), PHP_HTTP_URL_STRIP_USER); + zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("STRIP_PASS"), PHP_HTTP_URL_STRIP_PASS); + zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("STRIP_AUTH"), PHP_HTTP_URL_STRIP_AUTH); + zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("STRIP_PORT"), PHP_HTTP_URL_STRIP_PORT); + zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("STRIP_PATH"), PHP_HTTP_URL_STRIP_PATH); + zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("STRIP_QUERY"), PHP_HTTP_URL_STRIP_QUERY); + zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("STRIP_FRAGMENT"), PHP_HTTP_URL_STRIP_FRAGMENT); + zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("STRIP_ALL"), PHP_HTTP_URL_STRIP_ALL); + zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("FROM_ENV"), PHP_HTTP_URL_FROM_ENV); + zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("SANITIZE_PATH"), PHP_HTTP_URL_SANITIZE_PATH); #ifdef PHP_HTTP_HAVE_WCHAR - zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("PARSE_MBLOC"), PHP_HTTP_URL_PARSE_MBLOC TSRMLS_CC); + zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("PARSE_MBLOC"), PHP_HTTP_URL_PARSE_MBLOC); #endif - zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("PARSE_MBUTF8"), PHP_HTTP_URL_PARSE_MBUTF8 TSRMLS_CC); + zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("PARSE_MBUTF8"), PHP_HTTP_URL_PARSE_MBUTF8); #if defined(PHP_HTTP_HAVE_IDN2) || defined(PHP_HTTP_HAVE_IDN) || defined(HAVE_UIDNA_IDNTOASCII) - zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("PARSE_TOIDN"), PHP_HTTP_URL_PARSE_TOIDN TSRMLS_CC); + zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("PARSE_TOIDN"), PHP_HTTP_URL_PARSE_TOIDN); #endif - zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("PARSE_TOPCT"), PHP_HTTP_URL_PARSE_TOPCT TSRMLS_CC); + zend_declare_class_constant_long(php_http_url_class_entry, ZEND_STRL("PARSE_TOPCT"), PHP_HTTP_URL_PARSE_TOPCT); + + INIT_NS_CLASS_ENTRY(ce, "http\\Env", "Url", php_http_url_methods); + php_http_env_url_class_entry = zend_register_internal_class_ex(&ce, php_http_url_class_entry); return SUCCESS; } diff --combined tests/gh-issue50.phpt index 0000000,61e0865..6cef7d9 mode 000000,100644..100644 --- a/tests/gh-issue50.phpt +++ b/tests/gh-issue50.phpt @@@ -1,0 -1,39 +1,39 @@@ + --TEST-- + segfault with Client::setDebug and Client::dequeue() + --SKIPIF-- + + --FILE-- + enqueue(new http\Client\Request("GET", "http://example.com")); + + $c->setDebug(function(http\Client $c, http\Client\Request $r, $type, $data) { + if ($type & http\Client::DEBUG_HEADER) { + $c->dequeue($r); + } + }); + + try { + $c->send(); + } catch (Exception $e) { + echo $e; + } + + ?> + + ===DONE=== + --EXPECTF-- + Test -exception 'http\Exception\RuntimeException' with message 'http\Client::dequeue(): Could not dequeue request while executing callbacks' in %sgh-issue50.php:9 ++http\Exception\RuntimeException: http\Client::dequeue(): Could not dequeue request while executing callbacks in %sgh-issue50.php:9 + Stack trace: + #0 %sgh-issue50.php(9): http\Client->dequeue(Object(http\Client\Request)) + #1 [internal function]: {closure}(Object(http\Client), Object(http\Client\Request), 18, 'GET / HTTP/1.1\r...') + #2 %sgh-issue50.php(14): http\Client->send() + #3 {main} + ===DONE===