Merge branch 'v2.6.x'
authorMichael Wallner <mike@php.net>
Tue, 21 Jun 2016 07:09:14 +0000 (09:09 +0200)
committerMichael Wallner <mike@php.net>
Tue, 21 Jun 2016 07:09:14 +0000 (09:09 +0200)
1  2 
src/php_http_client.c
src/php_http_client.h
src/php_http_client_curl.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;
  
  
        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]);
  }
  
 -      zval *ztype, *zdata, *zreq, *zclient;
+ 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)
+ {
 -      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 ztype, zdata, zreq, zclient;
+       php_http_client_object_t *client_obj = arg;
+       zend_error_handling zeh;
 -      zend_restore_error_handling(&zeh 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);
+       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
        }
  }
  
 -      php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|f", &fci, &fcc), invalid_arg, return);
+ 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;
 -      client_obj = zend_object_store_get_object(getThis() TSRMLS_CC);
++      php_http_expect(SUCCESS == zend_parse_parameters(ZEND_NUM_ARGS(), "|f", &fci, &fcc), invalid_arg, return);
 -              Z_ADDREF_P(fci.function_name);
++      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);
+               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;
  }
@@@ -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);
Simple merge