From: Michael Wallner Date: Tue, 21 Jun 2016 07:09:14 +0000 (+0200) Subject: Merge branch 'v2.6.x' X-Git-Tag: RELEASE_3_1_0_BETA1~6 X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-http;a=commitdiff_plain;h=7214e1aef4efce10bcc509d2a741acef88d28781 Merge branch 'v2.6.x' --- 7214e1aef4efce10bcc509d2a741acef88d28781 diff --cc src/php_http_client.c index 4e4a0cf,f1b1fc5..b719d2f --- a/src/php_http_client.c +++ b/src/php_http_client.c @@@ -324,21 -323,26 +326,26 @@@ ZEND_RESULT_CODE php_http_client_getopt return FAILURE; } -zend_class_entry *php_http_client_class_entry; static zend_object_handlers php_http_client_object_handlers; -void php_http_client_object_free(void *object TSRMLS_DC) +void php_http_client_object_free(zend_object *object) { - php_http_client_object_t *o = (php_http_client_object_t *) object; + php_http_client_object_t *o = PHP_HTTP_OBJ(object, NULL); + + PTR_FREE(o->gc); php_http_client_free(&o->client); + if (o->debug.fci.size > 0) { + zend_fcall_info_args_clear(&o->debug.fci, 1); + zval_ptr_dtor(&o->debug.fci.function_name); + o->debug.fci.size = 0; + } php_http_object_method_dtor(&o->notify); php_http_object_method_free(&o->update); - zend_object_std_dtor((zend_object *) o TSRMLS_CC); - efree(o); + zend_object_std_dtor(object); } -zend_object_value php_http_client_object_new_ex(zend_class_entry *ce, php_http_client_t *client, php_http_client_object_t **ptr TSRMLS_DC) +php_http_client_object_t *php_http_client_object_new_ex(zend_class_entry *ce, php_http_client_t *client) { php_http_client_object_t *o; @@@ -348,74 -352,35 +355,78 @@@ o->client = client; - if (ptr) { - *ptr = o; - } + o->zo.handlers = &php_http_client_object_handlers; - o->zv.handle = zend_objects_store_put(o, NULL, php_http_client_object_free, NULL TSRMLS_CC); - o->zv.handlers = &php_http_client_object_handlers; + return o; +} - return o->zv; +zend_object *php_http_client_object_new(zend_class_entry *ce) +{ + return &php_http_client_object_new_ex(ce, NULL)->zo; } -zend_object_value php_http_client_object_new(zend_class_entry *ce TSRMLS_DC) +static HashTable *php_http_client_object_get_gc(zval *object, zval **table, int *n) { - return php_http_client_object_new_ex(ce, NULL, NULL TSRMLS_CC); + php_http_client_object_t *obj = PHP_HTTP_OBJ(NULL, object); + zend_llist_element *el = NULL; + HashTable *props = Z_OBJPROP_P(object); - uint32_t count = zend_hash_num_elements(props) + zend_llist_count(&obj->client->responses) + zend_llist_count(&obj->client->requests) + 1; ++ uint32_t count = zend_hash_num_elements(props) + zend_llist_count(&obj->client->responses) + zend_llist_count(&obj->client->requests) + 2; + zval *val; + + *n = 0; + *table = obj->gc = erealloc(obj->gc, sizeof(zval) * count); + +#if PHP_HTTP_HAVE_CURL + if (obj->client->ops == php_http_client_curl_get_ops()) { + php_http_client_curl_t *curl = obj->client->ctx; + + if (curl->ev_ops == php_http_client_curl_user_ops_get()) { + php_http_client_curl_user_context_t *ctx = curl->ev_ctx; + + ZVAL_COPY_VALUE(&obj->gc[(*n)++], &ctx->user); + } + } +#endif + ++ if (obj->debug.fci.size > 0) { ++ ZVAL_COPY_VALUE(&obj->gc[(*n)++], &obj->debug.fci.function_name); ++ } ++ + for (el = obj->client->responses.head; el; el = el->next) { + php_http_message_object_t *response_obj = *(php_http_message_object_t **) el->data; + ZVAL_OBJ(&obj->gc[(*n)++], &response_obj->zo); + } + + for (el = obj->client->requests.head; el; el = el->next) { + php_http_client_enqueue_t *q = (php_http_client_enqueue_t *) el->data; + php_http_message_object_t *request_obj = q->opaque; /* FIXME */ + ZVAL_OBJ(&obj->gc[(*n)++], &request_obj->zo); + } + + ZEND_HASH_FOREACH_VAL(props, val) + { + ZVAL_COPY_VALUE(&obj->gc[(*n)++], val); + } + ZEND_HASH_FOREACH_END(); + + return NULL; } -static void handle_history(zval *zclient, php_http_message_t *request, php_http_message_t *response TSRMLS_DC) +static void handle_history(zval *zclient, php_http_message_t *request, php_http_message_t *response) { - zval *new_hist, *old_hist = zend_read_property(php_http_client_class_entry, zclient, ZEND_STRL("history"), 0 TSRMLS_CC); - php_http_message_t *zipped = php_http_message_zip(response, request); - zend_object_value ov = php_http_message_object_new_ex(php_http_message_class_entry, zipped, NULL TSRMLS_CC); + zval new_hist, old_hist_tmp, *old_hist = zend_read_property(php_http_client_class_entry, zclient, ZEND_STRL("history"), 0, &old_hist_tmp); + php_http_message_t *req_copy = php_http_message_copy(request, NULL); + php_http_message_t *res_copy = php_http_message_copy(response, NULL); + php_http_message_t *zipped = php_http_message_zip(res_copy, req_copy); + php_http_message_object_t *obj = php_http_message_object_new_ex(php_http_message_get_class_entry(), zipped); - MAKE_STD_ZVAL(new_hist); - ZVAL_OBJVAL(new_hist, ov, 0); + ZVAL_OBJ(&new_hist, &obj->zo); if (Z_TYPE_P(old_hist) == IS_OBJECT) { - php_http_message_object_prepend(new_hist, old_hist, 1 TSRMLS_CC); + php_http_message_object_prepend(&new_hist, old_hist, 1); } - zend_update_property(php_http_client_class_entry, zclient, ZEND_STRL("history"), new_hist TSRMLS_CC); + zend_update_property(php_http_client_class_entry, zclient, ZEND_STRL("history"), &new_hist); zval_ptr_dtor(&new_hist); } @@@ -494,30 -466,68 +505,54 @@@ static ZEND_RESULT_CODE handle_response static void handle_progress(void *arg, php_http_client_t *client, php_http_client_enqueue_t *e, php_http_client_progress_state_t *progress) { - zval *zrequest, *zprogress, *zclient, **args[2]; + zval zclient, args[2]; php_http_client_object_t *client_obj = arg; zend_error_handling zeh; - TSRMLS_FETCH_FROM_CTX(client->ts); - - MAKE_STD_ZVAL(zclient); - ZVAL_OBJVAL(zclient, client_obj->zv, 1); - - MAKE_STD_ZVAL(zrequest); - ZVAL_OBJVAL(zrequest, ((php_http_message_object_t *) e->opaque)->zv, 1); - args[0] = &zrequest; - - MAKE_STD_ZVAL(zprogress); - object_init(zprogress); - add_property_bool(zprogress, "started", progress->started); - add_property_bool(zprogress, "finished", progress->finished); - add_property_string(zprogress, "info", STR_PTR(progress->info), 1); - add_property_double(zprogress, "dltotal", progress->dl.total); - add_property_double(zprogress, "dlnow", progress->dl.now); - add_property_double(zprogress, "ultotal", progress->ul.total); - add_property_double(zprogress, "ulnow", progress->ul.now); - args[1] = &zprogress; - - zend_replace_error_handling(EH_NORMAL, NULL, &zeh TSRMLS_CC); - php_http_object_method_call(&client_obj->notify, zclient, NULL, 2, args TSRMLS_CC); - zend_restore_error_handling(&zeh TSRMLS_CC); + + ZVAL_OBJECT(&zclient, &client_obj->zo, 1); + ZVAL_OBJECT(&args[0], &((php_http_message_object_t *) e->opaque)->zo, 1); + object_init(&args[1]); + add_property_bool(&args[1], "started", progress->started); + add_property_bool(&args[1], "finished", progress->finished); + add_property_string(&args[1], "info", STR_PTR(progress->info)); + add_property_double(&args[1], "dltotal", progress->dl.total); + add_property_double(&args[1], "dlnow", progress->dl.now); + add_property_double(&args[1], "ultotal", progress->ul.total); + add_property_double(&args[1], "ulnow", progress->ul.now); + + zend_replace_error_handling(EH_NORMAL, NULL, &zeh); + php_http_object_method_call(&client_obj->notify, &zclient, NULL, 2, args); + zend_restore_error_handling(&zeh); zval_ptr_dtor(&zclient); - zval_ptr_dtor(&zrequest); - zval_ptr_dtor(&zprogress); + zval_ptr_dtor(&args[0]); + zval_ptr_dtor(&args[1]); } + static void handle_debug(void *arg, php_http_client_t *client, php_http_client_enqueue_t *e, unsigned type, const char *data, size_t size) + { - zval *ztype, *zdata, *zreq, *zclient; ++ zval ztype, zdata, zreq, zclient; + php_http_client_object_t *client_obj = arg; + zend_error_handling zeh; - TSRMLS_FETCH_FROM_CTX(client->ts); - - MAKE_STD_ZVAL(zclient); - ZVAL_OBJVAL(zclient, client_obj->zv, 1); - MAKE_STD_ZVAL(zreq); - ZVAL_OBJVAL(zreq, ((php_http_message_object_t *) e->opaque)->zv, 1); - MAKE_STD_ZVAL(ztype); - ZVAL_LONG(ztype, type); - MAKE_STD_ZVAL(zdata); - ZVAL_STRINGL(zdata, data, size, 1); - - zend_replace_error_handling(EH_NORMAL, NULL, &zeh TSRMLS_CC); - if (SUCCESS == zend_fcall_info_argn(&client_obj->debug.fci TSRMLS_CC, 4, &zclient, &zreq, &ztype, &zdata)) { - zend_fcall_info_call(&client_obj->debug.fci, &client_obj->debug.fcc, NULL, NULL TSRMLS_CC); ++ ++ ZVAL_OBJECT(&zclient, &client_obj->zo, 1); ++ ZVAL_OBJECT(&zreq, &((php_http_message_object_t *) e->opaque)->zo, 1); ++ ZVAL_LONG(&ztype, type); ++ ZVAL_STRINGL(&zdata, data, size); ++ ++ zend_replace_error_handling(EH_NORMAL, NULL, &zeh); ++ if (SUCCESS == zend_fcall_info_argn(&client_obj->debug.fci, 4, &zclient, &zreq, &ztype, &zdata)) { ++ zend_fcall_info_call(&client_obj->debug.fci, &client_obj->debug.fcc, NULL, NULL); + zend_fcall_info_args_clear(&client_obj->debug.fci, 0); + } - zend_restore_error_handling(&zeh TSRMLS_CC); ++ zend_restore_error_handling(&zeh); + + zval_ptr_dtor(&zclient); + zval_ptr_dtor(&zreq); + zval_ptr_dtor(&ztype); + zval_ptr_dtor(&zdata); - + } + static void response_dtor(void *data) { php_http_message_object_t *msg_obj = *(php_http_message_object_t **) data; @@@ -1228,6 -1250,38 +1263,38 @@@ static PHP_METHOD(HttpClient, getAvaila } } + ZEND_BEGIN_ARG_INFO_EX(ai_HttpClient_setDebug, 0, 0, 1) + ZEND_ARG_TYPE_INFO(0, callback, IS_CALLABLE, 1) + ZEND_END_ARG_INFO(); + static PHP_METHOD(HttpClient, setDebug) + { + zend_fcall_info fci; + zend_fcall_info_cache fcc; + php_http_client_object_t *client_obj; + + fci.size = 0; - php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|f", &fci, &fcc), invalid_arg, return); ++ php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "|f", &fci, &fcc), invalid_arg, return); + - client_obj = zend_object_store_get_object(getThis() TSRMLS_CC); ++ client_obj = PHP_HTTP_OBJ(NULL, getThis()); + + if (client_obj->debug.fci.size > 0) { + zval_ptr_dtor(&client_obj->debug.fci.function_name); + client_obj->debug.fci.size = 0; + } + if (fci.size > 0) { + memcpy(&client_obj->debug.fci, &fci, sizeof(fci)); + memcpy(&client_obj->debug.fcc, &fcc, sizeof(fcc)); - Z_ADDREF_P(fci.function_name); ++ Z_ADDREF_P(&fci.function_name); + client_obj->client->callback.debug.func = handle_debug; + client_obj->client->callback.debug.arg = client_obj; + } else { + client_obj->client->callback.debug.func = NULL; + client_obj->client->callback.debug.arg = NULL; + } + + RETVAL_ZVAL(getThis(), 1, 0); + } + static zend_function_entry php_http_client_methods[] = { PHP_ME(HttpClient, __construct, ai_HttpClient_construct, ZEND_ACC_PUBLIC|ZEND_ACC_CTOR) PHP_ME(HttpClient, reset, ai_HttpClient_reset, ZEND_ACC_PUBLIC) @@@ -1268,20 -1323,24 +1336,27 @@@ PHP_MINIT_FUNCTION(http_client zend_class_entry ce = {0}; INIT_NS_CLASS_ENTRY(ce, "http", "Client", php_http_client_methods); - php_http_client_class_entry = zend_register_internal_class_ex(&ce, NULL, NULL TSRMLS_CC); + php_http_client_class_entry = zend_register_internal_class_ex(&ce, NULL); php_http_client_class_entry->create_object = php_http_client_object_new; - zend_class_implements(php_http_client_class_entry TSRMLS_CC, 2, spl_ce_SplSubject, spl_ce_Countable); + zend_class_implements(php_http_client_class_entry, 2, spl_ce_SplSubject, spl_ce_Countable); memcpy(&php_http_client_object_handlers, zend_get_std_object_handlers(), sizeof(zend_object_handlers)); + php_http_client_object_handlers.offset = XtOffsetOf(php_http_client_object_t, zo); + php_http_client_object_handlers.free_obj = php_http_client_object_free; php_http_client_object_handlers.clone_obj = NULL; - zend_declare_property_null(php_http_client_class_entry, ZEND_STRL("observers"), ZEND_ACC_PRIVATE TSRMLS_CC); - zend_declare_property_null(php_http_client_class_entry, ZEND_STRL("options"), ZEND_ACC_PROTECTED TSRMLS_CC); - zend_declare_property_null(php_http_client_class_entry, ZEND_STRL("history"), ZEND_ACC_PROTECTED TSRMLS_CC); - zend_declare_property_bool(php_http_client_class_entry, ZEND_STRL("recordHistory"), 0, ZEND_ACC_PUBLIC TSRMLS_CC); - - zend_declare_class_constant_long(php_http_client_class_entry, ZEND_STRL("DEBUG_INFO"), PHP_HTTP_CLIENT_DEBUG_INFO TSRMLS_CC); - zend_declare_class_constant_long(php_http_client_class_entry, ZEND_STRL("DEBUG_IN"), PHP_HTTP_CLIENT_DEBUG_IN TSRMLS_CC); - zend_declare_class_constant_long(php_http_client_class_entry, ZEND_STRL("DEBUG_OUT"), PHP_HTTP_CLIENT_DEBUG_OUT TSRMLS_CC); - zend_declare_class_constant_long(php_http_client_class_entry, ZEND_STRL("DEBUG_HEADER"), PHP_HTTP_CLIENT_DEBUG_HEADER TSRMLS_CC); - zend_declare_class_constant_long(php_http_client_class_entry, ZEND_STRL("DEBUG_BODY"), PHP_HTTP_CLIENT_DEBUG_BODY TSRMLS_CC); - zend_declare_class_constant_long(php_http_client_class_entry, ZEND_STRL("DEBUG_SSL"), PHP_HTTP_CLIENT_DEBUG_SSL TSRMLS_CC); - - zend_hash_init(&php_http_client_drivers, 2, NULL, NULL, 1); + php_http_client_object_handlers.get_gc = php_http_client_object_get_gc; + zend_declare_property_null(php_http_client_class_entry, ZEND_STRL("observers"), ZEND_ACC_PRIVATE); + zend_declare_property_null(php_http_client_class_entry, ZEND_STRL("options"), ZEND_ACC_PROTECTED); + zend_declare_property_null(php_http_client_class_entry, ZEND_STRL("history"), ZEND_ACC_PROTECTED); + zend_declare_property_bool(php_http_client_class_entry, ZEND_STRL("recordHistory"), 0, ZEND_ACC_PUBLIC); + ++ zend_declare_class_constant_long(php_http_client_class_entry, ZEND_STRL("DEBUG_INFO"), PHP_HTTP_CLIENT_DEBUG_INFO); ++ zend_declare_class_constant_long(php_http_client_class_entry, ZEND_STRL("DEBUG_IN"), PHP_HTTP_CLIENT_DEBUG_IN); ++ zend_declare_class_constant_long(php_http_client_class_entry, ZEND_STRL("DEBUG_OUT"), PHP_HTTP_CLIENT_DEBUG_OUT); ++ zend_declare_class_constant_long(php_http_client_class_entry, ZEND_STRL("DEBUG_HEADER"), PHP_HTTP_CLIENT_DEBUG_HEADER); ++ zend_declare_class_constant_long(php_http_client_class_entry, ZEND_STRL("DEBUG_BODY"), PHP_HTTP_CLIENT_DEBUG_BODY); ++ zend_declare_class_constant_long(php_http_client_class_entry, ZEND_STRL("DEBUG_SSL"), PHP_HTTP_CLIENT_DEBUG_SSL); ++ + zend_hash_init(&php_http_client_drivers, 2, NULL, php_http_client_driver_hash_dtor, 1); return SUCCESS; } diff --cc src/php_http_client.h index c206ccd,ecaa304..08743e6 --- a/src/php_http_client.h +++ b/src/php_http_client.h @@@ -109,20 -120,28 +121,24 @@@ typedef struct php_http_client 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);