scottmac                                 Thu, 03 Feb 2011 16:47:28 +0000

Revision: http://svn.php.net/viewvc?view=revision&revision=307977

Log:
Add header_register_callback(), allows a userland function
to be called as all the headers are being sent and after all
of the default headers have been merged.

headers_list(), header_remove() and header() can all be used
inside the callback.

<?php

header('Content-Type: text/plain');
header('X-Test: foo');

function foo() {
  foreach (headers_list() as $header) {
    if (strpos($header, 'X-Powered') !== false) {
      header_remove('X-Powered-By');
    }
    header_remove('X-Test');
  }
}

$result = header_register_callback('foo');
echo "a";

Changed paths:
    U   php/php-src/trunk/NEWS
    U   php/php-src/trunk/ext/standard/basic_functions.c
    U   php/php-src/trunk/ext/standard/basic_functions.h
    U   php/php-src/trunk/main/SAPI.c
    U   php/php-src/trunk/main/SAPI.h

Modified: php/php-src/trunk/NEWS
===================================================================
--- php/php-src/trunk/NEWS      2011-02-03 16:29:23 UTC (rev 307976)
+++ php/php-src/trunk/NEWS      2011-02-03 16:47:28 UTC (rev 307977)
@@ -42,6 +42,9 @@
   . Added support for object references in recursive serialize() calls.
     FR #36424. (Mike)
   . Added http_response_code() function. FR #52555. (Paul Dragoonis, Kalle)
+  . Added header_register_callback() which is invoked immediately
+    prior to the sending of headers and after default headers have
+    been added. (Scott)
   . Added DTrace support. (David Soria Parra)
   . Improved output layer, see README.NEW-OUTPUT-API for internals. (Mike)
   . Improved unserialize() performance.

Modified: php/php-src/trunk/ext/standard/basic_functions.c
===================================================================
--- php/php-src/trunk/ext/standard/basic_functions.c    2011-02-03 16:29:23 UTC 
(rev 307976)
+++ php/php-src/trunk/ext/standard/basic_functions.c    2011-02-03 16:47:28 UTC 
(rev 307977)
@@ -141,6 +141,13 @@
        ZEND_ARG_INFO(0, seconds)
 ZEND_END_ARG_INFO()
 /* }}} */
+
+/* {{{ main/sapi.c */
+ZEND_BEGIN_ARG_INFO(arginfo_header_register_callback, 0)
+       ZEND_ARG_INFO(0, callback)
+ZEND_END_ARG_INFO()
+/* }}} */
+
 /* {{{ main/output.c */
 ZEND_BEGIN_ARG_INFO_EX(arginfo_ob_start, 0, 0, 0)
        ZEND_ARG_INFO(0, user_function)
@@ -2940,6 +2947,7 @@
        PHP_FE(convert_cyr_string,                                              
                                                arginfo_convert_cyr_string)
        PHP_FE(get_current_user,                                                
                                                arginfo_get_current_user)
        PHP_FE(set_time_limit,                                                  
                                                arginfo_set_time_limit)
+       PHP_FE(header_register_callback,                                        
                                        arginfo_header_register_callback)
        PHP_FE(get_cfg_var,                                                     
                                                        arginfo_get_cfg_var)

        PHP_DEP_FALIAS(magic_quotes_runtime,    set_magic_quotes_runtime,       
        arginfo_set_magic_quotes_runtime)

Modified: php/php-src/trunk/ext/standard/basic_functions.h
===================================================================
--- php/php-src/trunk/ext/standard/basic_functions.h    2011-02-03 16:29:23 UTC 
(rev 307976)
+++ php/php-src/trunk/ext/standard/basic_functions.h    2011-02-03 16:47:28 UTC 
(rev 307977)
@@ -69,6 +69,8 @@
 PHP_FUNCTION(get_current_user);
 PHP_FUNCTION(set_time_limit);

+PHP_FUNCTION(header_register_callback);
+
 PHP_FUNCTION(get_cfg_var);
 PHP_FUNCTION(set_magic_quotes_runtime);
 PHP_FUNCTION(get_magic_quotes_runtime);

Modified: php/php-src/trunk/main/SAPI.c
===================================================================
--- php/php-src/trunk/main/SAPI.c       2011-02-03 16:29:23 UTC (rev 307976)
+++ php/php-src/trunk/main/SAPI.c       2011-02-03 16:47:28 UTC (rev 307977)
@@ -116,7 +116,59 @@
        efree(sapi_header->header);
 }

+/* {{{ proto bool header_register_callback(mixed callback)
+   call a header function */
+PHP_FUNCTION(header_register_callback)
+{
+       zval *callback_func;
+       char *callback_name;
+       if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", 
&callback_func) == FAILURE) {
+               return;
+       }
+
+       if (!zend_is_callable(callback_func, 0, &callback_name TSRMLS_CC)) {
+               efree(callback_name);
+               RETURN_FALSE;
+       }
+       efree(callback_name);

+       if (SG(callback_func)) {
+               zval_ptr_dtor(&SG(callback_func));
+               SG(fci_cache) = empty_fcall_info_cache;
+       }
+
+       Z_ADDREF_P(callback_func);
+
+       SG(callback_func) = callback_func;
+
+       RETURN_TRUE;
+}
+/* }}} */
+
+static void sapi_run_header_callback()
+{
+       int   error;
+       zend_fcall_info fci;
+       zval *retval_ptr = NULL;
+
+       fci.size = sizeof(fci);
+       fci.function_table = EG(function_table);
+       fci.object_ptr = NULL;
+       fci.function_name = SG(callback_func);
+       fci.retval_ptr_ptr = &retval_ptr;
+       fci.param_count = 0;
+       fci.params = NULL;
+       fci.no_separation = 0;
+       fci.symbol_table = NULL;
+
+       error = zend_call_function(&fci, &SG(fci_cache) TSRMLS_CC);
+       if (error == FAILURE) {
+               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not call the 
sapi_header_callback");
+       } else if (retval_ptr) {
+               zval_ptr_dtor(&retval_ptr);
+       }
+}
+
 SAPI_API void sapi_handle_post(void *arg TSRMLS_DC)
 {
        if (SG(request_info).post_entry && SG(request_info).content_type_dup) {
@@ -433,6 +485,9 @@
 SAPI_API void sapi_deactivate(TSRMLS_D)
 {
        zend_llist_destroy(&SG(sapi_headers).headers);
+       if (SG(callback_func)) {
+               zval_ptr_dtor(&SG(callback_func));
+       }
        if (SG(request_info).post_data) {
                efree(SG(request_info).post_data);
        }  else         if (SG(server_context)) {
@@ -574,7 +629,7 @@
        char *header_line;
        uint header_line_len;
        int http_response_code;
-
+
        if (SG(headers_sent) && !SG(request_info).no_headers) {
                char *output_start_filename = 
php_output_get_start_filename(TSRMLS_C);
                int output_start_lineno = php_output_get_start_lineno(TSRMLS_C);
@@ -774,6 +829,11 @@
                SG(sapi_headers).send_default_content_type = 0;
        }

+       if (SG(callback_func) && !SG(callback_run)) {
+               SG(callback_run) = 1;
+               sapi_run_header_callback();
+       }
+
        SG(headers_sent) = 1;

        if (sapi_module.send_headers) {

Modified: php/php-src/trunk/main/SAPI.h
===================================================================
--- php/php-src/trunk/main/SAPI.h       2011-02-03 16:29:23 UTC (rev 307976)
+++ php/php-src/trunk/main/SAPI.h       2011-02-03 16:47:28 UTC (rev 307977)
@@ -131,6 +131,9 @@
        zend_bool sapi_started;
        double global_request_time;
        HashTable known_post_content_types;
+       zval *callback_func;
+       zend_fcall_info_cache fci_cache;
+       zend_bool callback_run;
 } sapi_globals_struct;



-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to