@@ -495,6 +495,12 @@ static HashTable *curl_get_gc(zend_object *object, zval **table, int *n)
495
495
zend_get_gc_buffer_add_zval (gc_buffer , & curl -> handlers .xferinfo -> func_name );
496
496
}
497
497
498
+ #if LIBCURL_VERSION_NUM >= 0x075000 /* 7.80.0 */
499
+ if (curl -> handlers .prereq ) {
500
+ zend_get_gc_buffer_add_zval (gc_buffer , & curl -> handlers .prereq -> func_name );
501
+ }
502
+ #endif
503
+
498
504
if (curl -> handlers .fnmatch ) {
499
505
zend_get_gc_buffer_add_zval (gc_buffer , & curl -> handlers .fnmatch -> func_name );
500
506
}
@@ -938,6 +944,64 @@ static size_t curl_write_header(char *data, size_t size, size_t nmemb, void *ctx
938
944
}
939
945
/* }}} */
940
946
947
+ #if LIBCURL_VERSION_NUM >= 0x075000 /* 7.80.0 */
948
+ static int curl_prereqfunction (void * clientp , char * conn_primary_ip , char * conn_local_ip , int conn_primary_port , int conn_local_port )
949
+ {
950
+ php_curl * ch = (php_curl * )clientp ;
951
+ php_curl_callback * t = ch -> handlers .prereq ;
952
+
953
+ int rval = CURL_PREREQFUNC_ABORT ; /* Disallow the request by default. */
954
+
955
+ #if PHP_CURL_DEBUG
956
+ fprintf (stderr , "curl_prereqfunction() called\n" );
957
+ 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 );
958
+ #endif
959
+
960
+ zval argv [5 ];
961
+ zval retval ;
962
+ zend_result error ;
963
+ zend_fcall_info fci ;
964
+
965
+ GC_ADDREF (& ch -> std );
966
+ ZVAL_OBJ (& argv [0 ], & ch -> std );
967
+ ZVAL_STRING (& argv [1 ], conn_primary_ip );
968
+ ZVAL_STRING (& argv [2 ], conn_local_ip );
969
+ ZVAL_LONG (& argv [3 ], conn_primary_port );
970
+ ZVAL_LONG (& argv [4 ], conn_local_port );
971
+
972
+ fci .size = sizeof (fci );
973
+ ZVAL_COPY_VALUE (& fci .function_name , & t -> func_name );
974
+ fci .object = NULL ;
975
+ fci .retval = & retval ;
976
+ fci .param_count = 5 ;
977
+ fci .params = argv ;
978
+ fci .named_params = NULL ;
979
+
980
+ ch -> in_callback = 1 ;
981
+ error = zend_call_function (& fci , & t -> fci_cache );
982
+ ch -> in_callback = 0 ;
983
+ if (!Z_ISUNDEF (retval )) {
984
+ _php_curl_verify_handlers (ch , true);
985
+ if (Z_TYPE (retval ) == IS_LONG ) {
986
+ zend_long retval_long = Z_LVAL (retval );
987
+ if (retval_long == CURL_PREREQFUNC_OK || retval_long == CURL_PREREQFUNC_ABORT ) {
988
+ rval = retval_long ;
989
+ } else {
990
+ zend_throw_error (NULL , "The CURLOPT_PREREQFUNCTION callback must return either CURL_PREREQFUNC_OK or CURL_PREREQFUNC_ABORT" );
991
+ }
992
+ } else {
993
+ zend_throw_error (NULL , "The CURLOPT_PREREQFUNCTION callback must return either CURL_PREREQFUNC_OK or CURL_PREREQFUNC_ABORT" );
994
+ }
995
+ }
996
+ zval_ptr_dtor (& argv [0 ]);
997
+ zval_ptr_dtor (& argv [1 ]);
998
+ zval_ptr_dtor (& argv [2 ]);
999
+
1000
+ return rval ;
1001
+ }
1002
+
1003
+ #endif
1004
+
941
1005
static int curl_debug (CURL * cp , curl_infotype type , char * buf , size_t buf_len , void * ctx ) /* {{{ */
942
1006
{
943
1007
php_curl * ch = (php_curl * )ctx ;
@@ -1057,6 +1121,9 @@ void init_curl_handle(php_curl *ch)
1057
1121
ch -> handlers .progress = NULL ;
1058
1122
ch -> handlers .xferinfo = NULL ;
1059
1123
ch -> handlers .fnmatch = NULL ;
1124
+ #if LIBCURL_VERSION_NUM >= 0x075000 /* 7.80.0 */
1125
+ ch -> handlers .prereq = NULL ;
1126
+ #endif
1060
1127
#if LIBCURL_VERSION_NUM >= 0x075400 /* Available since 7.84.0 */
1061
1128
ch -> handlers .sshhostkey = NULL ;
1062
1129
#endif
@@ -1233,6 +1300,9 @@ void _php_setup_easy_copy_handlers(php_curl *ch, php_curl *source)
1233
1300
_php_copy_callback (ch , & ch -> handlers .progress , source -> handlers .progress , CURLOPT_PROGRESSDATA );
1234
1301
_php_copy_callback (ch , & ch -> handlers .xferinfo , source -> handlers .xferinfo , CURLOPT_XFERINFODATA );
1235
1302
_php_copy_callback (ch , & ch -> handlers .fnmatch , source -> handlers .fnmatch , CURLOPT_FNMATCH_DATA );
1303
+ #if LIBCURL_VERSION_NUM >= 0x075000 /* 7.80.0 */
1304
+ _php_copy_callback (ch , & ch -> handlers .prereq , source -> handlers .prereq , CURLOPT_PREREQFUNCTION );
1305
+ #endif
1236
1306
#if LIBCURL_VERSION_NUM >= 0x075400 /* Available since 7.84.0 */
1237
1307
_php_copy_callback (ch , & ch -> handlers .sshhostkey , source -> handlers .sshhostkey , CURLOPT_SSH_HOSTKEYDATA );
1238
1308
#endif
@@ -2143,6 +2213,20 @@ static zend_result _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue
2143
2213
ZVAL_COPY (& ch -> handlers .xferinfo -> func_name , zvalue );
2144
2214
break ;
2145
2215
2216
+ #if LIBCURL_VERSION_NUM >= 0x075000 /* 7.80.0 */
2217
+ case CURLOPT_PREREQFUNCTION :
2218
+ curl_easy_setopt (ch -> cp , CURLOPT_PREREQFUNCTION , curl_prereqfunction );
2219
+ curl_easy_setopt (ch -> cp , CURLOPT_PREREQDATA , ch );
2220
+ if (ch -> handlers .prereq == NULL ) {
2221
+ ch -> handlers .prereq = ecalloc (1 , sizeof (php_curl_callback ));
2222
+ } else if (!Z_ISUNDEF (ch -> handlers .prereq -> func_name )) {
2223
+ zval_ptr_dtor (& ch -> handlers .prereq -> func_name );
2224
+ ch -> handlers .prereq -> fci_cache = empty_fcall_info_cache ;
2225
+ }
2226
+ ZVAL_COPY (& ch -> handlers .prereq -> func_name , zvalue );
2227
+ break ;
2228
+ #endif
2229
+
2146
2230
/* Curl off_t options */
2147
2231
case CURLOPT_MAX_RECV_SPEED_LARGE :
2148
2232
case CURLOPT_MAX_SEND_SPEED_LARGE :
@@ -2786,6 +2870,9 @@ static void curl_free_obj(zend_object *object)
2786
2870
#if LIBCURL_VERSION_NUM >= 0x075400 /* Available since 7.84.0 */
2787
2871
_php_curl_free_callback (ch -> handlers .sshhostkey );
2788
2872
#endif
2873
+ #if LIBCURL_VERSION_NUM >= 0x075000 /* 7.80.0 */
2874
+ _php_curl_free_callback (ch -> handlers .prereq );
2875
+ #endif
2789
2876
2790
2877
zval_ptr_dtor (& ch -> postfields );
2791
2878
zval_ptr_dtor (& ch -> private_data );
@@ -2860,6 +2947,14 @@ static void _php_curl_reset_handlers(php_curl *ch)
2860
2947
ch -> handlers .xferinfo = NULL ;
2861
2948
}
2862
2949
2950
+ #if LIBCURL_VERSION_NUM >= 0x075000 /* 7.80.0 */
2951
+ if (ch -> handlers .prereq ) {
2952
+ zval_ptr_dtor (& ch -> handlers .prereq -> func_name );
2953
+ efree (ch -> handlers .prereq );
2954
+ ch -> handlers .prereq = NULL ;
2955
+ }
2956
+ #endif
2957
+
2863
2958
if (ch -> handlers .fnmatch ) {
2864
2959
zval_ptr_dtor (& ch -> handlers .fnmatch -> func_name );
2865
2960
efree (ch -> handlers .fnmatch );
0 commit comments