@@ -1472,12 +1472,46 @@ static bool php_curl_set_callable_handler(zend_fcall_info_cache *const handler_f
14721472 return true;
14731473}
14741474
1475+
1476+ #define HANDLE_CURL_OPTION_CALLABLE_PHP_CURL_USER (curl_ptr , constant_no_function , handler_type ) \
1477+ case constant_no_function##FUNCTION: { \
1478+ bool result = php_curl_set_callable_handler(&curl_ptr->handlers.handler_type->fcc, zvalue, is_array_config, #constant_no_function "FUNCTION"); \
1479+ if (!result) { \
1480+ return FAILURE; \
1481+ } \
1482+ curl_ptr->handlers.handler_type->method = PHP_CURL_USER; \
1483+ break; \
1484+ }
1485+
1486+ #define HANDLE_CURL_OPTION_CALLABLE (curl_ptr , constant_no_function , handler_fcc , c_callback ) \
1487+ case constant_no_function##FUNCTION: { \
1488+ bool result = php_curl_set_callable_handler(&curl_ptr->handler_fcc, zvalue, is_array_config, #constant_no_function "FUNCTION"); \
1489+ if (!result) { \
1490+ return FAILURE; \
1491+ } \
1492+ curl_easy_setopt(curl_ptr->cp, constant_no_function##FUNCTION, (c_callback)); \
1493+ curl_easy_setopt(curl_ptr->cp, constant_no_function##DATA, curl_ptr); \
1494+ break; \
1495+ }
1496+
14751497static zend_result _php_curl_setopt (php_curl * ch , zend_long option , zval * zvalue , bool is_array_config ) /* {{{ */
14761498{
14771499 CURLcode error = CURLE_OK ;
14781500 zend_long lval ;
14791501
14801502 switch (option ) {
1503+ /* Callable options */
1504+ HANDLE_CURL_OPTION_CALLABLE_PHP_CURL_USER (ch , CURLOPT_WRITE , write );
1505+ HANDLE_CURL_OPTION_CALLABLE_PHP_CURL_USER (ch , CURLOPT_HEADER , write_header );
1506+ HANDLE_CURL_OPTION_CALLABLE_PHP_CURL_USER (ch , CURLOPT_READ , read );
1507+
1508+ HANDLE_CURL_OPTION_CALLABLE (ch , CURLOPT_PROGRESS , handlers .progress , curl_progress );
1509+ HANDLE_CURL_OPTION_CALLABLE (ch , CURLOPT_XFERINFO , handlers .xferinfo , curl_xferinfo );
1510+ HANDLE_CURL_OPTION_CALLABLE (ch , CURLOPT_FNMATCH_ , handlers .fnmatch , curl_fnmatch );
1511+ #if LIBCURL_VERSION_NUM >= 0x075400 /* Available since 7.84.0 */
1512+ HANDLE_CURL_OPTION_CALLABLE (ch , CURLOPT_SSH_HOSTKEY , handlers .sshhostkey , curl_ssh_hostkeyfunction );
1513+ #endif
1514+
14811515 /* Long options */
14821516 case CURLOPT_SSL_VERIFYHOST :
14831517 lval = zval_get_long (zvalue );
@@ -2007,88 +2041,6 @@ static zend_result _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue
20072041 }
20082042 break ;
20092043
2010- case CURLOPT_WRITEFUNCTION : {
2011- /* Check value is actually a callable and set it */
2012- const char option_name [] = "CURLOPT_WRITEFUNCTION" ;
2013- bool result = php_curl_set_callable_handler (& ch -> handlers .write -> fcc , zvalue , is_array_config , option_name );
2014- if (!result ) {
2015- return FAILURE ;
2016- }
2017- ch -> handlers .write -> method = PHP_CURL_USER ;
2018- break ;
2019- }
2020-
2021- case CURLOPT_HEADERFUNCTION : {
2022- /* Check value is actually a callable and set it */
2023- const char option_name [] = "CURLOPT_HEADERFUNCTION" ;
2024- bool result = php_curl_set_callable_handler (& ch -> handlers .write_header -> fcc , zvalue , is_array_config , option_name );
2025- if (!result ) {
2026- return FAILURE ;
2027- }
2028- ch -> handlers .write_header -> method = PHP_CURL_USER ;
2029- break ;
2030- }
2031-
2032- case CURLOPT_READFUNCTION :
2033- /* Check value is actually a callable and set it */
2034- const char option_name [] = "CURLOPT_READFUNCTION" ;
2035- bool result = php_curl_set_callable_handler (& ch -> handlers .read -> fcc , zvalue , is_array_config , option_name );
2036- if (!result ) {
2037- return FAILURE ;
2038- }
2039- ch -> handlers .read -> method = PHP_CURL_USER ;
2040- break ;
2041-
2042- case CURLOPT_PROGRESSFUNCTION : {
2043- /* Check value is actually a callable and set it */
2044- const char option_name [] = "CURLOPT_PROGRESSFUNCTION" ;
2045- bool result = php_curl_set_callable_handler (& ch -> handlers .progress , zvalue , is_array_config , option_name );
2046- if (!result ) {
2047- return FAILURE ;
2048- }
2049- curl_easy_setopt (ch -> cp , CURLOPT_PROGRESSFUNCTION , curl_progress );
2050- curl_easy_setopt (ch -> cp , CURLOPT_PROGRESSDATA , ch );
2051- break ;
2052- }
2053-
2054- case CURLOPT_XFERINFOFUNCTION : {
2055- /* Check value is actually a callable and set it */
2056- const char option_name [] = "CURLOPT_XFERINFOFUNCTION" ;
2057- bool result = php_curl_set_callable_handler (& ch -> handlers .xferinfo , zvalue , is_array_config , option_name );
2058- if (!result ) {
2059- return FAILURE ;
2060- }
2061- curl_easy_setopt (ch -> cp , CURLOPT_XFERINFOFUNCTION , curl_xferinfo );
2062- curl_easy_setopt (ch -> cp , CURLOPT_XFERINFODATA , ch );
2063- break ;
2064- }
2065-
2066- case CURLOPT_FNMATCH_FUNCTION : {
2067- /* Check value is actually a callable and set it */
2068- const char option_name [] = "CURLOPT_FNMATCH_FUNCTION" ;
2069- bool result = php_curl_set_callable_handler (& ch -> handlers .fnmatch , zvalue , is_array_config , option_name );
2070- if (!result ) {
2071- return FAILURE ;
2072- }
2073- curl_easy_setopt (ch -> cp , CURLOPT_FNMATCH_FUNCTION , curl_fnmatch );
2074- curl_easy_setopt (ch -> cp , CURLOPT_FNMATCH_DATA , ch );
2075- break ;
2076- }
2077-
2078- #if LIBCURL_VERSION_NUM >= 0x075400 /* Available since 7.84.0 */
2079- case CURLOPT_SSH_HOSTKEYFUNCTION : {
2080- /* Check value is actually a callable and set it */
2081- const char option_name [] = "CURLOPT_SSH_HOSTKEYFUNCTION" ;
2082- bool result = php_curl_set_callable_handler (& ch -> handlers .sshhostkey , zvalue , is_array_config , option_name );
2083- if (!result ) {
2084- return FAILURE ;
2085- }
2086- curl_easy_setopt (ch -> cp , CURLOPT_SSH_HOSTKEYFUNCTION , curl_ssh_hostkeyfunction );
2087- curl_easy_setopt (ch -> cp , CURLOPT_SSH_HOSTKEYDATA , ch );
2088- break ;
2089- }
2090- #endif
2091-
20922044 case CURLOPT_RETURNTRANSFER :
20932045 if (zend_is_true (zvalue )) {
20942046 ch -> handlers .write -> method = PHP_CURL_RETURN ;
0 commit comments