@@ -478,12 +478,16 @@ static HashTable *curl_get_gc(zend_object *object, zval **table, int *n)
478
478
}
479
479
480
480
if (curl -> handlers .write ) {
481
- zend_get_gc_buffer_add_zval (gc_buffer , & curl -> handlers .write -> func_name );
481
+ if (ZEND_FCC_INITIALIZED (curl -> handlers .write -> fcc )) {
482
+ zend_get_gc_buffer_add_fcc (gc_buffer , & curl -> handlers .write -> fcc );
483
+ }
482
484
zend_get_gc_buffer_add_zval (gc_buffer , & curl -> handlers .write -> stream );
483
485
}
484
486
485
487
if (curl -> handlers .write_header ) {
486
- zend_get_gc_buffer_add_zval (gc_buffer , & curl -> handlers .write_header -> func_name );
488
+ if (ZEND_FCC_INITIALIZED (curl -> handlers .write_header -> fcc )) {
489
+ zend_get_gc_buffer_add_fcc (gc_buffer , & curl -> handlers .write_header -> fcc );
490
+ }
487
491
zend_get_gc_buffer_add_zval (gc_buffer , & curl -> handlers .write_header -> stream );
488
492
}
489
493
@@ -562,51 +566,39 @@ static size_t curl_write_nothing(char *data, size_t size, size_t nmemb, void *ct
562
566
static size_t curl_write (char * data , size_t size , size_t nmemb , void * ctx )
563
567
{
564
568
php_curl * ch = (php_curl * ) ctx ;
565
- php_curl_write * t = ch -> handlers .write ;
569
+ php_curl_write * write_handler = ch -> handlers .write ;
566
570
size_t length = size * nmemb ;
567
571
568
572
#if PHP_CURL_DEBUG
569
573
fprintf (stderr , "curl_write() called\n" );
570
574
fprintf (stderr , "data = %s, size = %d, nmemb = %d, ctx = %x\n" , data , size , nmemb , ctx );
571
575
#endif
572
576
573
- switch (t -> method ) {
577
+ switch (write_handler -> method ) {
574
578
case PHP_CURL_STDOUT :
575
579
PHPWRITE (data , length );
576
580
break ;
577
581
case PHP_CURL_FILE :
578
- return fwrite (data , size , nmemb , t -> fp );
582
+ return fwrite (data , size , nmemb , write_handler -> fp );
579
583
case PHP_CURL_RETURN :
580
584
if (length > 0 ) {
581
- smart_str_appendl (& t -> buf , data , (int ) length );
585
+ smart_str_appendl (& write_handler -> buf , data , (int ) length );
582
586
}
583
587
break ;
584
588
case PHP_CURL_USER : {
585
589
zval argv [2 ];
586
590
zval retval ;
587
- int error ;
588
- zend_fcall_info fci ;
589
591
590
592
GC_ADDREF (& ch -> std );
591
593
ZVAL_OBJ (& argv [0 ], & ch -> std );
592
594
ZVAL_STRINGL (& argv [1 ], data , length );
593
595
594
- fci .size = sizeof (fci );
595
- fci .object = NULL ;
596
- ZVAL_COPY_VALUE (& fci .function_name , & t -> func_name );
597
- fci .retval = & retval ;
598
- fci .param_count = 2 ;
599
- fci .params = argv ;
600
- fci .named_params = NULL ;
601
-
602
- ch -> in_callback = 1 ;
603
- error = zend_call_function (& fci , & t -> fci_cache );
604
- ch -> in_callback = 0 ;
605
- if (error == FAILURE ) {
606
- php_error_docref (NULL , E_WARNING , "Could not call the CURLOPT_WRITEFUNCTION" );
607
- length = -1 ;
608
- } else if (!Z_ISUNDEF (retval )) {
596
+ ch -> in_callback = true;
597
+ zend_call_known_fcc (& write_handler -> fcc , & retval , /* param_count */ 2 , argv , /* named_params */ NULL );
598
+ ch -> in_callback = false;
599
+ if (!Z_ISUNDEF (retval )) {
609
600
_php_curl_verify_handlers (ch , /* reporterror */ true);
601
+ /* TODO Check callback returns an int or something castable to int */
610
602
length = zval_get_long (& retval );
611
603
}
612
604
@@ -837,10 +829,10 @@ static size_t curl_read(char *data, size_t size, size_t nmemb, void *ctx)
837
829
static size_t curl_write_header (char * data , size_t size , size_t nmemb , void * ctx )
838
830
{
839
831
php_curl * ch = (php_curl * ) ctx ;
840
- php_curl_write * t = ch -> handlers .write_header ;
832
+ php_curl_write * write_handler = ch -> handlers .write_header ;
841
833
size_t length = size * nmemb ;
842
834
843
- switch (t -> method ) {
835
+ switch (write_handler -> method ) {
844
836
case PHP_CURL_STDOUT :
845
837
/* Handle special case write when we're returning the entire transfer
846
838
*/
@@ -851,32 +843,20 @@ static size_t curl_write_header(char *data, size_t size, size_t nmemb, void *ctx
851
843
}
852
844
break ;
853
845
case PHP_CURL_FILE :
854
- return fwrite (data , size , nmemb , t -> fp );
846
+ return fwrite (data , size , nmemb , write_handler -> fp );
855
847
case PHP_CURL_USER : {
856
848
zval argv [2 ];
857
849
zval retval ;
858
- zend_result error ;
859
- zend_fcall_info fci ;
860
850
861
851
GC_ADDREF (& ch -> std );
862
852
ZVAL_OBJ (& argv [0 ], & ch -> std );
863
853
ZVAL_STRINGL (& argv [1 ], data , length );
864
854
865
- fci .size = sizeof (fci );
866
- ZVAL_COPY_VALUE (& fci .function_name , & t -> func_name );
867
- fci .object = NULL ;
868
- fci .retval = & retval ;
869
- fci .param_count = 2 ;
870
- fci .params = argv ;
871
- fci .named_params = NULL ;
872
-
873
- ch -> in_callback = 1 ;
874
- error = zend_call_function (& fci , & t -> fci_cache );
875
- ch -> in_callback = 0 ;
876
- if (error == FAILURE ) {
877
- php_error_docref (NULL , E_WARNING , "Could not call the CURLOPT_HEADERFUNCTION" );
878
- length = -1 ;
879
- } else if (!Z_ISUNDEF (retval )) {
855
+ ch -> in_callback = true;
856
+ zend_call_known_fcc (& write_handler -> fcc , & retval , /* param_count */ 2 , argv , /* named_params */ NULL );
857
+ ch -> in_callback = false;
858
+ if (!Z_ISUNDEF (retval )) {
859
+ // TODO: Check for valid int type for return value
880
860
_php_curl_verify_handlers (ch , /* reporterror */ true);
881
861
length = zval_get_long (& retval );
882
862
}
@@ -1169,15 +1149,17 @@ void _php_setup_easy_copy_handlers(php_curl *ch, php_curl *source)
1169
1149
ch -> handlers .read -> fp = source -> handlers .read -> fp ;
1170
1150
ch -> handlers .read -> res = source -> handlers .read -> res ;
1171
1151
1172
- if (!Z_ISUNDEF (source -> handlers .write -> func_name )) {
1173
- ZVAL_COPY (& ch -> handlers .write -> func_name , & source -> handlers .write -> func_name );
1174
- }
1175
1152
if (!Z_ISUNDEF (source -> handlers .read -> func_name )) {
1176
1153
ZVAL_COPY (& ch -> handlers .read -> func_name , & source -> handlers .read -> func_name );
1177
1154
}
1178
- if (!Z_ISUNDEF (source -> handlers .write_header -> func_name )) {
1179
- ZVAL_COPY (& ch -> handlers .write_header -> func_name , & source -> handlers .write_header -> func_name );
1155
+ if (ZEND_FCC_INITIALIZED (source -> handlers .write -> fcc )) {
1156
+ zend_fcc_dup (& source -> handlers .write -> fcc , & source -> handlers .write -> fcc );
1157
+ }
1158
+ if (ZEND_FCC_INITIALIZED (source -> handlers .write_header -> fcc )) {
1159
+ zend_fcc_dup (& source -> handlers .write_header -> fcc , & source -> handlers .write_header -> fcc );
1180
1160
}
1161
+ php_curl_copy_fcc_with_option (ch , CURLOPT_XFERINFODATA , & ch -> handlers .xferinfo , & source -> handlers .xferinfo );
1162
+ php_curl_copy_fcc_with_option (ch , CURLOPT_XFERINFODATA , & ch -> handlers .xferinfo , & source -> handlers .xferinfo );
1181
1163
1182
1164
curl_easy_setopt (ch -> cp , CURLOPT_ERRORBUFFER , ch -> err .str );
1183
1165
curl_easy_setopt (ch -> cp , CURLOPT_FILE , (void * ) ch );
@@ -2024,15 +2006,6 @@ static zend_result _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue
2024
2006
error = curl_easy_setopt (ch -> cp , option , lval );
2025
2007
break ;
2026
2008
2027
- case CURLOPT_HEADERFUNCTION :
2028
- if (!Z_ISUNDEF (ch -> handlers .write_header -> func_name )) {
2029
- zval_ptr_dtor (& ch -> handlers .write_header -> func_name );
2030
- ch -> handlers .write_header -> fci_cache = empty_fcall_info_cache ;
2031
- }
2032
- ZVAL_COPY (& ch -> handlers .write_header -> func_name , zvalue );
2033
- ch -> handlers .write_header -> method = PHP_CURL_USER ;
2034
- break ;
2035
-
2036
2009
case CURLOPT_POSTFIELDS :
2037
2010
if (Z_TYPE_P (zvalue ) == IS_ARRAY ) {
2038
2011
if (zend_hash_num_elements (HASH_OF (zvalue )) == 0 ) {
@@ -2053,6 +2026,28 @@ static zend_result _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue
2053
2026
}
2054
2027
break ;
2055
2028
2029
+ case CURLOPT_WRITEFUNCTION : {
2030
+ /* Check value is actually a callable and set it */
2031
+ const char option_name [] = "CURLOPT_WRITEFUNCTION" ;
2032
+ bool result = php_curl_set_callable_handler (& ch -> handlers .write -> fcc , zvalue , is_array_config , option_name );
2033
+ if (!result ) {
2034
+ return FAILURE ;
2035
+ }
2036
+ ch -> handlers .write -> method = PHP_CURL_USER ;
2037
+ break ;
2038
+ }
2039
+
2040
+ case CURLOPT_HEADERFUNCTION : {
2041
+ /* Check value is actually a callable and set it */
2042
+ const char option_name [] = "CURLOPT_HEADERFUNCTION" ;
2043
+ bool result = php_curl_set_callable_handler (& ch -> handlers .write_header -> fcc , zvalue , is_array_config , option_name );
2044
+ if (!result ) {
2045
+ return FAILURE ;
2046
+ }
2047
+ ch -> handlers .write_header -> method = PHP_CURL_USER ;
2048
+ break ;
2049
+ }
2050
+
2056
2051
case CURLOPT_PROGRESSFUNCTION : {
2057
2052
/* Check value is actually a callable and set it */
2058
2053
const char option_name [] = "CURLOPT_PROGRESSFUNCTION" ;
@@ -2120,15 +2115,6 @@ static zend_result _php_curl_setopt(php_curl *ch, zend_long option, zval *zvalue
2120
2115
}
2121
2116
break ;
2122
2117
2123
- case CURLOPT_WRITEFUNCTION :
2124
- if (!Z_ISUNDEF (ch -> handlers .write -> func_name )) {
2125
- zval_ptr_dtor (& ch -> handlers .write -> func_name );
2126
- ch -> handlers .write -> fci_cache = empty_fcall_info_cache ;
2127
- }
2128
- ZVAL_COPY (& ch -> handlers .write -> func_name , zvalue );
2129
- ch -> handlers .write -> method = PHP_CURL_USER ;
2130
- break ;
2131
-
2132
2118
/* Curl off_t options */
2133
2119
case CURLOPT_MAX_RECV_SPEED_LARGE :
2134
2120
case CURLOPT_MAX_SEND_SPEED_LARGE :
@@ -2730,9 +2716,13 @@ static void curl_free_obj(zend_object *object)
2730
2716
}
2731
2717
2732
2718
smart_str_free (& ch -> handlers .write -> buf );
2733
- zval_ptr_dtor (& ch -> handlers .write -> func_name );
2734
2719
zval_ptr_dtor (& ch -> handlers .read -> func_name );
2735
- zval_ptr_dtor (& ch -> handlers .write_header -> func_name );
2720
+ if (ZEND_FCC_INITIALIZED (ch -> handlers .write -> fcc )) {
2721
+ zend_fcc_dtor (& ch -> handlers .write -> fcc );
2722
+ }
2723
+ if (ZEND_FCC_INITIALIZED (ch -> handlers .write_header -> fcc )) {
2724
+ zend_fcc_dtor (& ch -> handlers .write_header -> fcc );
2725
+ }
2736
2726
zval_ptr_dtor (& ch -> handlers .std_err );
2737
2727
if (ch -> header .str ) {
2738
2728
zend_string_release_ex (ch -> header .str , 0 );
0 commit comments