diff options
| author | Scott MacVicar <scottmac@php.net> | 2011-02-03 16:47:28 +0000 |
|---|---|---|
| committer | Scott MacVicar <scottmac@php.net> | 2011-02-03 16:47:28 +0000 |
| commit | ca378eefa042647892a9e7bb8f9e6da907207e70 (patch) | |
| tree | 8cdb083322eb2f7cca842f0296fbfce38bb27ee9 /main | |
| parent | ee9af39c901068e2b253ca3c9c6ef9ca7b932957 (diff) | |
| download | php-git-ca378eefa042647892a9e7bb8f9e6da907207e70.tar.gz | |
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";
Diffstat (limited to 'main')
| -rw-r--r-- | main/SAPI.c | 62 | ||||
| -rw-r--r-- | main/SAPI.h | 3 |
2 files changed, 64 insertions, 1 deletions
diff --git a/main/SAPI.c b/main/SAPI.c index 2e95eea320..619f00ae19 100644 --- a/main/SAPI.c +++ b/main/SAPI.c @@ -116,6 +116,58 @@ SAPI_API void sapi_free_header(sapi_header_struct *sapi_header) 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) { @@ -433,6 +485,9 @@ static void sapi_send_headers_free(TSRMLS_D) 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 @@ SAPI_API int sapi_header_op(sapi_header_op_enum op, void *arg TSRMLS_DC) 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 @@ SAPI_API int sapi_send_headers(TSRMLS_D) 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) { diff --git a/main/SAPI.h b/main/SAPI.h index 3fea6b8814..3966b2d5aa 100644 --- a/main/SAPI.h +++ b/main/SAPI.h @@ -131,6 +131,9 @@ typedef struct _sapi_globals_struct { 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; |
