From da2797108fb854d13df2a11a4c0712bd5e656113 Mon Sep 17 00:00:00 2001 From: Pierrick Charron Date: Wed, 23 Nov 2011 22:20:28 +0000 Subject: [PATCH] Implemented FR #55540, added functions curl_share_init(), curl_share_setopt() and curl_share_close(). --- NEWS | 4 +- ext/curl/config.m4 | 2 +- ext/curl/config.w32 | 2 +- ext/curl/curl.dsp | 4 ++ ext/curl/interface.c | 35 ++++++++++ ext/curl/package.xml | 1 + ext/curl/php_curl.h | 12 ++++ ext/curl/share.c | 151 +++++++++++++++++++++++++++++++++++++++++++ 8 files changed, 208 insertions(+), 3 deletions(-) create mode 100644 ext/curl/share.c diff --git a/NEWS b/NEWS index f71f27c2ea1..e5c2e2e3371 100644 --- a/NEWS +++ b/NEWS @@ -6,6 +6,8 @@ PHP NEWS . World domination - cURL: + . Implemented FR #55540, added functions curl_share_init(), + curl_share_setopt() and curl_share_close(). (Pierrick) . Added support for CURLOPT_FTP_RESPONSE_TIMEOUT, CURLOPT_APPEND, CURLOPT_DIRLISTONLY, CURLOPT_NEW_DIRECTORY_PERMS, CURLOPT_NEW_FILE_PERMS, CURLOPT_NETRC_FILE, CURLOPT_PREQUOTE, CURLOPT_KRBLEVEL, CURLOPT_MAXFILESIZE, @@ -25,7 +27,7 @@ PHP NEWS CURLOPT_TRANSFER_ENCODING, CURLOPT_DNS_SERVERS and CURLOPT_USE_SSL. (Pierrick) . Fixed bug #55635 (CURLOPT_BINARYTRANSFER no longer used. The constant - still exists for backward compatibility but is doing nothing). (Pierrick) + still exists for backward compatibility but is doing nothing). (Pierrick) . Fixed bug #54995 (Missing CURLINFO_RESPONSE_CODE support). (Pierrick) <<< NOTE: Insert NEWS from last stable release here prior to actual release! >>> diff --git a/ext/curl/config.m4 b/ext/curl/config.m4 index fbb4f5b4e59..19d3e59c477 100644 --- a/ext/curl/config.m4 +++ b/ext/curl/config.m4 @@ -156,6 +156,6 @@ int main(int argc, char *argv[]) AC_DEFINE(PHP_CURL_URL_WRAPPERS,1,[ ]) fi - PHP_NEW_EXTENSION(curl, interface.c multi.c streams.c, $ext_shared) + PHP_NEW_EXTENSION(curl, interface.c multi.c share.c streams.c, $ext_shared) PHP_SUBST(CURL_SHARED_LIBADD) fi diff --git a/ext/curl/config.w32 b/ext/curl/config.w32 index 930adcfd412..0d18318288c 100644 --- a/ext/curl/config.w32 +++ b/ext/curl/config.w32 @@ -13,7 +13,7 @@ if (PHP_CURL != "no") { && (((PHP_ZLIB=="no") && (CHECK_LIB("zlib_a.lib;zlib.lib", "curl", PHP_CURL))) || (PHP_ZLIB_SHARED && CHECK_LIB("zlib.lib", "curl", PHP_CURL)) || (PHP_ZLIB == "yes" && (!PHP_ZLIB_SHARED))) ) { - EXTENSION("curl", "interface.c multi.c streams.c", true); + EXTENSION("curl", "interface.c multi.c share.c streams.c", true); AC_DEFINE('HAVE_CURL', 1, 'Have cURL library'); AC_DEFINE('HAVE_CURL_SSL', 1, 'Have SSL suppurt in cURL'); AC_DEFINE('HAVE_CURL_EASY_STRERROR', 1, 'Have curl_easy_strerror in cURL'); diff --git a/ext/curl/curl.dsp b/ext/curl/curl.dsp index 81d823183d2..6524fceb899 100644 --- a/ext/curl/curl.dsp +++ b/ext/curl/curl.dsp @@ -165,6 +165,10 @@ SOURCE=.\interface.c SOURCE=.\multi.c # End Source File +# Begin Source File +SOURCE=.\share.c +# End Source File + # Begin Source File SOURCE=.\streams.c # End Source File diff --git a/ext/curl/interface.c b/ext/curl/interface.c index 176a7fea929..602220ae413 100644 --- a/ext/curl/interface.c +++ b/ext/curl/interface.c @@ -90,6 +90,7 @@ int le_curl; int le_curl_multi_handle; +int le_curl_share_handle; #ifdef PHP_CURL_NEED_OPENSSL_TSL /* {{{ */ static MUTEX_T *php_curl_openssl_tsl = NULL; @@ -348,6 +349,19 @@ ZEND_END_ARG_INFO() ZEND_BEGIN_ARG_INFO(arginfo_curl_multi_close, 0) ZEND_ARG_INFO(0, mh) ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_curl_share_init, 0) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_curl_share_close, 0) + ZEND_ARG_INFO(0, sh) +ZEND_END_ARG_INFO() + +ZEND_BEGIN_ARG_INFO(arginfo_curl_share_setopt, 0) + ZEND_ARG_INFO(0, sh) + ZEND_ARG_INFO(0, option) + ZEND_ARG_INFO(0, value) +ZEND_END_ARG_INFO() /* }}} */ /* {{{ curl_functions[] @@ -371,6 +385,9 @@ 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_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_END }; /* }}} */ @@ -527,6 +544,7 @@ PHP_MINIT_FUNCTION(curl) { le_curl = zend_register_list_destructors_ex(_php_curl_close, NULL, "curl", module_number); le_curl_multi_handle = zend_register_list_destructors_ex(_php_curl_multi_close, NULL, "curl_multi", module_number); + le_curl_share_handle = zend_register_list_destructors_ex(_php_curl_share_close, NULL, "curl_share", module_number); REGISTER_INI_ENTRIES(); @@ -989,6 +1007,14 @@ PHP_MINIT_FUNCTION(curl) REGISTER_CURL_CONSTANT(CURLFTPMETHOD_SINGLECWD); #endif + /* Constant for curl_share_setopt */ + REGISTER_CURL_CONSTANT(CURLOPT_SHARE); + REGISTER_CURL_CONSTANT(CURLSHOPT_SHARE); + REGISTER_CURL_CONSTANT(CURLSHOPT_UNSHARE); + REGISTER_CURL_CONSTANT(CURL_LOCK_DATA_COOKIE); + REGISTER_CURL_CONSTANT(CURL_LOCK_DATA_DNS); + REGISTER_CURL_CONSTANT(CURL_LOCK_DATA_SSL_SESSION); + #ifdef PHP_CURL_NEED_OPENSSL_TSL if (!CRYPTO_get_id_callback()) { int i, c = CRYPTO_num_locks(); @@ -2417,6 +2443,15 @@ string_copy: curl_easy_setopt(ch->cp, CURLOPT_VERBOSE, 0); } break; + case CURLOPT_SHARE: + { + php_curlsh *sh = NULL; + ZEND_FETCH_RESOURCE(sh, php_curlsh *, zvalue, -1, le_curl_share_handle_name, le_curl_share_handle); + if (sh) { + curl_easy_setopt(ch->cp, CURLOPT_SHARE, sh->share); + } + } + } SAVE_CURL_ERROR(ch, error); diff --git a/ext/curl/package.xml b/ext/curl/package.xml index 85cb634c631..c14321738df 100644 --- a/ext/curl/package.xml +++ b/ext/curl/package.xml @@ -39,6 +39,7 @@ package.xml added to support installation using pear installer + diff --git a/ext/curl/php_curl.h b/ext/curl/php_curl.h index 6acfc5eedde..d44a175e6e3 100644 --- a/ext/curl/php_curl.h +++ b/ext/curl/php_curl.h @@ -53,6 +53,8 @@ extern int le_curl; #define le_curl_name "cURL handle" extern int le_curl_multi_handle; #define le_curl_multi_handle_name "cURL Multi Handle" +extern int le_curl_share_handle; +#define le_curl_share_handle_name "cURL Share Handle" PHP_MINIT_FUNCTION(curl); PHP_MSHUTDOWN_FUNCTION(curl); @@ -75,7 +77,12 @@ PHP_FUNCTION(curl_multi_exec); PHP_FUNCTION(curl_multi_getcontent); PHP_FUNCTION(curl_multi_info_read); PHP_FUNCTION(curl_multi_close); +PHP_FUNCTION(curl_share_init); +PHP_FUNCTION(curl_share_close); +PHP_FUNCTION(curl_share_setopt); + void _php_curl_multi_close(zend_rsrc_list_entry * TSRMLS_DC); +void _php_curl_share_close(zend_rsrc_list_entry * TSRMLS_DC); typedef struct { zval *func_name; @@ -145,6 +152,11 @@ typedef struct { zend_llist easyh; } php_curlm; +typedef struct { + CURLSH *share; + MUTEX_T locks[CURL_LOCK_DATA_LAST]; +} php_curlsh; + void _php_curl_cleanup_handle(php_curl *); void _php_curl_multi_cleanup_list(void *data); int _php_curl_verify_handlers(php_curl *ch, int reporterror TSRMLS_DC); diff --git a/ext/curl/share.c b/ext/curl/share.c new file mode 100644 index 00000000000..b0834c99821 --- /dev/null +++ b/ext/curl/share.c @@ -0,0 +1,151 @@ +/* + +----------------------------------------------------------------------+ + | PHP Version 5 | + +----------------------------------------------------------------------+ + | Copyright (c) 1997-2011 The PHP Group | + +----------------------------------------------------------------------+ + | This source file is subject to version 3.01 of the PHP license, | + | that is bundled with this package in the file LICENSE, and is | + | available through the world-wide-web at the following url: | + | http://www.php.net/license/3_01.txt | + | If you did not receive a copy of the PHP license and are unable to | + | obtain it through the world-wide-web, please send a note to | + | license@php.net so we can mail you a copy immediately. | + +----------------------------------------------------------------------+ + | Author: Pierrick Charron | + +----------------------------------------------------------------------+ +*/ + +/* $Id$ */ + +#define ZEND_INCLUDE_FULL_WINDOWS_HEADERS + +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "php.h" + +#if HAVE_CURL + +#include "php_curl.h" + +#include + +static void _php_curl_share_lock(CURL *handle, curl_lock_data data, curl_lock_access laccess, void *ctx) { + php_curlsh *sh = (php_curlsh *) ctx; + tsrm_mutex_lock(&sh->locks[data]); +} + +static void _php_curl_share_unlock(CURL *handle, curl_lock_data data, void *ctx) { + php_curlsh *sh = (php_curlsh *) ctx; + tsrm_mutex_unlock(&sh->locks[data]); +} + + +/* {{{ proto void curl_share_init() + Initialize a share curl handle */ +PHP_FUNCTION(curl_share_init) +{ + php_curlsh *sh; + + if (zend_parse_parameters_none() == FAILURE) { + return; + } + + sh = ecalloc(1, sizeof(php_curlsh)); + + sh->share = curl_share_init(); + + curl_share_setopt(sh->share, CURLSHOPT_LOCKFUNC, _php_curl_share_lock); + curl_share_setopt(sh->share, CURLSHOPT_UNLOCKFUNC, _php_curl_share_unlock); + curl_share_setopt(sh->share, CURLSHOPT_USERDATA, sh); + + ZEND_REGISTER_RESOURCE(return_value, sh, le_curl_share_handle); +} +/* }}} */ + +/* {{{ proto void curl_share_close(resource sh) + Close a set of cURL handles */ +PHP_FUNCTION(curl_share_close) +{ + zval *z_sh; + php_curlsh *sh; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &z_sh) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(sh, php_curlsh *, &z_sh, -1, le_curl_share_handle_name, le_curl_share_handle); + zend_list_delete(Z_LVAL_P(z_sh)); +} +/* }}} */ + +static int _php_curl_share_setopt(php_curlsh *sh, long option, zval **zvalue, zval *return_value TSRMLS_DC) /* {{{ */ +{ + CURLSHcode error = CURLSHE_OK; + + switch (option) { + case CURLSHOPT_SHARE: + case CURLSHOPT_UNSHARE: + convert_to_long_ex(zvalue); + error = curl_share_setopt(sh->share, option, Z_LVAL_PP(zvalue)); + break; + } + + if (error != CURLE_OK) { + return 1; + } else { + return 0; + } +} +/* }}} */ + +/* {{{ proto bool curl_share_setopt(resource sh, int option, mixed value) + Set an option for a cURL transfer */ +PHP_FUNCTION(curl_share_setopt) +{ + zval *zid, **zvalue; + long options; + php_curlsh *sh; + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rlZ", &zid, &options, &zvalue) == FAILURE) { + return; + } + + ZEND_FETCH_RESOURCE(sh, php_curlsh *, &zid, -1, le_curl_share_handle_name, le_curl_share_handle); + + if (options <= 0) { + php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid curl share configuration option"); + RETURN_FALSE; + } + + if (!_php_curl_share_setopt(sh, options, zvalue, return_value TSRMLS_CC)) { + RETURN_TRUE; + } else { + RETURN_FALSE; + } +} +/* }}} */ + +void _php_curl_share_close(zend_rsrc_list_entry *rsrc TSRMLS_DC) /* {{{ */ +{ + php_curlsh *sh = (php_curlsh *) rsrc->ptr; + if (sh) { + curl_share_cleanup(sh->share); + efree(sh); + rsrc->ptr = NULL; + } +} +/* }}} */ + +#endif + +/* + * Local variables: + * tab-width: 4 + * c-basic-offset: 4 + * End: + * vim600: noet sw=4 ts=4 fdm=marker + * vim<600: noet sw=4 ts=4 + */