X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-http;a=blobdiff_plain;f=src%2Fphp_http_client_curl.c;h=71afd6f84c069a830a2a1f22739002b92eb64a19;hp=be1783252a5a98a6fe843c0af8095f8d1cf52f61;hb=b2be5b163e896bb9cbb3f28314551d0debf8408d;hpb=28d7c572181c8c3c335edd3df539f75c3bbde0fd diff --git a/src/php_http_client_curl.c b/src/php_http_client_curl.c index be17832..71afd6f 100644 --- a/src/php_http_client_curl.c +++ b/src/php_http_client_curl.c @@ -177,22 +177,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); } @@ -215,6 +212,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) { @@ -258,20 +256,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); @@ -453,6 +474,12 @@ static ZEND_RESULT_CODE php_http_curle_get_info(CURL *ch, HashTable *info) zend_hash_str_update(info, "local_port", lenof("local_port"), &tmp); } #endif +#if PHP_HTTP_CURL_VERSION(7,50,0) + if (CURLE_OK == curl_easy_getinfo(ch, CURLINFO_HTTP_VERSION, &l)) { + ZVAL_LONG(&tmp, l); + zend_hash_str_update(info, "http_version", lenof("http_version"), &tmp); + } +#endif /* END::CURLINFO */ @@ -896,20 +923,23 @@ static ZEND_RESULT_CODE php_http_curle_option_set_range(php_http_option_t *opt, if (val && Z_TYPE_P(val) != IS_NULL) { 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)) { + zend_long rbl = zval_get_long(rb), rel = zval_get_long(re); + + if (rbl >= 0) { + if (rel > 0) { php_http_buffer_appendf(&curl->options.ranges, "%ld-%ld,", rbl, rel); + } else { + php_http_buffer_appendf(&curl->options.ranges, "%ld-", rbl); } + } else if (rel > 0) { + php_http_buffer_appendf(&curl->options.ranges, "-%ld", rel); } - } } } @@ -1606,7 +1636,7 @@ static ZEND_RESULT_CODE php_http_curlm_option_set_use_eventloop(php_http_option_ php_http_client_t *client = userdata; php_http_client_curl_ops_t *ev_ops = NULL; - if (Z_TYPE_P(value) == IS_OBJECT && instanceof_function(Z_OBJCE_P(value), php_http_client_curl_user_get_class_entry())) { + if (value && 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 && zend_is_true(value)) { @@ -1724,15 +1754,13 @@ static ZEND_RESULT_CODE php_http_curlm_set_option(php_http_option_t *opt, zval * php_http_client_t *client = userdata; php_http_client_curl_t *curl = client->ctx; CURLM *ch = curl->handle->multi; - zval *orig = val; + zval zopt, *orig = val; CURLMcode rc = CURLM_UNKNOWN_OPTION; ZEND_RESULT_CODE rv = SUCCESS; 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)) { - zval zopt; - ZVAL_DUP(&zopt, val); convert_to_explicit_type(&zopt, opt->type); @@ -2056,6 +2084,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; @@ -2170,6 +2199,11 @@ static ZEND_RESULT_CODE php_http_client_curl_dequeue(php_http_client_t *h, php_h 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); @@ -2233,35 +2267,38 @@ static int php_http_client_curl_once(php_http_client_t *h) { php_http_client_curl_t *curl = h->ctx; - if (curl->ev_ops) { - curl->ev_ops->once(curl->ev_ctx); - } else { - while (CURLM_CALL_MULTI_PERFORM == curl_multi_perform(curl->handle->multi, &curl->unfinished)); - } + if (!h->callback.depth) { + if (curl->ev_ops) { + curl->ev_ops->once(curl->ev_ctx); + } else { + while (CURLM_CALL_MULTI_PERFORM == curl_multi_perform(curl->handle->multi, &curl->unfinished)); + } - php_http_client_curl_responsehandler(h); + php_http_client_curl_responsehandler(h); + } return curl->unfinished; - } static ZEND_RESULT_CODE php_http_client_curl_exec(php_http_client_t *h) { php_http_client_curl_t *curl = h->ctx; - if (curl->ev_ops) { - return curl->ev_ops->exec(curl->ev_ctx); - } + if (!h->callback.depth) { + if (curl->ev_ops) { + return curl->ev_ops->exec(curl->ev_ctx); + } - while (php_http_client_curl_once(h) && !EG(exception)) { - if (SUCCESS != php_http_client_curl_wait(h, NULL)) { + while (php_http_client_curl_once(h) && !EG(exception)) { + 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, E_WARNING, "WinSock error: %d", WSAGetLastError()); + /* see http://msdn.microsoft.com/library/en-us/winsock/winsock/windows_sockets_error_codes_2.asp */ + php_error_docref(NULL, E_WARNING, "WinSock error: %d", WSAGetLastError()); #else - php_error_docref(NULL, E_WARNING, "%s", strerror(errno)); + php_error_docref(NULL, E_WARNING, "%s", strerror(errno)); #endif - return FAILURE; + return FAILURE; + } } }