@@ -111,51 +111,26 @@ PHP_FUNCTION(header_register_callback)
111111 zend_fcall_info fci ;
112112 zend_fcall_info_cache fcc ;
113113
114- if (zend_parse_parameters (ZEND_NUM_ARGS (), "f " , & fci , & fcc ) == FAILURE ) {
114+ if (zend_parse_parameters (ZEND_NUM_ARGS (), "F " , & fci , & fcc ) == FAILURE ) {
115115 RETURN_THROWS ();
116116 }
117117
118- if (Z_TYPE (SG (callback_func )) != IS_UNDEF ) {
119- zval_ptr_dtor (& SG (callback_func ));
120- SG (fci_cache ) = empty_fcall_info_cache ;
118+ if (ZEND_FCC_INITIALIZED (SG (send_header_fcc )) ) {
119+ zend_fcc_dtor (& SG (send_header_fcc ));
120+ SG (send_header_fcc ) = empty_fcall_info_cache ;
121121 }
122122
123123 /* Don't store callback if headers have already been sent:
124124 * It won't get used and we won't have a chance to release it. */
125- if (! SG (headers_sent )) {
126- ZVAL_COPY ( & SG ( callback_func ), & fci . function_name );
125+ if (UNEXPECTED ( SG (headers_sent ) )) {
126+ zend_release_fcall_info_cache ( & fcc );
127127 }
128128
129+ zend_fcc_dup (& SG (send_header_fcc ), & fcc );
129130 RETURN_TRUE ;
130131}
131132/* }}} */
132133
133- static void sapi_run_header_callback (zval * callback )
134- {
135- int error ;
136- zend_fcall_info fci ;
137- char * callback_error = NULL ;
138- zval retval ;
139-
140- if (zend_fcall_info_init (callback , 0 , & fci , & SG (fci_cache ), NULL , & callback_error ) == SUCCESS ) {
141- fci .retval = & retval ;
142-
143- error = zend_call_function (& fci , & SG (fci_cache ));
144- if (error == FAILURE ) {
145- goto callback_failed ;
146- } else {
147- zval_ptr_dtor (& retval );
148- }
149- } else {
150- callback_failed :
151- php_error_docref (NULL , E_WARNING , "Could not call the sapi_header_callback" );
152- }
153-
154- if (callback_error ) {
155- efree (callback_error );
156- }
157- }
158-
159134SAPI_API void sapi_handle_post (void * arg )
160135{
161136 if (SG (request_info ).post_entry && SG (request_info ).content_type_dup ) {
@@ -436,7 +411,6 @@ SAPI_API void sapi_activate(void)
436411 SG (sapi_headers ).http_status_line = NULL ;
437412 SG (sapi_headers ).mimetype = NULL ;
438413 SG (headers_sent ) = 0 ;
439- ZVAL_UNDEF (& SG (callback_func ));
440414 SG (read_post_bytes ) = 0 ;
441415 SG (request_info ).request_body = NULL ;
442416 SG (request_info ).current_user = NULL ;
@@ -446,6 +420,7 @@ SAPI_API void sapi_activate(void)
446420 SG (request_info ).proto_num = 1000 ; /* Default to HTTP 1.0 */
447421 SG (global_request_time ) = 0 ;
448422 SG (post_read ) = 0 ;
423+ SG (send_header_fcc ) = empty_fcall_info_cache ;
449424 /* It's possible to override this general case in the activate() callback, if necessary. */
450425 if (SG (request_info ).request_method && !strcmp (SG (request_info ).request_method , "HEAD" )) {
451426 SG (request_info ).headers_only = 1 ;
@@ -890,12 +865,12 @@ SAPI_API int sapi_send_headers(void)
890865 SG (sapi_headers ).send_default_content_type = 0 ;
891866 }
892867
893- if (Z_TYPE (SG (callback_func )) != IS_UNDEF ) {
894- zval cb ;
895- ZVAL_COPY_VALUE ( & cb , & SG ( callback_func ));
896- ZVAL_UNDEF ( & SG (callback_func )) ;
897- sapi_run_header_callback ( & cb );
898- zval_ptr_dtor ( & cb );
868+ if (ZEND_FCC_INITIALIZED (SG (send_header_fcc )) ) {
869+ zend_fcall_info_cache fcc = SG ( send_header_fcc ) ;
870+ /* Prevent triggering the callback multiple times */
871+ SG (send_header_fcc ) = empty_fcall_info_cache ;
872+ zend_call_known_fcc ( & fcc , NULL , 0 , NULL , NULL );
873+ zend_fcc_dtor ( & fcc );
899874 }
900875
901876 SG (headers_sent ) = 1 ;
0 commit comments