Back to index

php5  5.3.10
php_functions.c
Go to the documentation of this file.
00001 /*
00002    +----------------------------------------------------------------------+
00003    | PHP Version 5                                                        |
00004    +----------------------------------------------------------------------+
00005    | Copyright (c) 1997-2012 The PHP Group                                |
00006    +----------------------------------------------------------------------+
00007    | This source file is subject to version 3.01 of the PHP license,      |
00008    | that is bundled with this package in the file LICENSE, and is        |
00009    | available through the world-wide-web at the following url:           |
00010    | http://www.php.net/license/3_01.txt                                  |
00011    | If you did not receive a copy of the PHP license and are unable to   |
00012    | obtain it through the world-wide-web, please send a note to          |
00013    | license@php.net so we can mail you a copy immediately.               |
00014    +----------------------------------------------------------------------+
00015    | Author: Sascha Schumann <sascha@schumann.cx>                         |
00016    +----------------------------------------------------------------------+
00017  */
00018 
00019 /* $Id: php_functions.c 321634 2012-01-01 13:15:04Z felipe $ */
00020 
00021 
00022 #define ZEND_INCLUDE_FULL_WINDOWS_HEADERS
00023 
00024 #include "php.h"
00025 #include "ext/standard/php_smart_str.h"
00026 #include "ext/standard/info.h"
00027 #include "SAPI.h"
00028 
00029 #define CORE_PRIVATE
00030 #include "apr_strings.h"
00031 #include "apr_time.h"
00032 #include "ap_config.h"
00033 #include "util_filter.h"
00034 #include "httpd.h"
00035 #include "http_config.h"
00036 #include "http_request.h"
00037 #include "http_core.h"
00038 #include "http_protocol.h"
00039 #include "http_log.h"
00040 #include "http_main.h"
00041 #include "util_script.h"
00042 #include "http_core.h"
00043 
00044 #include "php_apache.h"
00045 
00046 static request_rec *php_apache_lookup_uri(char *filename TSRMLS_DC)
00047 {
00048        php_struct *ctx;
00049        
00050        if (!filename) {
00051               return NULL;
00052        }
00053        
00054        ctx = SG(server_context);
00055        return ap_sub_req_lookup_uri(filename, ctx->f->r, ctx->f->next);
00056 }
00057 
00058 /* {{{ proto bool virtual(string uri)
00059  Perform an apache sub-request */
00060 PHP_FUNCTION(virtual)
00061 {
00062        char *filename;
00063        int filename_len;
00064        request_rec *rr;
00065 
00066        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &filename, &filename_len) == FAILURE) {
00067               return;
00068        }
00069 
00070        if (!(rr = php_apache_lookup_uri(filename TSRMLS_CC))) {
00071               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to include '%s' - URI lookup failed", filename);
00072               RETURN_FALSE;
00073        }
00074        
00075        if (rr->status == HTTP_OK) {
00076               if (ap_run_sub_req(rr)) {
00077                      php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to include '%s' - request execution failed", filename);
00078                      ap_destroy_sub_req(rr);
00079                      RETURN_FALSE;
00080               }
00081               ap_destroy_sub_req(rr);
00082               RETURN_TRUE;
00083        }
00084        
00085        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to include '%s' - error finding URI", filename);
00086        ap_destroy_sub_req(rr);
00087        RETURN_FALSE;
00088 }
00089 /* }}} */
00090 
00091 #define ADD_LONG(name) \
00092               add_property_long(return_value, #name, rr->name)
00093 #define ADD_TIME(name) \
00094               add_property_long(return_value, #name, apr_time_sec(rr->name));
00095 #define ADD_STRING(name) \
00096               if (rr->name) add_property_string(return_value, #name, (char *) rr->name, 1)
00097 
00098 PHP_FUNCTION(apache_lookup_uri)
00099 {
00100        request_rec *rr;
00101        char *filename;
00102        int filename_len;
00103 
00104        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &filename, &filename_len) == FAILURE) {
00105               return;
00106        }
00107 
00108        if (!(rr = php_apache_lookup_uri(filename TSRMLS_CC))) {
00109               php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to include '%s' - URI lookup failed", filename);
00110               RETURN_FALSE;
00111        }
00112        
00113        if (rr->status == HTTP_OK) {
00114               object_init(return_value);
00115 
00116               ADD_LONG(status);
00117               ADD_STRING(the_request);
00118               ADD_STRING(status_line);
00119               ADD_STRING(method);
00120               ADD_TIME(mtime);
00121               ADD_LONG(clength);
00122 #if MODULE_MAGIC_NUMBER < 20020506
00123               ADD_STRING(boundary);
00124 #endif
00125               ADD_STRING(range);
00126               ADD_LONG(chunked);
00127               ADD_STRING(content_type);
00128               ADD_STRING(handler);
00129               ADD_LONG(no_cache);
00130               ADD_LONG(no_local_copy);
00131               ADD_STRING(unparsed_uri);
00132               ADD_STRING(uri);
00133               ADD_STRING(filename);
00134               ADD_STRING(path_info);
00135               ADD_STRING(args);
00136               ADD_LONG(allowed);
00137               ADD_LONG(sent_bodyct);
00138               ADD_LONG(bytes_sent);
00139               ADD_LONG(mtime);
00140               ADD_TIME(request_time);
00141 
00142               ap_destroy_sub_req(rr);
00143               return;
00144        }
00145        
00146        php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to include '%s' - error finding URI", filename);
00147        ap_destroy_sub_req(rr);
00148        RETURN_FALSE;
00149 }
00150 
00151 /* {{{ proto array getallheaders(void)
00152    Fetch all HTTP request headers */
00153 PHP_FUNCTION(apache_request_headers)
00154 {
00155        php_struct *ctx;
00156        const apr_array_header_t *arr;
00157        char *key, *val;
00158 
00159        array_init(return_value);
00160        
00161        ctx = SG(server_context);
00162        arr = apr_table_elts(ctx->f->r->headers_in);
00163 
00164        APR_ARRAY_FOREACH_OPEN(arr, key, val)
00165               if (!val) val = "";
00166               add_assoc_string(return_value, key, val, 1);
00167        APR_ARRAY_FOREACH_CLOSE()
00168 }
00169 /* }}} */
00170 
00171 /* {{{ proto array apache_response_headers(void)
00172    Fetch all HTTP response headers */
00173 PHP_FUNCTION(apache_response_headers)
00174 {
00175        php_struct *ctx;
00176        const apr_array_header_t *arr;
00177        char *key, *val;
00178 
00179        array_init(return_value);
00180        
00181        ctx = SG(server_context);
00182        arr = apr_table_elts(ctx->f->r->headers_out);
00183 
00184        APR_ARRAY_FOREACH_OPEN(arr, key, val)
00185               if (!val) val = "";
00186               add_assoc_string(return_value, key, val, 1);
00187        APR_ARRAY_FOREACH_CLOSE()
00188 }
00189 /* }}} */
00190 
00191 /* {{{ proto string apache_note(string note_name [, string note_value])
00192    Get and set Apache request notes */
00193 PHP_FUNCTION(apache_note)
00194 {
00195        php_struct *ctx;
00196        char *note_name, *note_val = NULL;
00197        int note_name_len, note_val_len;
00198        char *old_note_val=NULL;
00199 
00200        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s", &note_name, &note_name_len, &note_val, &note_val_len) == FAILURE) {
00201               return;
00202        }
00203 
00204        ctx = SG(server_context);
00205 
00206        old_note_val = (char *) apr_table_get(ctx->r->notes, note_name);
00207 
00208        if (note_val) {
00209               apr_table_set(ctx->r->notes, note_name, note_val);
00210        }
00211 
00212        if (old_note_val) {
00213               RETURN_STRING(old_note_val, 1);
00214        }
00215 
00216        RETURN_FALSE;
00217 }
00218 /* }}} */
00219 
00220 
00221 /* {{{ proto bool apache_setenv(string variable, string value [, bool walk_to_top])
00222    Set an Apache subprocess_env variable */
00223 PHP_FUNCTION(apache_setenv)
00224 {
00225        php_struct *ctx;
00226        char *variable=NULL, *string_val=NULL;
00227        int variable_len, string_val_len;
00228        zend_bool walk_to_top = 0;
00229        int arg_count = ZEND_NUM_ARGS();
00230 
00231        if (zend_parse_parameters(arg_count TSRMLS_CC, "ss|b", &variable, &variable_len, &string_val, &string_val_len, &walk_to_top) == FAILURE) {
00232               return;
00233        }
00234 
00235        ctx = SG(server_context);
00236 
00237        if (arg_count == 3 && walk_to_top) {
00238               while(ctx->f->r->prev) {
00239                      ctx->f->r = ctx->f->r->prev;
00240               }
00241        }
00242 
00243        apr_table_set(ctx->r->subprocess_env, variable, string_val);
00244 
00245        RETURN_TRUE;
00246 }
00247 /* }}} */
00248 
00249 /* {{{ proto bool apache_getenv(string variable [, bool walk_to_top])
00250    Get an Apache subprocess_env variable */
00251 PHP_FUNCTION(apache_getenv)
00252 {
00253        php_struct *ctx;
00254        char *variable=NULL;
00255        int variable_len;
00256        zend_bool walk_to_top = 0;
00257        int arg_count = ZEND_NUM_ARGS();
00258        char *env_val=NULL;
00259 
00260        if (zend_parse_parameters(arg_count TSRMLS_CC, "s|b", &variable, &variable_len, &walk_to_top) == FAILURE) {
00261               return;
00262        }
00263 
00264        ctx = SG(server_context);
00265 
00266        if (arg_count == 2 && walk_to_top) {
00267               while(ctx->f->r->prev) {
00268                      ctx->f->r = ctx->f->r->prev;
00269               }
00270        }
00271 
00272        env_val = (char*) apr_table_get(ctx->r->subprocess_env, variable);
00273        if (env_val != NULL) {
00274               RETURN_STRING(env_val, 1);
00275        }
00276 
00277        RETURN_FALSE;
00278 }
00279 /* }}} */
00280 
00281 static char *php_apache_get_version()
00282 {
00283 #if MODULE_MAGIC_NUMBER_MAJOR >= 20060905
00284        return (char *) ap_get_server_banner();
00285 #else
00286        return (char *) ap_get_server_version();
00287 #endif
00288 }
00289 
00290 /* {{{ proto string apache_get_version(void)
00291    Fetch Apache version */
00292 PHP_FUNCTION(apache_get_version)
00293 {
00294        char *apv = php_apache_get_version();
00295 
00296        if (apv && *apv) {
00297               RETURN_STRING(apv, 1);
00298        } else {
00299               RETURN_FALSE;
00300        }
00301 }
00302 /* }}} */
00303 
00304 /* {{{ proto array apache_get_modules(void)
00305    Get a list of loaded Apache modules */
00306 PHP_FUNCTION(apache_get_modules)
00307 {
00308        int n;
00309        char *p;
00310        
00311        array_init(return_value);
00312        
00313        for (n = 0; ap_loaded_modules[n]; ++n) {
00314               char *s = (char *) ap_loaded_modules[n]->name;
00315               if ((p = strchr(s, '.'))) {
00316                      add_next_index_stringl(return_value, s, (p - s), 1);
00317               } else {
00318                      add_next_index_string(return_value, s, 1);
00319               }
00320        }
00321 }
00322 /* }}} */
00323 
00324 PHP_MINFO_FUNCTION(apache)
00325 {
00326        char *apv = php_apache_get_version();
00327        smart_str tmp1 = {0};
00328        int n;
00329        char *p;
00330        
00331        for (n = 0; ap_loaded_modules[n]; ++n) {
00332               char *s = (char *) ap_loaded_modules[n]->name;
00333               if ((p = strchr(s, '.'))) {
00334                      smart_str_appendl(&tmp1, s, (p - s));
00335               } else {
00336                      smart_str_appends(&tmp1, s);
00337               }
00338               smart_str_appendc(&tmp1, ' ');
00339        }
00340        if ((tmp1.len - 1) >= 0) {
00341               tmp1.c[tmp1.len - 1] = '\0';
00342        }
00343             
00344        php_info_print_table_start();
00345        if (apv && *apv) {
00346               php_info_print_table_row(2, "Apache Version", apv);
00347        }
00348        php_info_print_table_row(2, "Loaded Modules", tmp1.c);
00349        smart_str_free(&tmp1);
00350        php_info_print_table_end();
00351 }
00352 
00353 /* {{{ arginfo */
00354 ZEND_BEGIN_ARG_INFO_EX(arginfo_apache2filter_lookup_uri, 0, 0, 1)
00355        ZEND_ARG_INFO(0, filename)
00356 ZEND_END_ARG_INFO()
00357 
00358 ZEND_BEGIN_ARG_INFO_EX(arginfo_apache2filter_virtual, 0, 0, 1)
00359        ZEND_ARG_INFO(0, uri)
00360 ZEND_END_ARG_INFO()
00361 
00362 ZEND_BEGIN_ARG_INFO(arginfo_apache2filter_getallheaders, 0)
00363 ZEND_END_ARG_INFO()
00364 
00365 ZEND_BEGIN_ARG_INFO(arginfo_apache2filter_response_headers, 0)
00366 ZEND_END_ARG_INFO()
00367 
00368 ZEND_BEGIN_ARG_INFO_EX(arginfo_apache2filter_note, 0, 0, 1)
00369        ZEND_ARG_INFO(0, note_name)
00370        ZEND_ARG_INFO(0, note_value)
00371 ZEND_END_ARG_INFO()
00372 
00373 ZEND_BEGIN_ARG_INFO_EX(arginfo_apache2filter_setenv, 0, 0, 2)
00374        ZEND_ARG_INFO(0, variable)
00375        ZEND_ARG_INFO(0, value)
00376        ZEND_ARG_INFO(0, walk_to_top)
00377 ZEND_END_ARG_INFO()
00378 
00379 ZEND_BEGIN_ARG_INFO_EX(arginfo_apache2filter_getenv, 0, 0, 1)
00380        ZEND_ARG_INFO(0, variable)
00381        ZEND_ARG_INFO(0, walk_to_top)
00382 ZEND_END_ARG_INFO()
00383 
00384 ZEND_BEGIN_ARG_INFO(arginfo_apache2filter_get_version, 0)
00385 ZEND_END_ARG_INFO()
00386 
00387 ZEND_BEGIN_ARG_INFO(arginfo_apache2filter_get_modules, 0)
00388 ZEND_END_ARG_INFO()
00389 /* }}} */
00390 
00391 static const zend_function_entry apache_functions[] = {
00392        PHP_FE(apache_lookup_uri,          arginfo_apache2filter_lookup_uri)
00393        PHP_FE(virtual,                           arginfo_apache2filter_virtual)
00394        PHP_FE(apache_request_headers,     arginfo_apache2filter_getallheaders)
00395        PHP_FE(apache_response_headers, arginfo_apache2filter_response_headers)
00396        PHP_FE(apache_setenv,                     arginfo_apache2filter_setenv)
00397        PHP_FE(apache_getenv,                     arginfo_apache2filter_getenv)
00398        PHP_FE(apache_note,                arginfo_apache2filter_note)
00399        PHP_FE(apache_get_version,         arginfo_apache2filter_get_version)
00400        PHP_FE(apache_get_modules,         arginfo_apache2filter_get_modules)
00401        PHP_FALIAS(getallheaders,          apache_request_headers, arginfo_apache2filter_getallheaders)
00402        {NULL, NULL, NULL}
00403 };
00404 
00405 zend_module_entry php_apache_module = {
00406        STANDARD_MODULE_HEADER,
00407        "apache2filter",
00408        apache_functions,
00409        NULL,
00410        NULL,
00411        NULL,
00412        NULL,
00413        PHP_MINFO(apache),
00414        NULL,
00415        STANDARD_MODULE_PROPERTIES
00416 };
00417 
00418 /*
00419  * Local variables:
00420  * tab-width: 4
00421  * c-basic-offset: 4
00422  * End:
00423  * vim600: sw=4 ts=4 fdm=marker
00424  * vim<600: sw=4 ts=4
00425  */