X-Git-Url: https://git.m6w6.name/?p=m6w6%2Fext-http;a=blobdiff_plain;f=http_request_api.c;h=6c7df822c189b0917a0671e89fde4c16256c7e3a;hp=3396dba1d080f77e3488d920122a3caba0d1f4ef;hb=b0d260940d93ae0553dde04cea651cb4b19df207;hpb=1df42dae0279a4d0f98b042bb389e90cbd197f6f diff --git a/http_request_api.c b/http_request_api.c index 3396dba..6c7df82 100644 --- a/http_request_api.c +++ b/http_request_api.c @@ -19,11 +19,9 @@ #ifdef HTTP_HAVE_CURL #include "php_http_api.h" +#include "php_http_persistent_handle_api.h" #include "php_http_request_api.h" #include "php_http_url_api.h" -#ifdef HTTP_HAVE_PERSISTENT_HANDLES -# include "php_http_persistent_handle_api.h" -#endif #ifdef ZEND_ENGINE_2 # include "php_http_request_object.h" @@ -112,11 +110,9 @@ PHP_MINIT_FUNCTION(http_request) return FAILURE; } -#ifdef HTTP_HAVE_PERSISTENT_HANDLES - if (SUCCESS != http_persistent_handle_provide("http_request", curl_easy_init, curl_easy_cleanup)) { + if (SUCCESS != http_persistent_handle_provide("http_request", curl_easy_init, curl_easy_cleanup, curl_easy_duphandle)) { return FAILURE; } -#endif HTTP_LONG_CONSTANT("HTTP_AUTH_BASIC", CURLAUTH_BASIC); HTTP_LONG_CONSTANT("HTTP_AUTH_DIGEST", CURLAUTH_DIGEST); @@ -185,18 +181,10 @@ static int http_curl_dummy_callback(char *data, size_t n, size_t l, void *s) { r static curlioerr http_curl_ioctl_callback(CURL *, curliocmd, void *); /* }}} */ -#ifdef HTTP_HAVE_PERSISTENT_HANDLES -# define HTTP_CURL_HANDLE_CTOR(ch) (SUCCESS == http_persistent_handle_acquire("http_request", &(ch))) -# define HTTP_CURL_HANDLE_DTOR(chp) http_persistent_handle_release("http_request", (chp)) -#else -# define HTTP_CURL_HANDLE_CTOR(ch) ((ch) = curl_easy_init()) -# define HTTP_CURL_HANDLE_DTOR(chp) curl_easy_cleanup(*(chp)); *(chp) = NULL -#endif - /* {{{ CURL *http_curl_init(http_request *) */ PHP_HTTP_API CURL * _http_curl_init_ex(CURL *ch, http_request *request TSRMLS_DC) { - if (ch || HTTP_CURL_HANDLE_CTOR(ch)) { + if (ch || (SUCCESS == http_persistent_handle_acquire("http_request", &ch))) { #if defined(ZTS) curl_easy_setopt(ch, CURLOPT_NOSIGNAL, 1L); #endif @@ -227,6 +215,18 @@ PHP_HTTP_API CURL * _http_curl_init_ex(CURL *ch, http_request *request TSRMLS_DC } /* }}} */ +/* {{{ CURL *http_curl_copy(CURL *) */ +PHP_HTTP_API CURL *_http_curl_copy(CURL *ch TSRMLS_DC) +{ + CURL *copy; + + if (SUCCESS == http_persistent_handle_accrete("http_request", ch, ©)) { + return copy; + } + return NULL; +} +/* }}} */ + /* {{{ void http_curl_free(CURL **) */ PHP_HTTP_API void _http_curl_free(CURL **ch TSRMLS_DC) { @@ -236,7 +236,7 @@ PHP_HTTP_API void _http_curl_free(CURL **ch TSRMLS_DC) curl_easy_setopt(*ch, CURLOPT_VERBOSE, 0L); curl_easy_setopt(*ch, CURLOPT_DEBUGFUNCTION, NULL); - HTTP_CURL_HANDLE_DTOR(ch); + http_persistent_handle_release("http_request", ch); } } /* }}} */ @@ -481,9 +481,7 @@ PHP_HTTP_API STATUS _http_request_prepare(http_request *request, HashTable *opti /* proxy */ if ((zoption = http_request_option(request, options, "proxyhost", IS_STRING))) { - if (Z_STRLEN_P(zoption)) { - HTTP_CURL_OPT(CURLOPT_PROXY, Z_STRVAL_P(zoption)); - } + HTTP_CURL_OPT(CURLOPT_PROXY, Z_STRVAL_P(zoption)); /* type */ if ((zoption = http_request_option(request, options, "proxytype", IS_LONG))) { HTTP_CURL_OPT(CURLOPT_PROXYTYPE, Z_LVAL_P(zoption)); @@ -583,6 +581,18 @@ PHP_HTTP_API STATUS _http_request_prepare(http_request *request, HashTable *opti HTTP_CURL_OPT(CURLOPT_UNRESTRICTED_AUTH, Z_LVAL_P(zoption)); } } + + /* retries, defaults to 0 */ + if ((zoption = http_request_option(request, options, "retrycount", IS_LONG))) { + request->_retry.count = Z_LVAL_P(zoption); + if ((zoption = http_request_option(request, options, "retrydelay", IS_DOUBLE))) { + request->_retry.delay = Z_DVAL_P(zoption); + } else { + request->_retry.delay = 0; + } + } else { + request->_retry.count = 0; + } /* referer */ if ((zoption = http_request_option(request, options, "referer", IS_STRING)) && Z_STRLEN_P(zoption)) { @@ -874,11 +884,37 @@ PHP_HTTP_API STATUS _http_request_prepare(http_request *request, HashTable *opti /* {{{ void http_request_exec(http_request *) */ PHP_HTTP_API void _http_request_exec(http_request *request) { + uint tries = 0; CURLcode result; TSRMLS_FETCH_FROM_CTX(request->tsrm_ls); +retry: if (CURLE_OK != (result = curl_easy_perform(request->ch))) { http_error_ex(HE_WARNING, HTTP_E_REQUEST, "%s; %s (%s)", curl_easy_strerror(result), request->_error, request->url); + + if (request->_retry.count > tries++) { + switch (result) { + case CURLE_COULDNT_RESOLVE_PROXY: + case CURLE_COULDNT_RESOLVE_HOST: + case CURLE_COULDNT_CONNECT: + case CURLE_WRITE_ERROR: + case CURLE_READ_ERROR: + case CURLE_OPERATION_TIMEDOUT: + case CURLE_SSL_CONNECT_ERROR: + case CURLE_GOT_NOTHING: + case CURLE_SSL_ENGINE_SETFAILED: + case CURLE_SEND_ERROR: + case CURLE_RECV_ERROR: + case CURLE_SSL_ENGINE_INITFAILED: + case CURLE_LOGIN_DENIED: + if (request->_retry.delay) { + http_sleep(request->_retry.delay); + } + goto retry; + default: + break; + } + } } } /* }}} */