summaryrefslogtreecommitdiff
path: root/main
diff options
context:
space:
mode:
authorScott MacVicar <scottmac@php.net>2011-02-03 16:47:28 +0000
committerScott MacVicar <scottmac@php.net>2011-02-03 16:47:28 +0000
commitca378eefa042647892a9e7bb8f9e6da907207e70 (patch)
tree8cdb083322eb2f7cca842f0296fbfce38bb27ee9 /main
parentee9af39c901068e2b253ca3c9c6ef9ca7b932957 (diff)
downloadphp-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.c62
-rw-r--r--main/SAPI.h3
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;