X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-http;a=blobdiff_plain;f=src%2Fphp_http_client_curl.c;h=1ec6624cc21a07b7e3d6957b398621b393ff989d;hp=d3f5200c141921bc6dbf922fdc9f83f6ff6c1a06;hb=0fa2672890a4fe58c3418670e57a511b3ea7189c;hpb=286dfcc5b1e7b24117132c7bff5b8e64ac6ac5d0 diff --git a/src/php_http_client_curl.c b/src/php_http_client_curl.c index d3f5200..1ec6624 100644 --- a/src/php_http_client_curl.c +++ b/src/php_http_client_curl.c @@ -13,6 +13,7 @@ #include "php_http_api.h" #include "php_http_client.h" #include "php_http_client_curl_event.h" +#include "php_http_client_curl_user.h" #if PHP_HTTP_HAVE_CURL @@ -181,22 +182,19 @@ static int php_http_curle_progress_callback(void *ctx, double dltotal, double dl #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); } @@ -220,6 +218,7 @@ static int php_http_curle_seek_callback(void *userdata, curl_off_t offset, int o static int php_http_curle_raw_callback(CURL *ch, curl_infotype type, char *data, size_t length, void *ctx) { php_http_client_curl_handler_t *h = ctx; + unsigned utype = PHP_HTTP_CLIENT_DEBUG_INFO; /* catch progress */ switch (type) { @@ -263,20 +262,43 @@ static int php_http_curle_raw_callback(CURL *ch, curl_infotype type, char *data, h->client->callback.progress.func(h->client->callback.progress.arg, h->client, &h->queue, &h->progress); } break; + case CURLINFO_HEADER_OUT: - case CURLINFO_DATA_OUT: + utype |= PHP_HTTP_CLIENT_DEBUG_HEADER; + goto data_out; + case CURLINFO_SSL_DATA_OUT: + utype |= PHP_HTTP_CLIENT_DEBUG_SSL; + goto data_out; + + case CURLINFO_DATA_OUT: + data_out: + utype |= PHP_HTTP_CLIENT_DEBUG_OUT; h->progress.info = "send"; break; + case CURLINFO_HEADER_IN: - case CURLINFO_DATA_IN: + utype |= PHP_HTTP_CLIENT_DEBUG_HEADER; + goto data_in; + case CURLINFO_SSL_DATA_IN: + utype |= PHP_HTTP_CLIENT_DEBUG_SSL; + goto data_in; + + case CURLINFO_DATA_IN: + data_in: + utype |= PHP_HTTP_CLIENT_DEBUG_IN; h->progress.info = "receive"; break; + default: break; } + if (h->client->callback.debug.func) { + h->client->callback.debug.func(h->client->callback.debug.arg, h->client, &h->queue, utype, data, length); + } + #if 0 /* debug */ _dpf(type, data, length); @@ -667,6 +689,27 @@ void php_http_client_curl_responsehandler(php_http_client_t *context) } } +void php_http_client_curl_loop(php_http_client_t *client, curl_socket_t s, int curl_action) +{ + CURLMcode rc; + php_http_client_curl_t *curl = client->ctx; + TSRMLS_FETCH_FROM_CTX(client->ts); + +#if DBG_EVENTS + fprintf(stderr, "H"); +#endif + + do { + rc = curl_multi_socket_action(curl->handle->multi, s, curl_action, &curl->unfinished); + } while (CURLM_CALL_MULTI_PERFORM == rc); + + if (CURLM_OK != rc) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", curl_multi_strerror(rc)); + } + + php_http_client_curl_responsehandler(client); +} + /* curl options */ static php_http_options_t php_http_curle_options, php_http_curlm_options; @@ -1534,22 +1577,17 @@ static ZEND_RESULT_CODE php_http_curlm_option_set_pipelining_bl(php_http_option_ } #endif -#if PHP_HTTP_HAVE_EVENT -static inline ZEND_RESULT_CODE php_http_curlm_use_eventloop(php_http_client_t *h, zend_bool enable) +static inline ZEND_RESULT_CODE php_http_curlm_use_eventloop(php_http_client_t *h, php_http_client_curl_ops_t *ev_ops, zval *init_data) { php_http_client_curl_t *curl = h->ctx; + void *ev_ctx; - if (enable) { - if (!curl->ev_ops) { - if (!(curl->ev_ops = php_http_client_curl_event_ops_get())) { - return FAILURE; - } - } - if (curl->ev_ops && !curl->ev_ctx) { - if (!(curl->ev_ctx = curl->ev_ops->init(h))) { - return FAILURE; - } + if (ev_ops) { + if (!(ev_ctx = ev_ops->init(h, init_data))) { + return FAILURE; } + curl->ev_ctx = ev_ctx; + curl->ev_ops = ev_ops; } else { if (curl->ev_ops) { if (curl->ev_ctx) { @@ -1565,13 +1603,19 @@ static inline ZEND_RESULT_CODE php_http_curlm_use_eventloop(php_http_client_t *h static ZEND_RESULT_CODE php_http_curlm_option_set_use_eventloop(php_http_option_t *opt, zval *value, void *userdata) { 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 */) { - abort(); + if (Z_TYPE_P(value) == IS_OBJECT && instanceof_function(Z_OBJCE_P(value), php_http_client_curl_user_class_entry TSRMLS_CC)) { + ev_ops = php_http_client_curl_user_ops_get(); +#if PHP_HTTP_HAVE_EVENT + } else if (value && z_is_true(value)) { + ev_ops = php_http_client_curl_event_ops_get(); +#endif } - return php_http_curlm_use_eventloop(client, value && z_is_true(value)); + + return php_http_curlm_use_eventloop(client, ev_ops, value); } -#endif static ZEND_RESULT_CODE php_http_curlm_option_set_share_cookies(php_http_option_t *opt, zval *value, void *userdata) { @@ -1661,11 +1705,9 @@ static void php_http_curlm_options_init(php_http_options_t *registry TSRMLS_DC) } #endif /* events */ -#if PHP_HTTP_HAVE_EVENT - if ((opt = php_http_option_register(registry, ZEND_STRL("use_eventloop"), 0, IS_BOOL))) { + if ((opt = php_http_option_register(registry, ZEND_STRL("use_eventloop"), 0, 0))) { opt->setter = php_http_curlm_option_set_use_eventloop; } -#endif /* share */ if ((opt = php_http_option_register(registry, ZEND_STRL("share_cookies"), 0, IS_BOOL))) { opt->setter = php_http_curlm_option_set_share_cookies; @@ -2007,6 +2049,7 @@ static void php_http_client_curl_dtor(php_http_client_t *h) if (curl->ev_ops) { curl->ev_ops->dtor(&curl->ev_ctx); + curl->ev_ops = NULL; } curl->unfinished = 0; @@ -2122,6 +2165,11 @@ static ZEND_RESULT_CODE php_http_client_curl_dequeue(php_http_client_t *h, php_h 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"); + 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); @@ -2238,7 +2286,9 @@ static ZEND_RESULT_CODE php_http_client_curl_setopt(php_http_client_t *h, php_ht case PHP_HTTP_CLIENT_OPT_USE_EVENTS: #if PHP_HTTP_HAVE_EVENT - return php_http_curlm_use_eventloop(h, *(zend_bool *) arg); + return php_http_curlm_use_eventloop(h, (*(zend_bool *) arg) + ? php_http_client_curl_event_ops_get() + : NULL, NULL); break; #endif