@@ -111,51 +111,25 @@ 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 ));
121120 }
122121
123122 /* Don't store callback if headers have already been sent:
124123 * 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 );
124+ if (UNEXPECTED (SG (headers_sent ))) {
125+ zend_release_fcall_info_cache (& fcc );
126+ } else {
127+ zend_fcc_dup (& SG (send_header_fcc ), & fcc );
127128 }
128-
129129 RETURN_TRUE ;
130130}
131131/* }}} */
132132
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-
159133SAPI_API void sapi_handle_post (void * arg )
160134{
161135 if (SG (request_info ).post_entry && SG (request_info ).content_type_dup ) {
@@ -436,7 +410,6 @@ SAPI_API void sapi_activate(void)
436410 SG (sapi_headers ).http_status_line = NULL ;
437411 SG (sapi_headers ).mimetype = NULL ;
438412 SG (headers_sent ) = 0 ;
439- ZVAL_UNDEF (& SG (callback_func ));
440413 SG (read_post_bytes ) = 0 ;
441414 SG (request_info ).request_body = NULL ;
442415 SG (request_info ).current_user = NULL ;
@@ -446,6 +419,7 @@ SAPI_API void sapi_activate(void)
446419 SG (request_info ).proto_num = 1000 ; /* Default to HTTP 1.0 */
447420 SG (global_request_time ) = 0 ;
448421 SG (post_read ) = 0 ;
422+ SG (send_header_fcc ) = empty_fcall_info_cache ;
449423 /* It's possible to override this general case in the activate() callback, if necessary. */
450424 if (SG (request_info ).request_method && !strcmp (SG (request_info ).request_method , "HEAD" )) {
451425 SG (request_info ).headers_only = 1 ;
@@ -889,12 +863,12 @@ SAPI_API int sapi_send_headers(void)
889863 SG (sapi_headers ).send_default_content_type = 0 ;
890864 }
891865
892- if (Z_TYPE (SG (callback_func )) != IS_UNDEF ) {
893- zval cb ;
894- ZVAL_COPY_VALUE ( & cb , & SG ( callback_func ));
895- ZVAL_UNDEF ( & SG (callback_func )) ;
896- sapi_run_header_callback ( & cb );
897- zval_ptr_dtor ( & cb );
866+ if (ZEND_FCC_INITIALIZED (SG (send_header_fcc )) ) {
867+ zend_fcall_info_cache fcc = SG ( send_header_fcc ) ;
868+ /* Prevent triggering the callback multiple times */
869+ SG (send_header_fcc ) = empty_fcall_info_cache ;
870+ zend_call_known_fcc ( & fcc , NULL , 0 , NULL , NULL );
871+ zend_fcc_dtor ( & fcc );
898872 }
899873
900874 SG (headers_sent ) = 1 ;
0 commit comments