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);
+ --client->callback.depth;
zend_restore_error_handling(&zeh);
zend_fcall_info_argn(&e->closure.fci, 0);
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);
+ --client->callback.depth;
zend_restore_error_handling(&zeh);
zval_ptr_dtor(&zclient);
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);
php_http_client_debug_callback_t func;
void *arg;
} debug;
+ unsigned depth;
} callback;
zend_llist requests;
#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);
}
php_http_client_curl_t *curl = h->ctx;
php_http_client_curl_handler_t *handler = enqueue->opaque;
+ if (h->callback.depth) {
+ 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);
/* 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);
--- /dev/null
+--TEST--
+segfault with Client::setDebug and Client::dequeue()
+--SKIPIF--
+<?php
+include "skipif.inc";
+skip_client_test();
+skip_online_test();
+?>
+--FILE--
+<?php
+echo "Test\n";
+
+$c = new http\Client;
+$c->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
+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===