Annotation of embedaddon/php/sapi/apache2handler/php_functions.c, revision 1.1
1.1 ! misho 1: /*
! 2: +----------------------------------------------------------------------+
! 3: | PHP Version 5 |
! 4: +----------------------------------------------------------------------+
! 5: | Copyright (c) 1997-2012 The PHP Group |
! 6: +----------------------------------------------------------------------+
! 7: | This source file is subject to version 3.01 of the PHP license, |
! 8: | that is bundled with this package in the file LICENSE, and is |
! 9: | available through the world-wide-web at the following url: |
! 10: | http://www.php.net/license/3_01.txt |
! 11: | If you did not receive a copy of the PHP license and are unable to |
! 12: | obtain it through the world-wide-web, please send a note to |
! 13: | license@php.net so we can mail you a copy immediately. |
! 14: +----------------------------------------------------------------------+
! 15: | Author: Sascha Schumann <sascha@schumann.cx> |
! 16: +----------------------------------------------------------------------+
! 17: */
! 18:
! 19: /* $Id: php_functions.c 321634 2012-01-01 13:15:04Z felipe $ */
! 20:
! 21: #define ZEND_INCLUDE_FULL_WINDOWS_HEADERS
! 22:
! 23: #include "php.h"
! 24: #include "ext/standard/php_smart_str.h"
! 25: #include "ext/standard/info.h"
! 26: #include "ext/standard/head.h"
! 27: #include "php_ini.h"
! 28: #include "SAPI.h"
! 29:
! 30: #define CORE_PRIVATE
! 31: #include "apr_strings.h"
! 32: #include "apr_time.h"
! 33: #include "ap_config.h"
! 34: #include "util_filter.h"
! 35: #include "httpd.h"
! 36: #include "http_config.h"
! 37: #include "http_request.h"
! 38: #include "http_core.h"
! 39: #include "http_protocol.h"
! 40: #include "http_log.h"
! 41: #include "http_main.h"
! 42: #include "util_script.h"
! 43: #include "http_core.h"
! 44: #include "ap_mpm.h"
! 45: #if !defined(WIN32) && !defined(WINNT) && !defined(NETWARE)
! 46: #include "unixd.h"
! 47: #endif
! 48:
! 49: #include "php_apache.h"
! 50:
! 51: #ifdef ZTS
! 52: int php_apache2_info_id;
! 53: #else
! 54: php_apache2_info_struct php_apache2_info;
! 55: #endif
! 56:
! 57: #define SECTION(name) PUTS("<h2>" name "</h2>\n")
! 58:
! 59: static request_rec *php_apache_lookup_uri(char *filename TSRMLS_DC)
! 60: {
! 61: php_struct *ctx = SG(server_context);
! 62:
! 63: if (!filename || !ctx || !ctx->r) {
! 64: return NULL;
! 65: }
! 66:
! 67: return ap_sub_req_lookup_uri(filename, ctx->r, ctx->r->output_filters);
! 68: }
! 69:
! 70: /* {{{ proto bool virtual(string uri)
! 71: Perform an apache sub-request */
! 72: PHP_FUNCTION(virtual)
! 73: {
! 74: char *filename;
! 75: int filename_len;
! 76: request_rec *rr;
! 77:
! 78: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &filename, &filename_len) == FAILURE) {
! 79: return;
! 80: }
! 81:
! 82: if (!(rr = php_apache_lookup_uri(filename TSRMLS_CC))) {
! 83: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to include '%s' - URI lookup failed", filename);
! 84: RETURN_FALSE;
! 85: }
! 86:
! 87: if (rr->status != HTTP_OK) {
! 88: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to include '%s' - error finding URI", filename);
! 89: ap_destroy_sub_req(rr);
! 90: RETURN_FALSE;
! 91: }
! 92:
! 93: /* Flush everything. */
! 94: php_end_ob_buffers(1 TSRMLS_CC);
! 95: php_header(TSRMLS_C);
! 96:
! 97: /* Ensure that the ap_r* layer for the main request is flushed, to
! 98: * work around http://issues.apache.org/bugzilla/show_bug.cgi?id=17629 */
! 99: ap_rflush(rr->main);
! 100:
! 101: if (ap_run_sub_req(rr)) {
! 102: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to include '%s' - request execution failed", filename);
! 103: ap_destroy_sub_req(rr);
! 104: RETURN_FALSE;
! 105: }
! 106: ap_destroy_sub_req(rr);
! 107: RETURN_TRUE;
! 108: }
! 109: /* }}} */
! 110:
! 111: #define ADD_LONG(name) \
! 112: add_property_long(return_value, #name, rr->name)
! 113: #define ADD_TIME(name) \
! 114: add_property_long(return_value, #name, apr_time_sec(rr->name));
! 115: #define ADD_STRING(name) \
! 116: if (rr->name) add_property_string(return_value, #name, (char *) rr->name, 1)
! 117:
! 118: PHP_FUNCTION(apache_lookup_uri)
! 119: {
! 120: request_rec *rr;
! 121: char *filename;
! 122: int filename_len;
! 123:
! 124: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &filename, &filename_len) == FAILURE) {
! 125: return;
! 126: }
! 127:
! 128: if (!(rr = php_apache_lookup_uri(filename TSRMLS_CC))) {
! 129: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to include '%s' - URI lookup failed", filename);
! 130: RETURN_FALSE;
! 131: }
! 132:
! 133: if (rr->status == HTTP_OK) {
! 134: object_init(return_value);
! 135:
! 136: ADD_LONG(status);
! 137: ADD_STRING(the_request);
! 138: ADD_STRING(status_line);
! 139: ADD_STRING(method);
! 140: ADD_TIME(mtime);
! 141: ADD_LONG(clength);
! 142: #if MODULE_MAGIC_NUMBER < 20020506
! 143: ADD_STRING(boundary);
! 144: #endif
! 145: ADD_STRING(range);
! 146: ADD_LONG(chunked);
! 147: ADD_STRING(content_type);
! 148: ADD_STRING(handler);
! 149: ADD_LONG(no_cache);
! 150: ADD_LONG(no_local_copy);
! 151: ADD_STRING(unparsed_uri);
! 152: ADD_STRING(uri);
! 153: ADD_STRING(filename);
! 154: ADD_STRING(path_info);
! 155: ADD_STRING(args);
! 156: ADD_LONG(allowed);
! 157: ADD_LONG(sent_bodyct);
! 158: ADD_LONG(bytes_sent);
! 159: ADD_LONG(mtime);
! 160: ADD_TIME(request_time);
! 161:
! 162: ap_destroy_sub_req(rr);
! 163: return;
! 164: }
! 165:
! 166: php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to include '%s' - error finding URI", filename);
! 167: ap_destroy_sub_req(rr);
! 168: RETURN_FALSE;
! 169: }
! 170:
! 171: /* {{{ proto array getallheaders(void)
! 172: Fetch all HTTP request headers */
! 173: PHP_FUNCTION(apache_request_headers)
! 174: {
! 175: php_struct *ctx;
! 176: const apr_array_header_t *arr;
! 177: char *key, *val;
! 178:
! 179: if (zend_parse_parameters_none() == FAILURE) {
! 180: return;
! 181: }
! 182:
! 183: array_init(return_value);
! 184:
! 185: ctx = SG(server_context);
! 186: arr = apr_table_elts(ctx->r->headers_in);
! 187:
! 188: APR_ARRAY_FOREACH_OPEN(arr, key, val)
! 189: if (!val) val = "";
! 190: add_assoc_string(return_value, key, val, 1);
! 191: APR_ARRAY_FOREACH_CLOSE()
! 192: }
! 193: /* }}} */
! 194:
! 195: /* {{{ proto array apache_response_headers(void)
! 196: Fetch all HTTP response headers */
! 197: PHP_FUNCTION(apache_response_headers)
! 198: {
! 199: php_struct *ctx;
! 200: const apr_array_header_t *arr;
! 201: char *key, *val;
! 202:
! 203: if (zend_parse_parameters_none() == FAILURE) {
! 204: return;
! 205: }
! 206:
! 207: array_init(return_value);
! 208:
! 209: ctx = SG(server_context);
! 210: arr = apr_table_elts(ctx->r->headers_out);
! 211:
! 212: APR_ARRAY_FOREACH_OPEN(arr, key, val)
! 213: if (!val) val = "";
! 214: add_assoc_string(return_value, key, val, 1);
! 215: APR_ARRAY_FOREACH_CLOSE()
! 216: }
! 217: /* }}} */
! 218:
! 219: /* {{{ proto string apache_note(string note_name [, string note_value])
! 220: Get and set Apache request notes */
! 221: PHP_FUNCTION(apache_note)
! 222: {
! 223: php_struct *ctx;
! 224: char *note_name, *note_val = NULL;
! 225: int note_name_len, note_val_len;
! 226: char *old_note_val=NULL;
! 227:
! 228: if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s", ¬e_name, ¬e_name_len, ¬e_val, ¬e_val_len) == FAILURE) {
! 229: return;
! 230: }
! 231:
! 232: ctx = SG(server_context);
! 233:
! 234: old_note_val = (char *) apr_table_get(ctx->r->notes, note_name);
! 235:
! 236: if (note_val) {
! 237: apr_table_set(ctx->r->notes, note_name, note_val);
! 238: }
! 239:
! 240: if (old_note_val) {
! 241: RETURN_STRING(old_note_val, 1);
! 242: }
! 243:
! 244: RETURN_FALSE;
! 245: }
! 246: /* }}} */
! 247:
! 248:
! 249: /* {{{ proto bool apache_setenv(string variable, string value [, bool walk_to_top])
! 250: Set an Apache subprocess_env variable */
! 251: /*
! 252: * XXX this doesn't look right. shouldn't it be the parent ?*/
! 253: PHP_FUNCTION(apache_setenv)
! 254: {
! 255: php_struct *ctx;
! 256: char *variable=NULL, *string_val=NULL;
! 257: int variable_len, string_val_len;
! 258: zend_bool walk_to_top = 0;
! 259: int arg_count = ZEND_NUM_ARGS();
! 260: request_rec *r;
! 261:
! 262: if (zend_parse_parameters(arg_count TSRMLS_CC, "ss|b", &variable, &variable_len, &string_val, &string_val_len, &walk_to_top) == FAILURE) {
! 263: return;
! 264: }
! 265:
! 266: ctx = SG(server_context);
! 267:
! 268: r = ctx->r;
! 269: if (arg_count == 3) {
! 270: if (walk_to_top) {
! 271: while(r->prev) {
! 272: r = r->prev;
! 273: }
! 274: }
! 275: }
! 276:
! 277: apr_table_set(r->subprocess_env, variable, string_val);
! 278:
! 279: RETURN_TRUE;
! 280: }
! 281: /* }}} */
! 282:
! 283: /* {{{ proto bool apache_getenv(string variable [, bool walk_to_top])
! 284: Get an Apache subprocess_env variable */
! 285: /*
! 286: * XXX: shouldn't this be the parent not the 'prev'
! 287: */
! 288: PHP_FUNCTION(apache_getenv)
! 289: {
! 290: php_struct *ctx;
! 291: char *variable=NULL;
! 292: int variable_len;
! 293: zend_bool walk_to_top = 0;
! 294: int arg_count = ZEND_NUM_ARGS();
! 295: char *env_val=NULL;
! 296: request_rec *r;
! 297:
! 298: if (zend_parse_parameters(arg_count TSRMLS_CC, "s|b", &variable, &variable_len, &walk_to_top) == FAILURE) {
! 299: return;
! 300: }
! 301:
! 302: ctx = SG(server_context);
! 303:
! 304: r = ctx->r;
! 305: if (arg_count == 2) {
! 306: if (walk_to_top) {
! 307: while(r->prev) {
! 308: r = r->prev;
! 309: }
! 310: }
! 311: }
! 312:
! 313: env_val = (char*) apr_table_get(r->subprocess_env, variable);
! 314:
! 315: if (env_val != NULL) {
! 316: RETURN_STRING(env_val, 1);
! 317: }
! 318:
! 319: RETURN_FALSE;
! 320: }
! 321: /* }}} */
! 322:
! 323: static char *php_apache_get_version()
! 324: {
! 325: #if MODULE_MAGIC_NUMBER_MAJOR >= 20060905
! 326: return (char *) ap_get_server_banner();
! 327: #else
! 328: return (char *) ap_get_server_version();
! 329: #endif
! 330: }
! 331:
! 332: /* {{{ proto string apache_get_version(void)
! 333: Fetch Apache version */
! 334: PHP_FUNCTION(apache_get_version)
! 335: {
! 336: char *apv = php_apache_get_version();
! 337:
! 338: if (apv && *apv) {
! 339: RETURN_STRING(apv, 1);
! 340: } else {
! 341: RETURN_FALSE;
! 342: }
! 343: }
! 344: /* }}} */
! 345:
! 346: /* {{{ proto array apache_get_modules(void)
! 347: Get a list of loaded Apache modules */
! 348: PHP_FUNCTION(apache_get_modules)
! 349: {
! 350: int n;
! 351: char *p;
! 352:
! 353: array_init(return_value);
! 354:
! 355: for (n = 0; ap_loaded_modules[n]; ++n) {
! 356: char *s = (char *) ap_loaded_modules[n]->name;
! 357: if ((p = strchr(s, '.'))) {
! 358: add_next_index_stringl(return_value, s, (p - s), 1);
! 359: } else {
! 360: add_next_index_string(return_value, s, 1);
! 361: }
! 362: }
! 363: }
! 364: /* }}} */
! 365:
! 366: PHP_MINFO_FUNCTION(apache)
! 367: {
! 368: char *apv = php_apache_get_version();
! 369: smart_str tmp1 = {0};
! 370: char tmp[1024];
! 371: int n, max_requests;
! 372: char *p;
! 373: server_rec *serv = ((php_struct *) SG(server_context))->r->server;
! 374: #if !defined(WIN32) && !defined(WINNT) && !defined(NETWARE)
! 375: #if MODULE_MAGIC_NUMBER_MAJOR >= 20081201
! 376: AP_DECLARE_DATA extern unixd_config_rec ap_unixd_config;
! 377: #else
! 378: AP_DECLARE_DATA extern unixd_config_rec unixd_config;
! 379: #endif
! 380: #endif
! 381:
! 382: for (n = 0; ap_loaded_modules[n]; ++n) {
! 383: char *s = (char *) ap_loaded_modules[n]->name;
! 384: if ((p = strchr(s, '.'))) {
! 385: smart_str_appendl(&tmp1, s, (p - s));
! 386: } else {
! 387: smart_str_appends(&tmp1, s);
! 388: }
! 389: smart_str_appendc(&tmp1, ' ');
! 390: }
! 391: if ((tmp1.len - 1) >= 0) {
! 392: tmp1.c[tmp1.len - 1] = '\0';
! 393: }
! 394:
! 395: php_info_print_table_start();
! 396: if (apv && *apv) {
! 397: php_info_print_table_row(2, "Apache Version", apv);
! 398: }
! 399: snprintf(tmp, sizeof(tmp), "%d", MODULE_MAGIC_NUMBER);
! 400: php_info_print_table_row(2, "Apache API Version", tmp);
! 401:
! 402: if (serv->server_admin && *(serv->server_admin)) {
! 403: php_info_print_table_row(2, "Server Administrator", serv->server_admin);
! 404: }
! 405:
! 406: snprintf(tmp, sizeof(tmp), "%s:%u", serv->server_hostname, serv->port);
! 407: php_info_print_table_row(2, "Hostname:Port", tmp);
! 408:
! 409: #if !defined(WIN32) && !defined(WINNT) && !defined(NETWARE)
! 410: #if MODULE_MAGIC_NUMBER_MAJOR >= 20081201
! 411: snprintf(tmp, sizeof(tmp), "%s(%d)/%d", ap_unixd_config.user_name, ap_unixd_config.user_id, ap_unixd_config.group_id);
! 412: #else
! 413: snprintf(tmp, sizeof(tmp), "%s(%d)/%d", unixd_config.user_name, unixd_config.user_id, unixd_config.group_id);
! 414: #endif
! 415: php_info_print_table_row(2, "User/Group", tmp);
! 416: #endif
! 417:
! 418: ap_mpm_query(AP_MPMQ_MAX_REQUESTS_DAEMON, &max_requests);
! 419: snprintf(tmp, sizeof(tmp), "Per Child: %d - Keep Alive: %s - Max Per Connection: %d", max_requests, (serv->keep_alive ? "on":"off"), serv->keep_alive_max);
! 420: php_info_print_table_row(2, "Max Requests", tmp);
! 421:
! 422: apr_snprintf(tmp, sizeof tmp,
! 423: "Connection: %" APR_TIME_T_FMT " - Keep-Alive: %" APR_TIME_T_FMT,
! 424: apr_time_sec(serv->timeout), apr_time_sec(serv->keep_alive_timeout));
! 425: php_info_print_table_row(2, "Timeouts", tmp);
! 426:
! 427: php_info_print_table_row(2, "Virtual Server", (serv->is_virtual ? "Yes" : "No"));
! 428: php_info_print_table_row(2, "Server Root", ap_server_root);
! 429: php_info_print_table_row(2, "Loaded Modules", tmp1.c);
! 430:
! 431: smart_str_free(&tmp1);
! 432: php_info_print_table_end();
! 433:
! 434: DISPLAY_INI_ENTRIES();
! 435:
! 436: {
! 437: const apr_array_header_t *arr = apr_table_elts(((php_struct *) SG(server_context))->r->subprocess_env);
! 438: char *key, *val;
! 439:
! 440: SECTION("Apache Environment");
! 441: php_info_print_table_start();
! 442: php_info_print_table_header(2, "Variable", "Value");
! 443: APR_ARRAY_FOREACH_OPEN(arr, key, val)
! 444: if (!val) {
! 445: val = "";
! 446: }
! 447: php_info_print_table_row(2, key, val);
! 448: APR_ARRAY_FOREACH_CLOSE()
! 449:
! 450: php_info_print_table_end();
! 451:
! 452: SECTION("HTTP Headers Information");
! 453: php_info_print_table_start();
! 454: php_info_print_table_colspan_header(2, "HTTP Request Headers");
! 455: php_info_print_table_row(2, "HTTP Request", ((php_struct *) SG(server_context))->r->the_request);
! 456:
! 457: arr = apr_table_elts(((php_struct *) SG(server_context))->r->headers_in);
! 458: APR_ARRAY_FOREACH_OPEN(arr, key, val)
! 459: if (!val) {
! 460: val = "";
! 461: }
! 462: php_info_print_table_row(2, key, val);
! 463: APR_ARRAY_FOREACH_CLOSE()
! 464:
! 465: php_info_print_table_colspan_header(2, "HTTP Response Headers");
! 466: arr = apr_table_elts(((php_struct *) SG(server_context))->r->headers_out);
! 467: APR_ARRAY_FOREACH_OPEN(arr, key, val)
! 468: if (!val) {
! 469: val = "";
! 470: }
! 471: php_info_print_table_row(2, key, val);
! 472: APR_ARRAY_FOREACH_CLOSE()
! 473:
! 474: php_info_print_table_end();
! 475: }
! 476: }
! 477:
! 478: /* {{{ arginfo */
! 479: ZEND_BEGIN_ARG_INFO_EX(arginfo_apache2handler_lookup_uri, 0, 0, 1)
! 480: ZEND_ARG_INFO(0, filename)
! 481: ZEND_END_ARG_INFO()
! 482:
! 483: ZEND_BEGIN_ARG_INFO_EX(arginfo_apache2handler_virtual, 0, 0, 1)
! 484: ZEND_ARG_INFO(0, uri)
! 485: ZEND_END_ARG_INFO()
! 486:
! 487: ZEND_BEGIN_ARG_INFO(arginfo_apache2handler_response_headers, 0)
! 488: ZEND_END_ARG_INFO()
! 489:
! 490: ZEND_BEGIN_ARG_INFO(arginfo_apache2handler_getallheaders, 0)
! 491: ZEND_END_ARG_INFO()
! 492:
! 493: ZEND_BEGIN_ARG_INFO_EX(arginfo_apache2handler_note, 0, 0, 1)
! 494: ZEND_ARG_INFO(0, note_name)
! 495: ZEND_ARG_INFO(0, note_value)
! 496: ZEND_END_ARG_INFO()
! 497:
! 498: ZEND_BEGIN_ARG_INFO_EX(arginfo_apache2handler_setenv, 0, 0, 2)
! 499: ZEND_ARG_INFO(0, variable)
! 500: ZEND_ARG_INFO(0, value)
! 501: ZEND_ARG_INFO(0, walk_to_top)
! 502: ZEND_END_ARG_INFO()
! 503:
! 504: ZEND_BEGIN_ARG_INFO_EX(arginfo_apache2handler_getenv, 0, 0, 1)
! 505: ZEND_ARG_INFO(0, variable)
! 506: ZEND_ARG_INFO(0, walk_to_top)
! 507: ZEND_END_ARG_INFO()
! 508:
! 509: ZEND_BEGIN_ARG_INFO(arginfo_apache2handler_get_version, 0)
! 510: ZEND_END_ARG_INFO()
! 511:
! 512: ZEND_BEGIN_ARG_INFO(arginfo_apache2handler_get_modules, 0)
! 513: ZEND_END_ARG_INFO()
! 514: /* }}} */
! 515:
! 516: static const zend_function_entry apache_functions[] = {
! 517: PHP_FE(apache_lookup_uri, arginfo_apache2handler_lookup_uri)
! 518: PHP_FE(virtual, arginfo_apache2handler_virtual)
! 519: PHP_FE(apache_request_headers, arginfo_apache2handler_getallheaders)
! 520: PHP_FE(apache_response_headers, arginfo_apache2handler_response_headers)
! 521: PHP_FE(apache_setenv, arginfo_apache2handler_setenv)
! 522: PHP_FE(apache_getenv, arginfo_apache2handler_getenv)
! 523: PHP_FE(apache_note, arginfo_apache2handler_note)
! 524: PHP_FE(apache_get_version, arginfo_apache2handler_get_version)
! 525: PHP_FE(apache_get_modules, arginfo_apache2handler_get_modules)
! 526: PHP_FALIAS(getallheaders, apache_request_headers, arginfo_apache2handler_getallheaders)
! 527: {NULL, NULL, NULL}
! 528: };
! 529:
! 530: PHP_INI_BEGIN()
! 531: STD_PHP_INI_ENTRY("xbithack", "0", PHP_INI_ALL, OnUpdateLong, xbithack, php_apache2_info_struct, php_apache2_info)
! 532: STD_PHP_INI_ENTRY("engine", "1", PHP_INI_ALL, OnUpdateLong, engine, php_apache2_info_struct, php_apache2_info)
! 533: STD_PHP_INI_ENTRY("last_modified", "0", PHP_INI_ALL, OnUpdateLong, last_modified, php_apache2_info_struct, php_apache2_info)
! 534: PHP_INI_END()
! 535:
! 536: static PHP_MINIT_FUNCTION(apache)
! 537: {
! 538: #ifdef ZTS
! 539: ts_allocate_id(&php_apache2_info_id, sizeof(php_apache2_info_struct), (ts_allocate_ctor) NULL, NULL);
! 540: #endif
! 541: REGISTER_INI_ENTRIES();
! 542: return SUCCESS;
! 543: }
! 544:
! 545: static PHP_MSHUTDOWN_FUNCTION(apache)
! 546: {
! 547: UNREGISTER_INI_ENTRIES();
! 548: return SUCCESS;
! 549: }
! 550:
! 551: zend_module_entry php_apache_module = {
! 552: STANDARD_MODULE_HEADER,
! 553: "apache2handler",
! 554: apache_functions,
! 555: PHP_MINIT(apache),
! 556: PHP_MSHUTDOWN(apache),
! 557: NULL,
! 558: NULL,
! 559: PHP_MINFO(apache),
! 560: NULL,
! 561: STANDARD_MODULE_PROPERTIES
! 562: };
! 563:
! 564: /*
! 565: * Local variables:
! 566: * tab-width: 4
! 567: * c-basic-offset: 4
! 568: * End:
! 569: * vim600: sw=4 ts=4 fdm=marker
! 570: * vim<600: sw=4 ts=4
! 571: */
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>