@@ -504,6 +504,11 @@ static HashTable *curl_get_gc(zend_object *object, zval **table, int *n)
504504 zend_get_gc_buffer_add_fcc (gc_buffer , & curl -> handlers .fnmatch );
505505 }
506506
507+ #if LIBCURL_VERSION_NUM >= 0x075000 /* Available since 7.80.0 */
508+ if (ZEND_FCC_INITIALIZED (curl -> handlers .prereq )) {
509+ zend_get_gc_buffer_add_fcc (gc_buffer , & curl -> handlers .prereq );
510+ }
511+ #endif
507512#if LIBCURL_VERSION_NUM >= 0x075400 /* Available since 7.84.0 */
508513 if (ZEND_FCC_INITIALIZED (curl -> handlers .sshhostkey )) {
509514 zend_get_gc_buffer_add_fcc (gc_buffer , & curl -> handlers .sshhostkey );
@@ -709,6 +714,53 @@ static size_t curl_xferinfo(void *clientp, curl_off_t dltotal, curl_off_t dlnow,
709714}
710715/* }}} */
711716
717+ #if LIBCURL_VERSION_NUM >= 0x075000 /* Available since 7.80.0 */
718+ static int curl_prereqfunction (void * clientp , char * conn_primary_ip , char * conn_local_ip , int conn_primary_port , int conn_local_port )
719+ {
720+ php_curl * ch = (php_curl * )clientp ;
721+ int rval = CURL_PREREQFUNC_ABORT ;
722+
723+ #if PHP_CURL_DEBUG
724+ fprintf (stderr , "curl_prereqfunction() called\n" );
725+ fprintf (stderr , "clientp = %x, conn_primary_ip = %s, conn_local_ip = %s, conn_primary_port = %d, conn_local_port = %d\n" , clientp , conn_primary_ip , conn_local_ip , conn_primary_port , conn_local_port );
726+ #endif
727+
728+ zval args [5 ];
729+ zval retval ;
730+
731+ GC_ADDREF (& ch -> std );
732+ ZVAL_OBJ (& args [0 ], & ch -> std );
733+ ZVAL_STRING (& args [1 ], conn_primary_ip );
734+ ZVAL_STRING (& args [2 ], conn_local_ip );
735+ ZVAL_LONG (& args [3 ], conn_primary_port );
736+ ZVAL_LONG (& args [4 ], conn_local_port );
737+
738+ ch -> in_callback = true;
739+ zend_call_known_fcc (& ch -> handlers .prereq , & retval , /* param_count */ 5 , args , /* named_params */ NULL );
740+ ch -> in_callback = false;
741+
742+ if (!Z_ISUNDEF (retval )) {
743+ _php_curl_verify_handlers (ch , /* reporterror */ true);
744+ if (Z_TYPE (retval ) == IS_LONG ) {
745+ zend_long retval_long = Z_LVAL (retval );
746+ if (retval_long == CURL_PREREQFUNC_OK || retval_long == CURL_PREREQFUNC_ABORT ) {
747+ rval = retval_long ;
748+ } else {
749+ zend_value_error ("The CURLOPT_PREREQFUNCTION callback must return either CURL_PREREQFUNC_OK or CURL_PREREQFUNC_ABORT" );
750+ }
751+ } else {
752+ zend_type_error ("The CURLOPT_PREREQFUNCTION callback must return either CURL_PREREQFUNC_OK or CURL_PREREQFUNC_ABORT" );
753+ }
754+ }
755+
756+ zval_ptr_dtor (& args [0 ]);
757+ zval_ptr_dtor (& args [1 ]);
758+ zval_ptr_dtor (& args [2 ]);
759+
760+ return rval ;
761+ }
762+ #endif
763+
712764#if LIBCURL_VERSION_NUM >= 0x075400 /* Available since 7.84.0 */
713765static int curl_ssh_hostkeyfunction (void * clientp , int keytype , const char * key , size_t keylen )
714766{
@@ -1037,6 +1089,9 @@ void init_curl_handle(php_curl *ch)
10371089 ch -> handlers .progress = empty_fcall_info_cache ;
10381090 ch -> handlers .xferinfo = empty_fcall_info_cache ;
10391091 ch -> handlers .fnmatch = empty_fcall_info_cache ;
1092+ #if LIBCURL_VERSION_NUM >= 0x075000 /* Available since 7.80.0 */
1093+ ch -> handlers .prereq = empty_fcall_info_cache ;
1094+ #endif
10401095#if LIBCURL_VERSION_NUM >= 0x075400 /* Available since 7.84.0 */
10411096 ch -> handlers .sshhostkey = empty_fcall_info_cache ;
10421097#endif
@@ -1210,6 +1265,9 @@ void _php_setup_easy_copy_handlers(php_curl *ch, php_curl *source)
12101265 php_curl_copy_fcc_with_option (ch , CURLOPT_PROGRESSDATA , & ch -> handlers .progress , & source -> handlers .progress );
12111266 php_curl_copy_fcc_with_option (ch , CURLOPT_XFERINFODATA , & ch -> handlers .xferinfo , & source -> handlers .xferinfo );
12121267 php_curl_copy_fcc_with_option (ch , CURLOPT_FNMATCH_DATA , & ch -> handlers .fnmatch , & source -> handlers .fnmatch );
1268+ #if LIBCURL_VERSION_NUM >= 0x075000 /* Available since 7.80.0 */
1269+ php_curl_copy_fcc_with_option (ch , CURLOPT_PREREQDATA , & ch -> handlers .prereq , & source -> handlers .prereq );
1270+ #endif
12131271#if LIBCURL_VERSION_NUM >= 0x075400 /* Available since 7.84.0 */
12141272 php_curl_copy_fcc_with_option (ch , CURLOPT_SSH_HOSTKEYDATA , & ch -> handlers .sshhostkey , & source -> handlers .sshhostkey );
12151273#endif
@@ -1570,6 +1628,9 @@ static zend_result _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue
15701628 HANDLE_CURL_OPTION_CALLABLE (ch , CURLOPT_PROGRESS , handlers .progress , curl_progress );
15711629 HANDLE_CURL_OPTION_CALLABLE (ch , CURLOPT_XFERINFO , handlers .xferinfo , curl_xferinfo );
15721630 HANDLE_CURL_OPTION_CALLABLE (ch , CURLOPT_FNMATCH_ , handlers .fnmatch , curl_fnmatch );
1631+ #if LIBCURL_VERSION_NUM >= 0x075000 /* Available since 7.80.0 */
1632+ HANDLE_CURL_OPTION_CALLABLE (ch , CURLOPT_PREREQ , handlers .prereq , curl_prereqfunction );
1633+ #endif
15731634#if LIBCURL_VERSION_NUM >= 0x075400 /* Available since 7.84.0 */
15741635 HANDLE_CURL_OPTION_CALLABLE (ch , CURLOPT_SSH_HOSTKEY , handlers .sshhostkey , curl_ssh_hostkeyfunction );
15751636#endif
@@ -2736,6 +2797,11 @@ static void curl_free_obj(zend_object *object)
27362797 if (ZEND_FCC_INITIALIZED (ch -> handlers .fnmatch )) {
27372798 zend_fcc_dtor (& ch -> handlers .fnmatch );
27382799 }
2800+ #if LIBCURL_VERSION_NUM >= 0x075000 /* Available since 7.80.0 */
2801+ if (ZEND_FCC_INITIALIZED (ch -> handlers .prereq )) {
2802+ zend_fcc_dtor (& ch -> handlers .prereq );
2803+ }
2804+ #endif
27392805#if LIBCURL_VERSION_NUM >= 0x075400 /* Available since 7.84.0 */
27402806 if (ZEND_FCC_INITIALIZED (ch -> handlers .sshhostkey )) {
27412807 zend_fcc_dtor (& ch -> handlers .sshhostkey );
@@ -2814,7 +2880,11 @@ static void _php_curl_reset_handlers(php_curl *ch)
28142880 if (ZEND_FCC_INITIALIZED (ch -> handlers .fnmatch )) {
28152881 zend_fcc_dtor (& ch -> handlers .fnmatch );
28162882 }
2817-
2883+ #if LIBCURL_VERSION_NUM >= 0x075000 /* Available since 7.80.0 */
2884+ if (ZEND_FCC_INITIALIZED (ch -> handlers .prereq )) {
2885+ zend_fcc_dtor (& ch -> handlers .prereq );
2886+ }
2887+ #endif
28182888#if LIBCURL_VERSION_NUM >= 0x075400 /* Available since 7.84.0 */
28192889 if (ZEND_FCC_INITIALIZED (ch -> handlers .sshhostkey )) {
28202890 zend_fcc_dtor (& ch -> handlers .sshhostkey );
0 commit comments