diff options
Diffstat (limited to 'ext/curl/interface.c')
-rw-r--r-- | ext/curl/interface.c | 191 |
1 files changed, 102 insertions, 89 deletions
diff --git a/ext/curl/interface.c b/ext/curl/interface.c index 7069710ece..08846808fc 100644 --- a/ext/curl/interface.c +++ b/ext/curl/interface.c @@ -167,7 +167,7 @@ static void _php_curl_close(zend_resource *rsrc); # define php_curl_ret(__ret) RETVAL_FALSE; return; #endif -static int php_curl_option_str(php_curl *ch, zend_long option, const char *str, const int len, zend_bool make_copy) +static int php_curl_option_str(php_curl *ch, zend_long option, const char *str, const size_t len, zend_bool make_copy) { CURLcode error = CURLE_OK; @@ -196,7 +196,7 @@ static int php_curl_option_str(php_curl *ch, zend_long option, const char *str, return error == CURLE_OK ? SUCCESS : FAILURE; } -static int php_curl_option_url(php_curl *ch, const char *url, const int len) /* {{{ */ +static int php_curl_option_url(php_curl *ch, const char *url, const size_t len) /* {{{ */ { /* Disable file:// if open_basedir are used */ if (PG(open_basedir) && *PG(open_basedir)) { @@ -392,6 +392,10 @@ ZEND_BEGIN_ARG_INFO(arginfo_curl_multi_close, 0) ZEND_ARG_INFO(0, mh) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_INFO(arginfo_curl_multi_errno, 0) + ZEND_ARG_INFO(0, mh) +ZEND_END_ARG_INFO() + #if LIBCURL_VERSION_NUM >= 0x070c00 /* Available since 7.12.0 */ ZEND_BEGIN_ARG_INFO(arginfo_curl_strerror, 0) ZEND_ARG_INFO(0, errornum) @@ -400,6 +404,10 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO(arginfo_curl_multi_strerror, 0) ZEND_ARG_INFO(0, errornum) ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_curl_share_strerror, 0) + ZEND_ARG_INFO(0, errornum) +ZEND_END_ARG_INFO() #endif ZEND_BEGIN_ARG_INFO(arginfo_curl_share_init, 0) @@ -415,6 +423,10 @@ ZEND_BEGIN_ARG_INFO(arginfo_curl_share_setopt, 0) ZEND_ARG_INFO(0, value) ZEND_END_ARG_INFO() +ZEND_BEGIN_ARG_INFO(arginfo_curl_share_errno, 0) + ZEND_ARG_INFO(0, sh) +ZEND_END_ARG_INFO() + #if LIBCURL_VERSION_NUM >= 0x071200 /* Available since 7.18.0 */ ZEND_BEGIN_ARG_INFO(arginfo_curl_pause, 0) ZEND_ARG_INFO(0, ch) @@ -445,6 +457,7 @@ const zend_function_entry curl_functions[] = { #if LIBCURL_VERSION_NUM >= 0x070c00 /* 7.12.0 */ PHP_FE(curl_strerror, arginfo_curl_strerror) PHP_FE(curl_multi_strerror, arginfo_curl_multi_strerror) + PHP_FE(curl_share_strerror, arginfo_curl_share_strerror) #endif #if LIBCURL_VERSION_NUM >= 0x070c01 /* 7.12.1 */ PHP_FE(curl_reset, arginfo_curl_reset) @@ -464,12 +477,14 @@ const zend_function_entry curl_functions[] = { PHP_FE(curl_multi_getcontent, arginfo_curl_multi_getcontent) PHP_FE(curl_multi_info_read, arginfo_curl_multi_info_read) PHP_FE(curl_multi_close, arginfo_curl_multi_close) + PHP_FE(curl_multi_errno, arginfo_curl_multi_errno) #if LIBCURL_VERSION_NUM >= 0x070f04 /* 7.15.4 */ PHP_FE(curl_multi_setopt, arginfo_curl_multi_setopt) #endif PHP_FE(curl_share_init, arginfo_curl_share_init) PHP_FE(curl_share_close, arginfo_curl_share_close) PHP_FE(curl_share_setopt, arginfo_curl_share_setopt) + PHP_FE(curl_share_errno, arginfo_curl_share_errno) PHP_FE(curl_file_create, arginfo_curlfile_create) PHP_FE_END }; @@ -1322,6 +1337,9 @@ PHP_MINIT_FUNCTION(curl) #if LIBCURL_VERSION_NUM >= 0x072e00 /* Available since 7.46.0 */ REGISTER_CURL_CONSTANT(CURLOPT_STREAM_WEIGHT); + REGISTER_CURL_CONSTANT(CURLMOPT_PUSHFUNCTION); + REGISTER_CURL_CONSTANT(CURL_PUSH_OK); + REGISTER_CURL_CONSTANT(CURL_PUSH_DENY); #endif #if LIBCURL_VERSION_NUM >= 0x072f00 /* Available since 7.47.0 */ @@ -1449,14 +1467,12 @@ static size_t curl_write(char *data, size_t size, size_t nmemb, void *ctx) ZVAL_STRINGL(&argv[1], data, length); fci.size = sizeof(fci); - fci.function_table = EG(function_table); fci.object = NULL; ZVAL_COPY_VALUE(&fci.function_name, &t->func_name); fci.retval = &retval; fci.param_count = 2; fci.params = argv; fci.no_separation = 0; - fci.symbol_table = NULL; ch->in_callback = 1; error = zend_call_function(&fci, &t->fci_cache); @@ -1500,14 +1516,12 @@ static int curl_fnmatch(void *ctx, const char *pattern, const char *string) ZVAL_STRING(&argv[2], string); fci.size = sizeof(fci); - fci.function_table = EG(function_table); ZVAL_COPY_VALUE(&fci.function_name, &t->func_name); fci.object = NULL; fci.retval = &retval; fci.param_count = 3; fci.params = argv; fci.no_separation = 0; - fci.symbol_table = NULL; ch->in_callback = 1; error = zend_call_function(&fci, &t->fci_cache); @@ -1557,14 +1571,12 @@ static size_t curl_progress(void *clientp, double dltotal, double dlnow, double ZVAL_LONG(&argv[4], (zend_long)ulnow); fci.size = sizeof(fci); - fci.function_table = EG(function_table); ZVAL_COPY_VALUE(&fci.function_name, &t->func_name); fci.object = NULL; fci.retval = &retval; fci.param_count = 5; fci.params = argv; fci.no_separation = 0; - fci.symbol_table = NULL; ch->in_callback = 1; error = zend_call_function(&fci, &t->fci_cache); @@ -1620,14 +1632,12 @@ static size_t curl_read(char *data, size_t size, size_t nmemb, void *ctx) ZVAL_LONG(&argv[2], (int)size * nmemb); fci.size = sizeof(fci); - fci.function_table = EG(function_table); ZVAL_COPY_VALUE(&fci.function_name, &t->func_name); fci.object = NULL; fci.retval = &retval; fci.param_count = 3; fci.params = argv; fci.no_separation = 0; - fci.symbol_table = NULL; ch->in_callback = 1; error = zend_call_function(&fci, &t->fci_cache); @@ -1688,9 +1698,7 @@ static size_t curl_write_header(char *data, size_t size, size_t nmemb, void *ctx ZVAL_STRINGL(&argv[1], data, length); fci.size = sizeof(fci); - fci.function_table = EG(function_table); ZVAL_COPY_VALUE(&fci.function_name, &t->func_name); - fci.symbol_table = NULL; fci.object = NULL; fci.retval = &retval; fci.param_count = 2; @@ -1848,7 +1856,7 @@ PHP_FUNCTION(curl_version) /* {{{ alloc_curl_handle */ -static php_curl *alloc_curl_handle() +php_curl *alloc_curl_handle() { php_curl *ch = ecalloc(1, sizeof(php_curl)); ch->to_free = ecalloc(1, sizeof(struct _php_curl_free)); @@ -1986,6 +1994,79 @@ PHP_FUNCTION(curl_init) } /* }}} */ +void _php_setup_easy_copy_handlers(php_curl *ch, php_curl *source) +{ + if (!Z_ISUNDEF(source->handlers->write->stream)) { + Z_ADDREF(source->handlers->write->stream); + } + ch->handlers->write->stream = source->handlers->write->stream; + ch->handlers->write->method = source->handlers->write->method; + if (!Z_ISUNDEF(source->handlers->read->stream)) { + Z_ADDREF(source->handlers->read->stream); + } + ch->handlers->read->stream = source->handlers->read->stream; + ch->handlers->read->method = source->handlers->read->method; + ch->handlers->write_header->method = source->handlers->write_header->method; + if (!Z_ISUNDEF(source->handlers->write_header->stream)) { + Z_ADDREF(source->handlers->write_header->stream); + } + ch->handlers->write_header->stream = source->handlers->write_header->stream; + + ch->handlers->write->fp = source->handlers->write->fp; + ch->handlers->write_header->fp = source->handlers->write_header->fp; + ch->handlers->read->fp = source->handlers->read->fp; + ch->handlers->read->res = source->handlers->read->res; +#if CURLOPT_PASSWDDATA != 0 + if (!Z_ISUNDEF(source->handlers->passwd)) { + ZVAL_COPY(&ch->handlers->passwd, &source->handlers->passwd); + curl_easy_setopt(source->cp, CURLOPT_PASSWDDATA, (void *) ch); + } +#endif + if (!Z_ISUNDEF(source->handlers->write->func_name)) { + ZVAL_COPY(&ch->handlers->write->func_name, &source->handlers->write->func_name); + } + if (!Z_ISUNDEF(source->handlers->read->func_name)) { + ZVAL_COPY(&ch->handlers->read->func_name, &source->handlers->read->func_name); + } + if (!Z_ISUNDEF(source->handlers->write_header->func_name)) { + ZVAL_COPY(&ch->handlers->write_header->func_name, &source->handlers->write_header->func_name); + } + + curl_easy_setopt(ch->cp, CURLOPT_ERRORBUFFER, ch->err.str); + curl_easy_setopt(ch->cp, CURLOPT_FILE, (void *) ch); + curl_easy_setopt(ch->cp, CURLOPT_INFILE, (void *) ch); + curl_easy_setopt(ch->cp, CURLOPT_WRITEHEADER, (void *) ch); + + if (source->handlers->progress) { + ch->handlers->progress = ecalloc(1, sizeof(php_curl_progress)); + if (!Z_ISUNDEF(source->handlers->progress->func_name)) { + ZVAL_COPY(&ch->handlers->progress->func_name, &source->handlers->progress->func_name); + } + ch->handlers->progress->method = source->handlers->progress->method; + curl_easy_setopt(ch->cp, CURLOPT_PROGRESSDATA, (void *) ch); + } + +#if LIBCURL_VERSION_NUM >= 0x071500 + if (source->handlers->fnmatch) { + ch->handlers->fnmatch = ecalloc(1, sizeof(php_curl_fnmatch)); + if (!Z_ISUNDEF(source->handlers->fnmatch->func_name)) { + ZVAL_COPY(&ch->handlers->fnmatch->func_name, &source->handlers->fnmatch->func_name); + } + ch->handlers->fnmatch->method = source->handlers->fnmatch->method; + curl_easy_setopt(ch->cp, CURLOPT_FNMATCH_DATA, (void *) ch); + } +#endif + + efree(ch->to_free->slist); + efree(ch->to_free); + ch->to_free = source->to_free; + efree(ch->clone); + ch->clone = source->clone; + + /* Keep track of cloned copies to avoid invoking curl destructors for every clone */ + (*source->clone)++; +} + /* {{{ proto resource curl_copy_handle(resource ch) Copy a cURL handle along with all of it's preferences */ PHP_FUNCTION(curl_copy_handle) @@ -2009,79 +2090,11 @@ PHP_FUNCTION(curl_copy_handle) } dupch = alloc_curl_handle(); - dupch->cp = cp; - Z_ADDREF_P(zid); - if (!Z_ISUNDEF(ch->handlers->write->stream)) { - Z_ADDREF(ch->handlers->write->stream); - } - dupch->handlers->write->stream = ch->handlers->write->stream; - dupch->handlers->write->method = ch->handlers->write->method; - if (!Z_ISUNDEF(ch->handlers->read->stream)) { - Z_ADDREF(ch->handlers->read->stream); - } - dupch->handlers->read->stream = ch->handlers->read->stream; - dupch->handlers->read->method = ch->handlers->read->method; - dupch->handlers->write_header->method = ch->handlers->write_header->method; - if (!Z_ISUNDEF(ch->handlers->write_header->stream)) { - Z_ADDREF(ch->handlers->write_header->stream); - } - dupch->handlers->write_header->stream = ch->handlers->write_header->stream; - - dupch->handlers->write->fp = ch->handlers->write->fp; - dupch->handlers->write_header->fp = ch->handlers->write_header->fp; - dupch->handlers->read->fp = ch->handlers->read->fp; - dupch->handlers->read->res = ch->handlers->read->res; -#if CURLOPT_PASSWDDATA != 0 - if (!Z_ISUNDEF(ch->handlers->passwd)) { - ZVAL_COPY(&dupch->handlers->passwd, &ch->handlers->passwd); - curl_easy_setopt(ch->cp, CURLOPT_PASSWDDATA, (void *) dupch); - } -#endif - if (!Z_ISUNDEF(ch->handlers->write->func_name)) { - ZVAL_COPY(&dupch->handlers->write->func_name, &ch->handlers->write->func_name); - } - if (!Z_ISUNDEF(ch->handlers->read->func_name)) { - ZVAL_COPY(&dupch->handlers->read->func_name, &ch->handlers->read->func_name); - } - if (!Z_ISUNDEF(ch->handlers->write_header->func_name)) { - ZVAL_COPY(&dupch->handlers->write_header->func_name, &ch->handlers->write_header->func_name); - } - - curl_easy_setopt(dupch->cp, CURLOPT_ERRORBUFFER, dupch->err.str); - curl_easy_setopt(dupch->cp, CURLOPT_FILE, (void *) dupch); - curl_easy_setopt(dupch->cp, CURLOPT_INFILE, (void *) dupch); - curl_easy_setopt(dupch->cp, CURLOPT_WRITEHEADER, (void *) dupch); - - if (ch->handlers->progress) { - dupch->handlers->progress = ecalloc(1, sizeof(php_curl_progress)); - if (!Z_ISUNDEF(ch->handlers->progress->func_name)) { - ZVAL_COPY(&dupch->handlers->progress->func_name, &ch->handlers->progress->func_name); - } - dupch->handlers->progress->method = ch->handlers->progress->method; - curl_easy_setopt(dupch->cp, CURLOPT_PROGRESSDATA, (void *) dupch); - } - -/* Available since 7.21.0 */ -#if LIBCURL_VERSION_NUM >= 0x071500 - if (ch->handlers->fnmatch) { - dupch->handlers->fnmatch = ecalloc(1, sizeof(php_curl_fnmatch)); - if (!Z_ISUNDEF(ch->handlers->fnmatch->func_name)) { - ZVAL_COPY(&dupch->handlers->fnmatch->func_name, &ch->handlers->fnmatch->func_name); - } - dupch->handlers->fnmatch->method = ch->handlers->fnmatch->method; - curl_easy_setopt(dupch->cp, CURLOPT_FNMATCH_DATA, (void *) dupch); - } -#endif - efree(dupch->to_free->slist); - efree(dupch->to_free); - dupch->to_free = ch->to_free; - efree(dupch->clone); - dupch->clone = ch->clone; + _php_setup_easy_copy_handlers(dupch, ch); - /* Keep track of cloned copies to avoid invoking curl destructors for every clone */ - (*ch->clone)++; + Z_ADDREF_P(zid); ZVAL_RES(return_value, zend_register_resource(dupch, le_curl)); dupch->res = Z_RES_P(return_value); @@ -3325,9 +3338,7 @@ PHP_FUNCTION(curl_close) return; } - if (Z_REFCOUNT_P(zid) <= 2) { - zend_list_close(Z_RES_P(zid)); - } + zend_list_close(Z_RES_P(zid)); } /* }}} */ @@ -3352,10 +3363,12 @@ static void _php_curl_close_ex(php_curl *ch) * * Libcurl commit d021f2e8a00 fix this issue and should be part of 7.28.2 */ - curl_easy_setopt(ch->cp, CURLOPT_HEADERFUNCTION, curl_write_nothing); - curl_easy_setopt(ch->cp, CURLOPT_WRITEFUNCTION, curl_write_nothing); + if (ch->cp != NULL) { + curl_easy_setopt(ch->cp, CURLOPT_HEADERFUNCTION, curl_write_nothing); + curl_easy_setopt(ch->cp, CURLOPT_WRITEFUNCTION, curl_write_nothing); - curl_easy_cleanup(ch->cp); + curl_easy_cleanup(ch->cp); + } /* cURL destructors should be invoked only by last curl handle */ if (--(*ch->clone) == 0) { |