@@ -511,6 +511,12 @@ static HashTable *curl_get_gc(zend_object *object, zval **table, int *n)
511
511
}
512
512
#endif
513
513
514
+ #if LIBCURL_VERSION_NUM >= 0x075000
515
+ if (curl -> handlers .prereq ) {
516
+ zend_get_gc_buffer_add_zval (gc_buffer , & curl -> handlers .prereq -> func_name );
517
+ }
518
+ #endif
519
+
514
520
if (curl -> handlers .fnmatch ) {
515
521
zend_get_gc_buffer_add_zval (gc_buffer , & curl -> handlers .fnmatch -> func_name );
516
522
}
@@ -956,6 +962,66 @@ static size_t curl_write_header(char *data, size_t size, size_t nmemb, void *ctx
956
962
}
957
963
/* }}} */
958
964
965
+ #if LIBCURL_VERSION_NUM >= 0x075000
966
+ static int curl_prereqfunction (void * clientp , char * conn_primary_ip , char * conn_local_ip , int conn_primary_port , int conn_local_port )
967
+ {
968
+ php_curl * ch = (php_curl * )clientp ;
969
+ php_curl_callback * t = ch -> handlers .prereq ;
970
+
971
+ int rval = CURL_PREREQFUNC_ABORT ; /* Disallow the request by default. */
972
+
973
+ #if PHP_CURL_DEBUG
974
+ fprintf (stderr , "curl_prereqfunction() called\n" );
975
+ 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 , c , onn_primary_port , conn_local_port );
976
+ #endif
977
+
978
+ zval argv [5 ];
979
+ zval retval ;
980
+ zend_result error ;
981
+ zend_fcall_info fci ;
982
+
983
+ GC_ADDREF (& ch -> std );
984
+ ZVAL_OBJ (& argv [0 ], & ch -> std );
985
+ ZVAL_STRING (& argv [1 ], conn_primary_ip );
986
+ ZVAL_STRING (& argv [2 ], conn_local_ip );
987
+ ZVAL_LONG (& argv [3 ], conn_primary_port );
988
+ ZVAL_LONG (& argv [4 ], conn_local_port );
989
+
990
+ fci .size = sizeof (fci );
991
+ ZVAL_COPY_VALUE (& fci .function_name , & t -> func_name );
992
+ fci .object = NULL ;
993
+ fci .retval = & retval ;
994
+ fci .param_count = 5 ;
995
+ fci .params = argv ;
996
+ fci .named_params = NULL ;
997
+
998
+ ch -> in_callback = 1 ;
999
+ error = zend_call_function (& fci , & t -> fci_cache );
1000
+ ch -> in_callback = 0 ;
1001
+ if (error == FAILURE ) {
1002
+ php_error_docref (NULL , E_WARNING , "Cannot call the CURLOPT_PREREQFUNCTION" );
1003
+ } else if (!Z_ISUNDEF (retval )) {
1004
+ _php_curl_verify_handlers (ch , true);
1005
+ if (Z_TYPE (retval ) == IS_LONG ) {
1006
+ zend_long retval_long = Z_LVAL (retval );
1007
+ if (retval_long == CURL_PREREQFUNC_OK || retval_long == CURL_PREREQFUNC_ABORT ) {
1008
+ rval = retval_long ;
1009
+ } else {
1010
+ zend_throw_error (NULL , "The CURLOPT_PREREQFUNCTION callback must return either CURL_PREREQFUNC_OK or CURL_PREREQFUNC_ABORT" );
1011
+ }
1012
+ } else {
1013
+ zend_throw_error (NULL , "The CURLOPT_PREREQFUNCTION callback must return either CURL_PREREQFUNC_OK or CURL_PREREQFUNC_ABORT" );
1014
+ }
1015
+ }
1016
+ zval_ptr_dtor (& argv [0 ]);
1017
+ zval_ptr_dtor (& argv [1 ]);
1018
+ zval_ptr_dtor (& argv [2 ]);
1019
+
1020
+ return rval ;
1021
+ }
1022
+
1023
+ #endif
1024
+
959
1025
static int curl_debug (CURL * cp , curl_infotype type , char * buf , size_t buf_len , void * ctx ) /* {{{ */
960
1026
{
961
1027
php_curl * ch = (php_curl * )ctx ;
@@ -1090,6 +1156,9 @@ void init_curl_handle(php_curl *ch)
1090
1156
ch -> handlers .progress = NULL ;
1091
1157
#if LIBCURL_VERSION_NUM >= 0x072000
1092
1158
ch -> handlers .xferinfo = NULL ;
1159
+ #endif
1160
+ #if LIBCURL_VERSION_NUM >= 0x075000
1161
+ ch -> handlers .prereq = NULL ;
1093
1162
#endif
1094
1163
ch -> handlers .fnmatch = NULL ;
1095
1164
#if LIBCURL_VERSION_NUM >= 0x075400
@@ -1272,6 +1341,9 @@ void _php_setup_easy_copy_handlers(php_curl *ch, php_curl *source)
1272
1341
_php_copy_callback (ch , & ch -> handlers .progress , source -> handlers .progress , CURLOPT_PROGRESSDATA );
1273
1342
#if LIBCURL_VERSION_NUM >= 0x072000
1274
1343
_php_copy_callback (ch , & ch -> handlers .xferinfo , source -> handlers .xferinfo , CURLOPT_XFERINFODATA );
1344
+ #endif
1345
+ #if LIBCURL_VERSION_NUM >= 0x075000
1346
+ _php_copy_callback (ch , & ch -> handlers .prereq , source -> handlers .prereq , CURLOPT_PREREQFUNCTION );
1275
1347
#endif
1276
1348
_php_copy_callback (ch , & ch -> handlers .fnmatch , source -> handlers .fnmatch , CURLOPT_FNMATCH_DATA );
1277
1349
#if LIBCURL_VERSION_NUM >= 0x075400
@@ -2330,6 +2402,20 @@ static zend_result _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue
2330
2402
break ;
2331
2403
#endif
2332
2404
2405
+ #if LIBCURL_VERSION_NUM >= 0x075000
2406
+ case CURLOPT_PREREQFUNCTION :
2407
+ curl_easy_setopt (ch -> cp , CURLOPT_PREREQFUNCTION , curl_prereqfunction );
2408
+ curl_easy_setopt (ch -> cp , CURLOPT_PREREQDATA , ch );
2409
+ if (ch -> handlers .prereq == NULL ) {
2410
+ ch -> handlers .prereq = ecalloc (1 , sizeof (php_curl_callback ));
2411
+ } else if (!Z_ISUNDEF (ch -> handlers .prereq -> func_name )) {
2412
+ zval_ptr_dtor (& ch -> handlers .prereq -> func_name );
2413
+ ch -> handlers .prereq -> fci_cache = empty_fcall_info_cache ;
2414
+ }
2415
+ ZVAL_COPY (& ch -> handlers .prereq -> func_name , zvalue );
2416
+ break ;
2417
+ #endif
2418
+
2333
2419
/* Curl off_t options */
2334
2420
case CURLOPT_MAX_RECV_SPEED_LARGE :
2335
2421
case CURLOPT_MAX_SEND_SPEED_LARGE :
@@ -2991,6 +3077,9 @@ static void curl_free_obj(zend_object *object)
2991
3077
#if LIBCURL_VERSION_NUM >= 0x075400
2992
3078
_php_curl_free_callback (ch -> handlers .sshhostkey );
2993
3079
#endif
3080
+ #if LIBCURL_VERSION_NUM >= 0x075000
3081
+ _php_curl_free_callback (ch -> handlers .prereq );
3082
+ #endif
2994
3083
2995
3084
zval_ptr_dtor (& ch -> postfields );
2996
3085
zval_ptr_dtor (& ch -> private_data );
@@ -3067,6 +3156,14 @@ static void _php_curl_reset_handlers(php_curl *ch)
3067
3156
}
3068
3157
#endif
3069
3158
3159
+ #if LIBCURL_VERSION_NUM >= 0x075000
3160
+ if (ch -> handlers .prereq ) {
3161
+ zval_ptr_dtor (& ch -> handlers .prereq -> func_name );
3162
+ efree (ch -> handlers .prereq );
3163
+ ch -> handlers .prereq = NULL ;
3164
+ }
3165
+ #endif
3166
+
3070
3167
if (ch -> handlers .fnmatch ) {
3071
3168
zval_ptr_dtor (& ch -> handlers .fnmatch -> func_name );
3072
3169
efree (ch -> handlers .fnmatch );
0 commit comments