File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / php / sapi / apache_hooks / php_apache.c
Revision 1.1.1.3 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Mon Jul 22 01:32:13 2013 UTC (11 years ago) by misho
Branches: php, MAIN
CVS tags: v5_4_29p0, v5_4_20p0, v5_4_20, v5_4_17, HEAD
5.4.17

    1: /*
    2:    +----------------------------------------------------------------------+
    3:    | PHP Version 5                                                        |
    4:    +----------------------------------------------------------------------+
    5:    | Copyright (c) 1997-2013 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:    | Authors: Rasmus Lerdorf <rasmus@lerdorf.on.ca>                       |
   16:    |          Stig Sæther Bakken <ssb@php.net>                            |
   17:    |          David Sklar <sklar@student.net>                             |
   18:    +----------------------------------------------------------------------+
   19:  */
   20: /* $Id: php_apache.c,v 1.1.1.3 2013/07/22 01:32:13 misho Exp $ */
   21: 
   22: #include "php_apache_http.h"
   23: 
   24: #if defined(PHP_WIN32) || defined(NETWARE)
   25: #include "zend.h"
   26: #include "ap_compat.h"
   27: #else
   28: #include <build-defs.h>
   29: #endif
   30: 
   31: #ifdef ZTS
   32: int php_apache_info_id;
   33: #else
   34: php_apache_info_struct php_apache_info;
   35: #endif
   36: 
   37: #define SECTION(name)  PUTS("<H2 align=\"center\">" name "</H2>\n")
   38: 
   39: #undef offsetof
   40: #define offsetof(s_type,field) ((size_t)&(((s_type*)0)->field))
   41: 
   42: extern module *top_module;
   43: extern module **ap_loaded_modules;
   44: static int le_apachereq;
   45: static zend_class_entry *apacherequest_class_entry;
   46: 
   47: static void apache_table_to_zval(table *, zval *return_value);
   48: 
   49: PHP_FUNCTION(virtual);
   50: PHP_FUNCTION(apache_request_headers);
   51: PHP_FUNCTION(apache_response_headers);
   52: PHP_FUNCTION(apachelog);
   53: PHP_FUNCTION(apache_note);
   54: PHP_FUNCTION(apache_lookup_uri);
   55: PHP_FUNCTION(apache_child_terminate);
   56: PHP_FUNCTION(apache_setenv);
   57: PHP_FUNCTION(apache_get_version);
   58: PHP_FUNCTION(apache_get_modules);
   59: 
   60: PHP_MINFO_FUNCTION(apache);
   61: 
   62: ZEND_BEGIN_ARG_INFO_EX(arginfo_apachehooks_virtual, 0, 0, 1)
   63: 	ZEND_ARG_INFO(0, filename)
   64: ZEND_END_ARG_INFO()
   65: 
   66: ZEND_BEGIN_ARG_INFO_EX(arginfo_apachehooks_setenv, 0, 0, 2)
   67: 	ZEND_ARG_INFO(0, variable)
   68: 	ZEND_ARG_INFO(0, value)
   69: 	ZEND_ARG_INFO(0, walk_to_top)
   70: ZEND_END_ARG_INFO()
   71: 
   72: ZEND_BEGIN_ARG_INFO_EX(arginfo_apachehooks_lookup_uri, 0, 0, 1)
   73: 	ZEND_ARG_INFO(0, uri)
   74: ZEND_END_ARG_INFO()
   75: 
   76: ZEND_BEGIN_ARG_INFO(arginfo_apachehooks__void, 0)
   77: ZEND_END_ARG_INFO()
   78: 
   79: ZEND_BEGIN_ARG_INFO_EX(arginfo_apachehooks_note, 0, 0, 1)
   80: 	ZEND_ARG_INFO(0, note_name)
   81: 	ZEND_ARG_INFO(0, note_value)
   82: ZEND_END_ARG_INFO()
   83: 
   84: const zend_function_entry apache_functions[] = {
   85: 	PHP_FE(virtual,									arginfo_apachehooks_virtual)
   86: 	PHP_FE(apache_request_headers,					arginfo_apachehooks__void)
   87: 	PHP_FE(apache_note,								arginfo_apachehooks_note)
   88: 	PHP_FE(apache_lookup_uri,						arginfo_apachehooks_lookup_uri)
   89: 	PHP_FE(apache_child_terminate,					arginfo_apachehooks__void)
   90: 	PHP_FE(apache_setenv,							arginfo_apachehooks_setenv)
   91: 	PHP_FE(apache_response_headers,					arginfo_apachehooks__void)
   92: 	PHP_FE(apache_get_version,						arginfo_apachehooks__void)
   93: 	PHP_FE(apache_get_modules,						arginfo_apachehooks__void)
   94: 	PHP_FALIAS(getallheaders, apache_request_headers, arginfo_apachehooks__void)
   95: 	{NULL, NULL, NULL}
   96: };
   97: 
   98: /* {{{ php_apache ini entries
   99:  */
  100: PHP_INI_BEGIN()
  101: 	STD_PHP_INI_ENTRY("xbithack",			"0",				PHP_INI_ALL,		OnUpdateLong,		xbithack, php_apache_info_struct, php_apache_info)
  102: 	STD_PHP_INI_ENTRY("engine",				"1",				PHP_INI_ALL,		OnUpdateLong,		engine, php_apache_info_struct, php_apache_info)
  103: 	STD_PHP_INI_ENTRY("last_modified",		"0",				PHP_INI_ALL,		OnUpdateLong,		last_modified, php_apache_info_struct, php_apache_info)
  104: 	STD_PHP_INI_ENTRY("child_terminate",	"0",				PHP_INI_ALL,		OnUpdateLong,		terminate_child, php_apache_info_struct, php_apache_info)
  105: PHP_INI_END()
  106: /* }}} */
  107: 
  108: static void php_apache_globals_ctor(php_apache_info_struct *apache_globals TSRMLS_DC)
  109: {
  110: 	apache_globals->in_request = 0;
  111: }
  112: 
  113: 
  114: #define APREQ_GET_THIS(ZVAL)		if (NULL == (ZVAL = getThis())) { \
  115: 										php_error(E_WARNING, "%s(): underlying ApacheRequest object missing", \
  116: 											get_active_function_name(TSRMLS_C)); \
  117: 										RETURN_FALSE; \
  118: 									}
  119: #define APREQ_GET_REQUEST(ZVAL, R)	APREQ_GET_THIS(ZVAL); \
  120: 									R = get_apache_request(ZVAL TSRMLS_CC)
  121: 
  122: static void php_apache_request_free(zend_rsrc_list_entry *rsrc TSRMLS_DC)
  123: {
  124: 	zval *z = (zval *)rsrc->ptr;
  125: /*	fprintf(stderr, "%s() %p\n", __FUNCTION__, z); */
  126: 	zval_ptr_dtor(&z);
  127: }
  128: 
  129: static request_rec *get_apache_request(zval *z TSRMLS_DC)
  130: {
  131: 	request_rec *r;
  132: 	zval **addr;
  133: 
  134: 	if (NULL == z) {
  135: 		php_error(E_WARNING, "get_apache_request() invalid wrapper passed");
  136: 		return NULL;
  137: 	}
  138: 
  139: 	if (Z_TYPE_P(z) != IS_OBJECT) {
  140: 		php_error(E_WARNING, "%s(): wrapper is not an object", get_active_function_name(TSRMLS_C));
  141: 		return NULL;
  142: 	}
  143: 
  144: 	if (zend_hash_index_find(Z_OBJPROP_P(z), 0, (void **)&addr) == FAILURE) {
  145: 		php_error(E_WARNING, "%s(): underlying object missing", get_active_function_name(TSRMLS_C));
  146: 		return NULL;
  147: 	}
  148: 
  149: 	r = (request_rec *)Z_LVAL_PP(addr);
  150: 	if (!r) {
  151: 		php_error(E_WARNING, "%s(): request_rec invalid", get_active_function_name(TSRMLS_C));
  152: 		return NULL;
  153: 	}
  154: 
  155: 	return r;
  156: }
  157: 
  158: /* {{{ php_apache_request_new(request_rec *r)
  159:  * create a new zval-instance for ApacheRequest that wraps request_rec
  160:  */
  161: zval *php_apache_request_new(request_rec *r)
  162: {
  163: 	zval *req;
  164: 	zval *addr;
  165: 	
  166: 	TSRMLS_FETCH();
  167: 
  168: 	MAKE_STD_ZVAL(addr);
  169: 	Z_TYPE_P(addr) = IS_LONG;
  170: 	Z_LVAL_P(addr) = (int) r;
  171: 
  172: 	MAKE_STD_ZVAL(req);
  173: 	object_init_ex(req, apacherequest_class_entry);
  174: 	zend_hash_index_update(Z_OBJPROP_P(req), 0, &addr, sizeof(zval *), NULL);
  175: 
  176: 	return req;
  177: }
  178: /* }}} */
  179: 
  180: /* {{{ apache_request_read_string_slot()
  181:  */
  182: static void apache_request_read_string_slot(int offset, INTERNAL_FUNCTION_PARAMETERS)
  183: {
  184: 	zval *id;
  185: 	request_rec *r;
  186: 	char *s;
  187: 
  188: 	if (zend_parse_parameters_none() == FAILURE) {
  189: 		return;
  190: 	}
  191: 
  192: 	APREQ_GET_REQUEST(id, r);
  193: 
  194: 	s = *(char **)((char*)r + offset);
  195: 
  196: 	if (s) {
  197: 		RETURN_STRING(s, 1);
  198: 	}
  199: 
  200: 	RETURN_EMPTY_STRING();
  201: }
  202: /* }}} */
  203: 
  204: 
  205: /* {{{ apache_request_string_slot()
  206:  */
  207: static void apache_request_string_slot(int offset, INTERNAL_FUNCTION_PARAMETERS)
  208: {
  209: 	zval *id;
  210: 	request_rec *r;
  211: 	char *old_value, *new_value = NULL;
  212: 	int new_value_len;
  213: 	char **target;
  214: 
  215: 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &new_value, &new_value_len) == FAILURE) {
  216: 		return;
  217: 	}
  218: 
  219: 	APREQ_GET_REQUEST(id, r);
  220: 
  221: 	target = (char **)((char*)r + offset);
  222: 	old_value = *target;
  223: 
  224: 	if (new_value) {
  225: 		*target = ap_pstrdup(r->pool, new_value);
  226: 	}
  227: 
  228: 	if (old_value) {
  229: 		RETURN_STRING(old_value, 1);
  230: 	}
  231: 
  232: 	RETURN_EMPTY_STRING();
  233: }
  234: /* }}} */
  235: 
  236: /* {{{ apache_request_read_int_slot()
  237:  */
  238: static void apache_request_read_int_slot(int offset, INTERNAL_FUNCTION_PARAMETERS)
  239: {
  240: 	zval *id;
  241: 	request_rec *r;
  242: 	long l;
  243: 
  244: 	if (zend_parse_parameters_none() == FAILURE) {
  245: 		return;
  246: 	}
  247: 
  248: 	APREQ_GET_REQUEST(id, r);
  249: 
  250: 	l = *(long *)((char*)r + offset);
  251: 
  252: 	RETURN_LONG(l);
  253: }
  254: /* }}} */
  255: 
  256: /* {{{ apache_request_int_slot()
  257:  */
  258: static void apache_request_int_slot(int offset, INTERNAL_FUNCTION_PARAMETERS)
  259: {
  260: 	zval *id;
  261: 	request_rec *r;
  262: 	long old_value, new_value;
  263: 	long *target;
  264: 
  265: 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &new_value) == FAILURE) {
  266: 		return;
  267: 	}
  268: 
  269: 	APREQ_GET_REQUEST(id, r);
  270: 
  271: 	target = (long *)((char*)r + offset);
  272: 	old_value = *target;
  273: 
  274: 	switch (ZEND_NUM_ARGS()) {
  275: 		case 0:
  276: 			break;
  277: 		case 1:
  278: 			*target = new_value;
  279: 			break;
  280: 		default:
  281: 			WRONG_PARAM_COUNT;
  282: 			break;
  283: 	}
  284: 
  285: 	RETURN_LONG(old_value);
  286: }
  287: /* }}} */
  288: 
  289: 
  290: /* {{{ access string slots of request rec
  291:  */
  292: 
  293: /* {{{ proto string ApacheRequest::filename([string new_filename])
  294:  */
  295: PHP_FUNCTION(apache_request_filename)
  296: {
  297: 	apache_request_string_slot(offsetof(request_rec, filename), INTERNAL_FUNCTION_PARAM_PASSTHRU);
  298: }
  299: /* }}} */
  300: 
  301: /* {{{ proto string ApacheRequest::uri([string new_uri])
  302:  */
  303: PHP_FUNCTION(apache_request_uri)
  304: {
  305: 	apache_request_string_slot(offsetof(request_rec, uri), INTERNAL_FUNCTION_PARAM_PASSTHRU);
  306: }
  307: /* }}} */
  308: 
  309: /* {{{ proto string ApacheRequest::unparsed_uri([string new_unparsed_uri])
  310:  */
  311: PHP_FUNCTION(apache_request_unparsed_uri)
  312: {
  313: 	apache_request_string_slot(offsetof(request_rec, unparsed_uri), INTERNAL_FUNCTION_PARAM_PASSTHRU);
  314: }
  315: /* }}} */
  316: 
  317: /* {{{ proto string ApacheRequest::path_info([string new_path_info])
  318:  */
  319: PHP_FUNCTION(apache_request_path_info)
  320: {
  321: 	apache_request_string_slot(offsetof(request_rec, path_info), INTERNAL_FUNCTION_PARAM_PASSTHRU);
  322: }
  323: /* }}} */
  324: 
  325: /* {{{ proto string ApacheRequest::args([string new_args])
  326:  */
  327: PHP_FUNCTION(apache_request_args)
  328: {
  329: 	apache_request_string_slot(offsetof(request_rec, args), INTERNAL_FUNCTION_PARAM_PASSTHRU);
  330: }
  331: /* }}} */
  332: 
  333: /* {{{ proto string ApacheRequest::boundary()
  334:  */
  335: PHP_FUNCTION(apache_request_boundary)
  336: {
  337: 	apache_request_read_string_slot(offsetof(request_rec, boundary), INTERNAL_FUNCTION_PARAM_PASSTHRU);
  338: }
  339: /* }}} */
  340: 
  341: 
  342: /* {{{ proto string ApacheRequest::content_type([string new_type])
  343:  */
  344: PHP_FUNCTION(apache_request_content_type)
  345: {
  346: 	apache_request_string_slot(offsetof(request_rec, content_type), INTERNAL_FUNCTION_PARAM_PASSTHRU);
  347: }
  348: /* }}} */
  349: 
  350: /* {{{ proto string ApacheRequest::content_encoding([string new_encoding])
  351:  */
  352: PHP_FUNCTION(apache_request_content_encoding)
  353: {
  354: 	apache_request_string_slot(offsetof(request_rec, content_encoding), INTERNAL_FUNCTION_PARAM_PASSTHRU);
  355: }
  356: /* }}} */
  357: 
  358: /* {{{ proto string ApacheRequest::handler([string new_handler])
  359:  */
  360: PHP_FUNCTION(apache_request_handler)
  361: {
  362: 	apache_request_string_slot(offsetof(request_rec, handler), INTERNAL_FUNCTION_PARAM_PASSTHRU);
  363: }
  364: /* }}} */
  365: 
  366: /* {{{ proto string ApacheRequest::the_request()
  367:  */
  368: PHP_FUNCTION(apache_request_the_request)
  369: {
  370: 	apache_request_read_string_slot(offsetof(request_rec, the_request), INTERNAL_FUNCTION_PARAM_PASSTHRU);
  371: }
  372: /* }}} */
  373: 
  374: /* {{{ proto string ApacheRequest::protocol()
  375:  */
  376: PHP_FUNCTION(apache_request_protocol)
  377: {
  378: 	apache_request_read_string_slot(offsetof(request_rec, protocol), INTERNAL_FUNCTION_PARAM_PASSTHRU);
  379: }
  380: /* }}} */
  381: 
  382: /* {{{ proto string ApacheRequest::hostname()
  383:  */
  384: PHP_FUNCTION(apache_request_hostname)
  385: {
  386: 	apache_request_read_string_slot(offsetof(request_rec, hostname), INTERNAL_FUNCTION_PARAM_PASSTHRU);
  387: }
  388: /* }}} */
  389: 
  390: /* {{{ proto string ApacheRequest::status_line([string new_status_line])
  391:  */
  392: PHP_FUNCTION(apache_request_status_line)
  393: {
  394: 	apache_request_string_slot(offsetof(request_rec, status_line), INTERNAL_FUNCTION_PARAM_PASSTHRU);
  395: }
  396: /* }}} */
  397: 
  398: /* {{{ proto string ApacheRequest::method()
  399:  */
  400: PHP_FUNCTION(apache_request_method)
  401: {
  402: 	apache_request_read_string_slot(offsetof(request_rec, method), INTERNAL_FUNCTION_PARAM_PASSTHRU);
  403: }
  404: /* }}} */
  405: 
  406: /* }}} access string slots of request rec */
  407: 
  408: /* {{{ access int slots of request_rec
  409:  */
  410: 
  411: /* {{{ proto int ApacheRequest::proto_num()
  412:  */
  413: PHP_FUNCTION(apache_request_proto_num)
  414: {
  415: 	apache_request_read_int_slot(offsetof(request_rec, proto_num), INTERNAL_FUNCTION_PARAM_PASSTHRU);
  416: }
  417: /* }}} */
  418: 
  419: /* {{{ proto int ApacheRequest::assbackwards()
  420:  */
  421: PHP_FUNCTION(apache_request_assbackwards)
  422: {
  423: 	apache_request_read_int_slot(offsetof(request_rec, assbackwards), INTERNAL_FUNCTION_PARAM_PASSTHRU);
  424: }
  425: /* }}} */
  426: 
  427: 
  428: /* {{{ proto int ApacheRequest::proxyreq([int new_proxyreq])
  429:  */
  430: PHP_FUNCTION(apache_request_proxyreq)
  431: {
  432: 	apache_request_int_slot(offsetof(request_rec, proxyreq), INTERNAL_FUNCTION_PARAM_PASSTHRU);
  433: }
  434: /* }}} */
  435: 
  436: /* {{{ proto int ApacheRequest::chunked()
  437:  */
  438: PHP_FUNCTION(apache_request_chunked)
  439: {
  440: 	apache_request_read_int_slot(offsetof(request_rec, chunked), INTERNAL_FUNCTION_PARAM_PASSTHRU);
  441: }
  442: /* }}} */
  443: 
  444: 
  445: /* {{{ proto int ApacheRequest::header_only()
  446:  */
  447: PHP_FUNCTION(apache_request_header_only)
  448: {
  449: 	apache_request_read_int_slot(offsetof(request_rec, header_only), INTERNAL_FUNCTION_PARAM_PASSTHRU);
  450: }
  451: /* }}} */
  452: 
  453: /* {{{ proto int ApacheRequest::request_time()
  454:  */
  455: PHP_FUNCTION(apache_request_request_time)
  456: {
  457: 	apache_request_read_int_slot(offsetof(request_rec, request_time), INTERNAL_FUNCTION_PARAM_PASSTHRU);
  458: }
  459: /* }}} */
  460: 
  461: /* {{{ proto int ApacheRequest::status([int new_status])
  462:  */
  463: PHP_FUNCTION(apache_request_status)
  464: {
  465: 	apache_request_int_slot(offsetof(request_rec, status), INTERNAL_FUNCTION_PARAM_PASSTHRU);
  466: }
  467: /* }}} */
  468: 
  469: /* {{{ proto int ApacheRequest::method_number([int method_number])
  470:  */
  471: PHP_FUNCTION(apache_request_method_number)
  472: {
  473: 	apache_request_read_int_slot(offsetof(request_rec, method_number), INTERNAL_FUNCTION_PARAM_PASSTHRU);
  474: }
  475: /* }}} */
  476: 
  477: /* {{{ proto int ApacheRequest::allowed([int allowed])
  478:  */
  479: PHP_FUNCTION(apache_request_allowed)
  480: {
  481: 	apache_request_int_slot(offsetof(request_rec, allowed), INTERNAL_FUNCTION_PARAM_PASSTHRU);
  482: }
  483: /* }}} */
  484: 
  485: /* {{{ proto int ApacheRequest::bytes_sent()
  486:  */
  487: PHP_FUNCTION(apache_request_bytes_sent)
  488: {
  489: 	apache_request_read_int_slot(offsetof(request_rec, bytes_sent), INTERNAL_FUNCTION_PARAM_PASSTHRU);
  490: }
  491: /* }}} */
  492: 
  493: /* {{{ proto int ApacheRequest::mtime()
  494:  */
  495: PHP_FUNCTION(apache_request_mtime)
  496: {
  497: 	apache_request_read_int_slot(offsetof(request_rec, mtime), INTERNAL_FUNCTION_PARAM_PASSTHRU);
  498: }
  499: /* }}} */
  500: 
  501: /* {{{ proto int ApacheRequest::content_length([int new_content_length])
  502:  */
  503: PHP_FUNCTION(apache_request_content_length)
  504: {
  505: 	zval *id;
  506: 	long zlen;
  507: 	request_rec *r;
  508: 
  509: 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &zlen) == FAILURE) {
  510: 		return;
  511: 	}
  512: 
  513: 	if (ZEND_NUM_ARGS() == 0) {
  514: 		apache_request_read_int_slot(offsetof(request_rec, clength), INTERNAL_FUNCTION_PARAM_PASSTHRU);
  515: 	} else {
  516: 		APREQ_GET_REQUEST(id, r);
  517: 
  518: 		(void)ap_set_content_length(r, zlen);
  519: 		RETURN_TRUE;
  520: 	}
  521: }
  522: /* }}} */
  523: 
  524: /* {{{ proto int ApacheRequest::remaining()
  525:  */
  526: PHP_FUNCTION(apache_request_remaining)
  527: {
  528: 	apache_request_read_int_slot(offsetof(request_rec, remaining), INTERNAL_FUNCTION_PARAM_PASSTHRU);
  529: }
  530: /* }}} */
  531: 
  532: /* {{{ proto int ApacheRequest::no_cache()
  533:  */
  534: PHP_FUNCTION(apache_request_no_cache)
  535: {
  536: 	apache_request_int_slot(offsetof(request_rec, no_cache), INTERNAL_FUNCTION_PARAM_PASSTHRU);
  537: }
  538: /* }}} */
  539: 
  540: /* {{{ proto int ApacheRequest::no_local_copy()
  541:  */
  542: PHP_FUNCTION(apache_request_no_local_copy)
  543: {
  544: 	apache_request_int_slot(offsetof(request_rec, no_local_copy), INTERNAL_FUNCTION_PARAM_PASSTHRU);
  545: }
  546: /* }}} */
  547: 
  548: /* {{{ proto int ApacheRequest::read_body()
  549:  */
  550: PHP_FUNCTION(apache_request_read_body)
  551: {
  552: 	apache_request_int_slot(offsetof(request_rec, read_body), INTERNAL_FUNCTION_PARAM_PASSTHRU);
  553: }
  554: /* }}} */
  555: 
  556: 
  557: /* }}} access int slots of request_rec */
  558: 
  559: 
  560: /* {{{ proto array apache_request_headers_in()
  561:  * fetch all incoming request headers
  562:  */
  563: PHP_FUNCTION(apache_request_headers_in)
  564: {
  565: 	zval *id;
  566: 	request_rec *r;
  567: 	
  568: 	APREQ_GET_REQUEST(id, r);
  569: 
  570: 	apache_table_to_zval(r->headers_in, return_value);
  571: }
  572: /* }}} */
  573: 
  574: 
  575: /* {{{ add_header_to_table
  576: */
  577: static void add_header_to_table(table *t, INTERNAL_FUNCTION_PARAMETERS)
  578: {
  579: 	zval *first = NULL;
  580: 	zval *second = NULL;
  581: 	zval **entry, **value;
  582: 	char *string_key;
  583: 	uint string_key_len;
  584: 	ulong num_key;
  585: 	
  586: 	zend_bool replace = 0;
  587: 	HashPosition pos;
  588: 
  589: 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|zb", &first, &second, &replace) == FAILURE) {
  590: 		RETURN_FALSE;
  591: 	}
  592: 
  593: 	if (Z_TYPE_P(first) == IS_ARRAY) {
  594: 		switch(ZEND_NUM_ARGS()) {
  595: 			case 1:
  596: 			case 3:
  597: 				zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(first), &pos);
  598: 				while (zend_hash_get_current_data_ex(Z_ARRVAL_P(first), (void **)&entry, &pos) == SUCCESS) {
  599: 					switch(zend_hash_get_current_key_ex(Z_ARRVAL_P(first), &string_key, &string_key_len, &num_key, 0, &pos)) {
  600: 						case HASH_KEY_IS_STRING:
  601: 							if (zend_hash_find(Z_ARRVAL_P(first), string_key, string_key_len, (void **)&value) == FAILURE) {
  602: 								zend_hash_move_forward_ex(Z_ARRVAL_P(first), &pos);
  603: 								continue;
  604: 							}
  605: 							if (!value) {
  606: 								zend_hash_move_forward_ex(Z_ARRVAL_P(first), &pos);
  607: 								continue;
  608: 							}
  609: 
  610: 							convert_to_string_ex(value);
  611: 							if (replace) {
  612: 								ap_table_set(t, string_key, Z_STRVAL_PP(value));
  613: 							} else {
  614: 								ap_table_merge(t, string_key, Z_STRVAL_PP(value));
  615: 							}
  616: 							break;
  617: 						case HASH_KEY_IS_LONG:
  618: 						default:
  619: 							php_error(E_WARNING, "%s(): Can only add STRING keys to headers!", get_active_function_name(TSRMLS_C));
  620: 							break;
  621: 					}
  622: 
  623: 					zend_hash_move_forward_ex(Z_ARRVAL_P(first), &pos);
  624: 				}
  625: 				break;
  626: 			default:
  627: 				WRONG_PARAM_COUNT;
  628: 				break;
  629: 		}
  630: 	} else if (Z_TYPE_P(first) == IS_STRING) {
  631: 		switch(ZEND_NUM_ARGS()) {
  632: 			case 2:
  633: 			case 3:
  634: 				convert_to_string_ex(&second);
  635: 				if (replace) {
  636: 					ap_table_set(t, Z_STRVAL_P(first), Z_STRVAL_P(second));
  637: 				} else {
  638: 					ap_table_merge(t, Z_STRVAL_P(first), Z_STRVAL_P(second));
  639: 				}
  640: 				break;
  641: 			default:
  642: 				WRONG_PARAM_COUNT;
  643: 				break;
  644: 		}
  645: 	} else {
  646: 		RETURN_FALSE;
  647: 	}
  648: }
  649: 
  650: /* }}} */
  651: 
  652: 
  653: /* {{{ proto array apache_request_headers_out([{string name|array list} [, string value [, bool replace = false]]])
  654:  * fetch all outgoing request headers
  655:  */
  656: PHP_FUNCTION(apache_request_headers_out)
  657: {
  658: 	zval *id;
  659: 	request_rec *r;
  660: 	
  661: 	APREQ_GET_REQUEST(id, r);
  662: 
  663: 	if (ZEND_NUM_ARGS() > 0) {
  664: 		add_header_to_table(r->headers_out, INTERNAL_FUNCTION_PARAM_PASSTHRU);
  665: 	}
  666: 
  667: 	apache_table_to_zval(r->headers_out, return_value);
  668: }
  669: /* }}} */
  670: 
  671: 
  672: /* {{{ proto array apache_request_err_headers_out([{string name|array list} [, string value [, bool replace = false]]])
  673:  * fetch all headers that go out in case of an error or a subrequest
  674:  */
  675: PHP_FUNCTION(apache_request_err_headers_out)
  676: {
  677: 	zval *id;
  678: 	request_rec *r;
  679: 	
  680: 	APREQ_GET_REQUEST(id, r);
  681: 
  682: 	if (ZEND_NUM_ARGS() > 0) {
  683: 		add_header_to_table(r->err_headers_out, INTERNAL_FUNCTION_PARAM_PASSTHRU);
  684: 	}
  685: 
  686: 	apache_table_to_zval(r->err_headers_out, return_value);
  687: }
  688: /* }}} */
  689: 
  690: 
  691: /* {{{ proxy functions for the ap_* functions family
  692:  */
  693: 
  694: /* {{{ proto int apache_request_server_port()
  695:  */
  696: PHP_FUNCTION(apache_request_server_port)
  697: {
  698: 	zval *id;
  699: 	request_rec *r;
  700: 
  701: 	if (zend_parse_parameters_none() == FAILURE) {
  702: 		return;
  703: 	}
  704: 
  705: 	APREQ_GET_REQUEST(id, r);
  706: 
  707: 	RETURN_LONG(ap_get_server_port(r));
  708: }
  709: /* }}} */
  710: 
  711: /* {{{ proto int apache_request_remote_host([int type])
  712:  */
  713: PHP_FUNCTION(apache_request_remote_host)
  714: {
  715: 	zval *id;
  716: 	long type = 0;
  717: 	request_rec *r;
  718: 	char *res;
  719: 
  720: 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &type) == FAILURE) {
  721: 		return;
  722: 	}
  723: 
  724: 	if (!type) {
  725: 		type = REMOTE_NAME;
  726: 	}
  727: 
  728: 	APREQ_GET_REQUEST(id, r);
  729: 
  730: 	res = (char *)ap_get_remote_host(r->connection, r->per_dir_config, (int)type);
  731: 
  732: 	if (res) {
  733: 		RETURN_STRING(res, 1);
  734: 	}
  735: 
  736: 	RETURN_EMPTY_STRING();
  737: }
  738: /* }}} */
  739: 
  740: /* {{{ proto long apache_request_update_mtime([int dependency_mtime])
  741:  */
  742: PHP_FUNCTION(apache_request_update_mtime)
  743: {
  744: 	zval *id;
  745: 	request_rec *r;
  746: 	long mtime = 0;
  747: 
  748: 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &mtime) == FAILURE) {
  749: 		return;
  750: 	}
  751: 
  752: 	APREQ_GET_REQUEST(id, r);
  753: 
  754: 	RETURN_LONG(ap_update_mtime(r, (int) mtime));
  755: }
  756: /* }}} */
  757: 
  758: 
  759: /* {{{ proto void apache_request_set_etag()
  760:  */
  761: PHP_FUNCTION(apache_request_set_etag)
  762: {
  763: 	zval *id;
  764: 	request_rec *r;
  765: 
  766: 	if (zend_parse_parameters_none() == FAILURE) {
  767: 		return;
  768: 	}
  769: 
  770: 	APREQ_GET_REQUEST(id, r);
  771: 
  772: 	ap_set_etag(r);
  773: 	RETURN_TRUE;
  774: }
  775: /* }}} */
  776: 
  777: /* {{{ proto void apache_request_set_last_modified()
  778:  */
  779: PHP_FUNCTION(apache_request_set_last_modified)
  780: {
  781: 	zval *id;
  782: 	request_rec *r;
  783: 
  784: 	if (zend_parse_parameters_none() == FAILURE) {
  785: 		return;
  786: 	}
  787: 
  788: 	APREQ_GET_REQUEST(id, r);
  789: 
  790: 	ap_set_last_modified(r);
  791: 	RETURN_TRUE;
  792: }
  793: /* }}} */
  794: 
  795: /* {{{ proto long apache_request_meets_conditions()
  796:  */
  797: PHP_FUNCTION(apache_request_meets_conditions)
  798: {
  799: 	zval *id;
  800: 	request_rec *r;
  801: 
  802: 	if (zend_parse_parameters_none() == FAILURE) {
  803: 		return;
  804: 	}
  805: 
  806: 	APREQ_GET_REQUEST(id, r);
  807: 
  808: 	RETURN_LONG(ap_meets_conditions(r));
  809: }
  810: /* }}} */
  811: 
  812: /* {{{ proto long apache_request_discard_request_body()
  813:  */
  814: PHP_FUNCTION(apache_request_discard_request_body)
  815: {
  816: 	zval *id;
  817: 	request_rec *r;
  818: 
  819: 	if (zend_parse_parameters_none() == FAILURE) {
  820: 		return;
  821: 	}
  822: 
  823: 	APREQ_GET_REQUEST(id, r);
  824: 
  825: 	RETURN_LONG(ap_discard_request_body(r));
  826: }
  827: /* }}} */
  828: 
  829: /* {{{ proto long apache_request_satisfies()
  830:  */
  831: PHP_FUNCTION(apache_request_satisfies)
  832: {
  833: 	zval *id;
  834: 	request_rec *r;
  835: 
  836: 	if (zend_parse_parameters_none() == FAILURE) {
  837: 		return;
  838: 	}
  839: 
  840: 	APREQ_GET_REQUEST(id, r);
  841: 
  842: 	RETURN_LONG(ap_satisfies(r));
  843: }
  844: /* }}} */
  845: 
  846: 
  847: /* {{{ proto bool apache_request_is_initial_req()
  848:  */
  849: PHP_FUNCTION(apache_request_is_initial_req)
  850: {
  851: 	zval *id;
  852: 	request_rec *r;
  853: 
  854: 	if (zend_parse_parameters_none() == FAILURE) {
  855: 		return;
  856: 	}
  857: 
  858: 	APREQ_GET_REQUEST(id, r);
  859: 
  860: 	RETURN_BOOL(ap_is_initial_req(r));
  861: }
  862: /* }}} */
  863: 
  864: /* {{{ proto bool apache_request_some_auth_required()
  865:  */
  866: PHP_FUNCTION(apache_request_some_auth_required)
  867: {
  868: 	zval *id;
  869: 	request_rec *r;
  870: 
  871: 	if (zend_parse_parameters_none() == FAILURE) {
  872: 		return;
  873: 	}
  874: 
  875: 	APREQ_GET_REQUEST(id, r);
  876: 
  877: 	RETURN_BOOL(ap_some_auth_required(r));
  878: }
  879: /* }}} */
  880: 
  881: /* {{{ proto string apache_request_auth_type()
  882:  */
  883: PHP_FUNCTION(apache_request_auth_type)
  884: {
  885: 	zval *id;
  886: 	request_rec *r;
  887: 	char *t;
  888: 
  889: 	if (zend_parse_parameters_none() == FAILURE) {
  890: 		return;
  891: 	}
  892: 
  893: 	APREQ_GET_REQUEST(id, r);
  894: 
  895: 	t = (char *)ap_auth_type(r);
  896: 	if (!t) {
  897: 		RETURN_NULL();
  898: 	}
  899: 
  900: 	RETURN_STRING(t, 1);
  901: }
  902: /* }}} */
  903: 
  904: /* {{{ proto string apache_request_auth_name()
  905:  */
  906: PHP_FUNCTION(apache_request_auth_name)
  907: {
  908: 	zval *id;
  909: 	request_rec *r;
  910: 	char *t;
  911: 
  912: 	if (zend_parse_parameters_none() == FAILURE) {
  913: 		return;
  914: 	}
  915: 
  916: 	APREQ_GET_REQUEST(id, r);
  917: 
  918: 	t = (char *)ap_auth_name(r);
  919: 	if (!t) {
  920: 		RETURN_NULL();
  921: 	}
  922: 
  923: 	RETURN_STRING(t, 1);
  924: }
  925: /* }}} */
  926: 
  927: /* {{{ proto apache_request_basic_auth_pw()
  928:  */
  929: PHP_FUNCTION(apache_request_basic_auth_pw)
  930: {
  931: 	zval *id, *zpw;
  932: 	request_rec *r;
  933: 	const char *pw;
  934: 	long status;
  935: 
  936: 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &zpw) == FAILURE) {
  937: 	    return;
  938: 	}
  939: 
  940: 	if (!PZVAL_IS_REF(zpw)) {
  941: 	    zend_error(E_WARNING, "Parameter wasn't passed by reference");
  942: 	    RETURN_NULL();
  943: 	}
  944: 
  945: 	APREQ_GET_REQUEST(id, r);
  946: 
  947: 	pw = NULL;
  948: 	status = ap_get_basic_auth_pw(r, &pw);
  949: 	if (status == OK && pw) {
  950: 		ZVAL_STRING(zpw, (char *)pw, 1);
  951: 	} else {
  952: 		ZVAL_NULL(zpw);
  953: 	}
  954: 	RETURN_LONG(status);
  955: }
  956: /* }}} */
  957: 
  958: 
  959: /* http_protocol.h */
  960: 
  961: PHP_FUNCTION(apache_request_send_http_header)
  962: {
  963:     zval *id;
  964:     request_rec *r;
  965:     char *type = NULL;
  966:     int typelen;
  967: 
  968: 	if (zend_parse_parameters(ZEND_NUM_ARGS()  TSRMLS_CC, "|s", &type, &typelen) == FAILURE) {
  969:         return;
  970: 	}
  971: 
  972:     APREQ_GET_REQUEST(id, r);
  973:     if(type) {
  974:         r->content_type = pstrdup(r->pool, type);
  975:     }
  976:     ap_send_http_header(r);
  977:     SG(headers_sent) = 1;
  978:     AP(headers_sent) = 1;
  979:     RETURN_TRUE;
  980: }
  981: 
  982: PHP_FUNCTION(apache_request_basic_http_header)
  983: {
  984:     zval *id;
  985:     request_rec *r;
  986: 
  987: 	if (zend_parse_parameters_none() == FAILURE) {
  988: 		return;
  989: 	}
  990: 
  991:     APREQ_GET_REQUEST(id, r);
  992: 
  993:     ap_basic_http_header((request_rec *)SG(server_context));
  994:     SG(headers_sent) = 1;
  995:     AP(headers_sent) = 1;
  996:     RETURN_TRUE;
  997: }
  998: 
  999: PHP_FUNCTION(apache_request_send_http_trace)
 1000: {
 1001:     zval *id;
 1002:     request_rec *r;
 1003: 
 1004: 	if (zend_parse_parameters_none() == FAILURE) {
 1005: 		return;
 1006: 	}
 1007: 	
 1008:     APREQ_GET_REQUEST(id, r);
 1009: 
 1010:     ap_send_http_trace((request_rec *)SG(server_context));
 1011:     SG(headers_sent) = 1;
 1012:     AP(headers_sent) = 1;
 1013:     RETURN_TRUE;
 1014: }
 1015: 
 1016: PHP_FUNCTION(apache_request_send_http_options)
 1017: {
 1018:     zval *id;
 1019:     request_rec *r;
 1020: 
 1021: 	if (zend_parse_parameters_none() == FAILURE) {
 1022: 		return;
 1023: 	}
 1024: 
 1025:     APREQ_GET_REQUEST(id, r);
 1026: 
 1027:     ap_send_http_options((request_rec *)SG(server_context));
 1028:     SG(headers_sent) = 1;
 1029:     AP(headers_sent) = 1;
 1030:     RETURN_TRUE;
 1031: }
 1032: 
 1033: PHP_FUNCTION(apache_request_send_error_response)
 1034: {
 1035:     zval *id;
 1036:     request_rec *r;
 1037: 	long rec = 0;
 1038: 
 1039: 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &rec) == FAILURE) {
 1040: 		return;
 1041: 	}
 1042: 
 1043:     APREQ_GET_REQUEST(id, r);
 1044: 	ap_send_error_response(r, (int) rec);
 1045:     RETURN_TRUE;
 1046: }
 1047: 
 1048: PHP_FUNCTION(apache_request_set_content_length)
 1049: {
 1050: 	long length;
 1051:     zval *id;
 1052:     request_rec *r;
 1053: 
 1054: 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &length) == FAILURE) {
 1055: 		return;
 1056: 	}
 1057: 
 1058:     APREQ_GET_REQUEST(id, r);
 1059: 
 1060:     ap_set_content_length(r, length);
 1061:     RETURN_TRUE;
 1062: }
 1063: 
 1064: PHP_FUNCTION(apache_request_set_keepalive)
 1065: {
 1066:     zval *id;
 1067:     request_rec *r;
 1068: 
 1069: 	if (zend_parse_parameters_none() == FAILURE) {
 1070: 		return;
 1071: 	}
 1072: 	
 1073:     APREQ_GET_REQUEST(id, r);
 1074:     ap_set_keepalive(r);
 1075:     RETURN_TRUE;
 1076: }
 1077: 
 1078: /* This stuff should use streams or however this is implemented now
 1079: 
 1080: PHP_FUNCTION(apache_request_send_fd) 
 1081: {
 1082: }
 1083: 
 1084: PHP_FUNCTION(apache_request_send_fd_length)
 1085: {
 1086: }
 1087: */
 1088: 
 1089: /* These are for overriding default output behaviour */
 1090: PHP_FUNCTION(apache_request_rputs)
 1091: {
 1092:     char *buffer;
 1093: 	int buffer_len;
 1094:     zval *id;
 1095:     request_rec *r;
 1096: 
 1097: 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &buffer, &buffer_len) == FAILURE) {
 1098: 		return;
 1099: 	}
 1100: 
 1101:     APREQ_GET_REQUEST(id, r);
 1102:     ap_rwrite(buffer, buffer_len, (request_rec*)SG(server_context));
 1103: }
 1104: 
 1105: /* This stuff would be useful for custom POST handlers, 
 1106:    which should be supported.  Probably by not using
 1107:    sapi_activate at all inside a phpResponseHandler
 1108:    and instead using a builtin composed of the below
 1109:    calls as a apache_read_request_body() and allow
 1110:    people to custom craft their own.
 1111:     
 1112: PHP_FUNCTION(apache_request_setup_client_block)
 1113: {
 1114: }
 1115: 
 1116: PHP_FUNCTION(apache_request_should_client_block)
 1117: {
 1118: }
 1119: 
 1120: PHP_FUNCTION(apache_request_get_client_block)
 1121: {
 1122: }
 1123: 
 1124: PHP_FUNCTION(apache_request_discard_request_body)
 1125: {
 1126: }
 1127: */
 1128: 
 1129: /* http_log.h */
 1130: 
 1131: /* {{{ proto boolean apache_request_log_error(string message, [long facility])
 1132:  */
 1133: PHP_FUNCTION(apache_request_log_error)
 1134: {
 1135:     zval *id;
 1136: 	char *z_errstr;
 1137: 	int z_errstr_len;
 1138:     long facility = APLOG_ERR;
 1139:     request_rec *r;
 1140: 
 1141: 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &z_errstr, &z_errstr_len, &facility) == FAILURE) {
 1142: 		return;
 1143: 	}
 1144: 
 1145:     APREQ_GET_REQUEST(id, r);
 1146: 	ap_log_error(APLOG_MARK, (int) facility, r->server, "%s", z_errstr);
 1147:     RETURN_TRUE;
 1148: }
 1149: /* }}} */
 1150: /* http_main.h */
 1151: 
 1152: /* {{{ proto object apache_request_sub_req_lookup_uri(string uri)
 1153:     Returns sub-request for the specified uri.  You would
 1154:     need to run it yourself with run()
 1155: */
 1156: PHP_FUNCTION(apache_request_sub_req_lookup_uri)
 1157: {
 1158:     zval *id;
 1159: 	char *file;
 1160: 	int file_len;
 1161:     request_rec *r, *sub_r;
 1162: 
 1163: 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &file, &file_len) == FAILURE) {
 1164: 		return;
 1165: 	}
 1166: 
 1167:     APREQ_GET_REQUEST(id, r);
 1168:     sub_r = ap_sub_req_lookup_uri(file, r);
 1169: 
 1170:     if (!sub_r) {
 1171:         RETURN_FALSE;
 1172:     }
 1173:     return_value = php_apache_request_new(sub_r);
 1174: }
 1175: /* }}} */
 1176: 
 1177: /* {{{ proto object apache_request_sub_req_lookup_file(string file)
 1178:     Returns sub-request for the specified file.  You would
 1179:     need to run it yourself with run().
 1180: */
 1181: PHP_FUNCTION(apache_request_sub_req_lookup_file)
 1182: {
 1183:     zval *id;
 1184: 	char *file;
 1185: 	int file_len;
 1186:     request_rec *r, *sub_r;
 1187: 
 1188: 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &file, &file_len) == FAILURE) {
 1189: 		return;
 1190: 	}
 1191: 
 1192:     APREQ_GET_REQUEST(id, r);
 1193: 
 1194:     sub_r = ap_sub_req_lookup_file(file, r);
 1195: 
 1196:     if (!sub_r) {
 1197:         RETURN_FALSE;
 1198:     }
 1199:     return_value = php_apache_request_new(sub_r);
 1200: }
 1201: /* }}} */
 1202: 
 1203: /* {{{ proto object apache_request_sub_req_method_uri(string method, string uri)
 1204:     Returns sub-request for the specified file.  You would
 1205:     need to run it yourself with run().
 1206: */
 1207: PHP_FUNCTION(apache_request_sub_req_method_uri)
 1208: {
 1209:     zval *id;
 1210: 	char *file, *method;
 1211: 	int file_len, method_len;
 1212:     request_rec *r, *sub_r;
 1213: 
 1214: 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &method, &method_len, &file, &file_len) == FAILURE) {
 1215: 		return;
 1216: 	}
 1217: 
 1218:     APREQ_GET_REQUEST(id, r);
 1219: 
 1220:     sub_r = ap_sub_req_method_uri(method, file, r);
 1221: 
 1222:     if (!sub_r) {
 1223:         RETURN_FALSE;
 1224:     }
 1225:     return_value = php_apache_request_new(sub_r);
 1226: }
 1227: /* }}} */
 1228: 
 1229: /* {{{ proto long apache_request_run()
 1230:     This is a wrapper for ap_sub_run_req and ap_destory_sub_req.  It takes 
 1231:     sub_request, runs it, destroys it, and returns it's status.
 1232: */
 1233: PHP_FUNCTION(apache_request_run)
 1234: {
 1235:     zval *id;
 1236:     request_rec *r;
 1237:     int status;
 1238: 
 1239:     if (zend_parse_parameters_none() == FAILURE) {
 1240:     	return;
 1241: 	}
 1242: 
 1243:     APREQ_GET_REQUEST(id, r);
 1244:     if (!r || ap_is_initial_req(r)) {
 1245:         RETURN_FALSE;
 1246: 	}
 1247:     status = ap_run_sub_req(r);
 1248:     ap_destroy_sub_req(r);
 1249:     RETURN_LONG(status);
 1250: }
 1251: /* }}} */
 1252: 
 1253: PHP_FUNCTION(apache_request_internal_redirect)
 1254: {
 1255:     zval *id;
 1256: 	char *new_uri;
 1257: 	int new_uri_len;
 1258:     request_rec *r;
 1259: 
 1260: 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &new_uri, &new_uri_len) == FAILURE) {
 1261: 		return;
 1262: 	}
 1263: 
 1264:     APREQ_GET_REQUEST(id, r);
 1265: 
 1266:     ap_internal_redirect(new_uri, r);
 1267: }
 1268: 
 1269: PHP_FUNCTION(apache_request_send_header_field)
 1270: {
 1271: 	char *fieldname, *fieldval;
 1272: 	int fieldname_len, fieldval_len;
 1273:     zval *id;
 1274:     request_rec *r;
 1275: 
 1276: 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &fieldname, &fieldname_len, &fieldval, &fieldval_len) == FAILURE) {
 1277: 		return;
 1278: 	}
 1279: 
 1280:     APREQ_GET_REQUEST(id, r);
 1281: 
 1282:     ap_send_header_field(r, fieldname, fieldval);
 1283:     SG(headers_sent) = 1;
 1284:     AP(headers_sent) = 1;
 1285: }
 1286: 
 1287: 
 1288: 
 1289: /* }}} */
 1290: 
 1291: /* {{{ php_apache_request_class_functions
 1292:  */
 1293: const static zend_function_entry php_apache_request_class_functions[] = {
 1294: 	/* string slots */
 1295: 	PHP_FALIAS(args,						apache_request_args,				NULL)
 1296: 	PHP_FALIAS(boundary,					apache_request_boundary,			NULL)
 1297: 	PHP_FALIAS(content_encoding,			apache_request_content_encoding,	NULL)
 1298: 	PHP_FALIAS(content_type,				apache_request_content_type,		NULL)
 1299: 	PHP_FALIAS(filename,					apache_request_filename,			NULL)
 1300: 	PHP_FALIAS(handler,						apache_request_handler,				NULL)
 1301: 	PHP_FALIAS(hostname,					apache_request_hostname,			NULL)
 1302: 	PHP_FALIAS(method,						apache_request_method,				NULL)
 1303: 	PHP_FALIAS(path_info,					apache_request_path_info,			NULL)
 1304: 	PHP_FALIAS(protocol,					apache_request_protocol,			NULL)
 1305: 	PHP_FALIAS(status_line,					apache_request_status_line,			NULL)
 1306: 	PHP_FALIAS(the_request,					apache_request_the_request,			NULL)
 1307: 	PHP_FALIAS(unparsed_uri,				apache_request_unparsed_uri,		NULL)
 1308: 	PHP_FALIAS(uri,							apache_request_uri,					NULL)
 1309: 
 1310: 	/* int slots */
 1311: 	PHP_FALIAS(allowed,						apache_request_allowed,				NULL)
 1312: 	PHP_FALIAS(bytes_sent,					apache_request_bytes_sent,			NULL)
 1313: 	PHP_FALIAS(chunked,						apache_request_chunked,				NULL)
 1314: 	PHP_FALIAS(content_length,				apache_request_content_length,		NULL)
 1315: 	PHP_FALIAS(header_only,					apache_request_header_only,			NULL)
 1316: 	PHP_FALIAS(method_number,				apache_request_method_number,		NULL)
 1317: 	PHP_FALIAS(mtime,						apache_request_mtime,				NULL)
 1318: 	PHP_FALIAS(no_cache,					apache_request_no_cache,			NULL)
 1319: 	PHP_FALIAS(no_local_copy,				apache_request_no_local_copy,		NULL)
 1320: 	PHP_FALIAS(proto_num,					apache_request_proto_num,			NULL)
 1321: 	PHP_FALIAS(proxyreq,					apache_request_proxyreq,			NULL)
 1322: 	PHP_FALIAS(read_body,					apache_request_read_body,			NULL)
 1323: 	PHP_FALIAS(remaining,					apache_request_remaining,			NULL)
 1324: 	PHP_FALIAS(request_time,				apache_request_request_time,		NULL)
 1325: 	PHP_FALIAS(status,						apache_request_status,				NULL)
 1326: 
 1327: 	/* tables & arrays */
 1328: 	PHP_FALIAS(headers_in,					apache_request_headers_in,			NULL)
 1329: 	PHP_FALIAS(headers_out,					apache_request_headers_out,			NULL)
 1330: 	PHP_FALIAS(err_headers_out,				apache_request_err_headers_out,			NULL)
 1331: 
 1332: 
 1333: 	/* proxy functions for the ap_* functions family */
 1334: #undef auth_name
 1335: #undef auth_type
 1336: #undef discard_request_body
 1337: #undef is_initial_req
 1338: #undef meets_conditions
 1339: #undef satisfies
 1340: #undef set_etag
 1341: #undef set_last_modified
 1342: #undef some_auth_required
 1343: #undef update_mtime
 1344: #undef send_http_header
 1345: #undef send_header_field
 1346: #undef basic_http_header
 1347: #undef send_http_trace
 1348: #undef send_http_options
 1349: #undef send_error_response
 1350: #undef set_content_length
 1351: #undef set_keepalive
 1352: #undef rputs
 1353: #undef log_error
 1354: #undef lookup_uri
 1355: #undef lookup_file
 1356: #undef method_uri
 1357: #undef run
 1358: #undef internal_redirect
 1359: 	PHP_FALIAS(auth_name,					apache_request_auth_name,				NULL)
 1360: 	PHP_FALIAS(auth_type,					apache_request_auth_type,				NULL)
 1361: 	PHP_FALIAS(basic_auth_pw,				apache_request_basic_auth_pw,			NULL)
 1362: 	PHP_FALIAS(discard_request_body,		apache_request_discard_request_body,	NULL)
 1363: 	PHP_FALIAS(is_initial_req,				apache_request_is_initial_req,			NULL)
 1364: 	PHP_FALIAS(meets_conditions,			apache_request_meets_conditions,		NULL)
 1365: 	PHP_FALIAS(remote_host,					apache_request_remote_host,				NULL)
 1366: 	PHP_FALIAS(satisfies,					apache_request_satisfies,				NULL)
 1367: 	PHP_FALIAS(server_port,					apache_request_server_port,				NULL)
 1368: 	PHP_FALIAS(set_etag,					apache_request_set_etag,				NULL)
 1369: 	PHP_FALIAS(set_last_modified,			apache_request_set_last_modified,		NULL)
 1370: 	PHP_FALIAS(some_auth_required,			apache_request_some_auth_required,		NULL)
 1371: 	PHP_FALIAS(update_mtime,				apache_request_update_mtime,			NULL)
 1372: 	PHP_FALIAS(send_http_header,			apache_request_send_http_header,		NULL)
 1373: 	PHP_FALIAS(basic_http_header,			apache_request_basic_http_header,		NULL)
 1374:     PHP_FALIAS(send_header_field,           apache_request_send_header_field,       NULL)
 1375: 	PHP_FALIAS(send_http_trace,			    apache_request_send_http_trace,		    NULL)
 1376: 	PHP_FALIAS(send_http_options,			apache_request_send_http_trace,		    NULL)
 1377: 	PHP_FALIAS(send_error_response,			apache_request_send_error_response,	    NULL)
 1378:     PHP_FALIAS(set_content_length,          apache_request_set_content_length,      NULL)
 1379:     PHP_FALIAS(set_keepalive,               apache_request_set_keepalive,           NULL)
 1380:     PHP_FALIAS(rputs,                       apache_request_rputs,                   NULL)
 1381:     PHP_FALIAS(log_error,                   apache_request_log_error,               NULL)
 1382:     PHP_FALIAS(lookup_uri,                  apache_request_sub_req_lookup_uri,      NULL)
 1383:     PHP_FALIAS(lookup_file,                 apache_request_sub_req_lookup_file,     NULL)
 1384:     PHP_FALIAS(method_uri,                  apache_request_sub_req_method_uri,      NULL)
 1385:     PHP_FALIAS(run,                         apache_request_run,                     NULL)
 1386:     PHP_FALIAS(internal_redirect,           apache_request_internal_redirect,       NULL)
 1387: 	PHP_FE_END
 1388: };
 1389: /* }}} */
 1390: 
 1391: 
 1392: static PHP_MINIT_FUNCTION(apache)
 1393: {
 1394: 	zend_class_entry ce;
 1395: 
 1396: #ifdef ZTS
 1397: 	ts_allocate_id(&php_apache_info_id, sizeof(php_apache_info_struct), (ts_allocate_ctor) php_apache_globals_ctor, NULL);
 1398: #else
 1399: 	php_apache_globals_ctor(&php_apache_info TSRMLS_CC);
 1400: #endif
 1401: 	REGISTER_INI_ENTRIES();
 1402: 
 1403: 
 1404: 	le_apachereq = zend_register_list_destructors_ex(php_apache_request_free, NULL, "ApacheRequest", module_number);
 1405: 	INIT_OVERLOADED_CLASS_ENTRY(ce, "ApacheRequest", php_apache_request_class_functions, NULL, NULL, NULL);
 1406: 	apacherequest_class_entry = zend_register_internal_class_ex(&ce, NULL, NULL TSRMLS_CC);
 1407: 
 1408: 	REGISTER_LONG_CONSTANT("OK",				OK,					CONST_CS | CONST_PERSISTENT);
 1409: 	REGISTER_LONG_CONSTANT("DECLINED",			DECLINED,			CONST_CS | CONST_PERSISTENT);
 1410: 	REGISTER_LONG_CONSTANT("FORBIDDEN",			FORBIDDEN,			CONST_CS | CONST_PERSISTENT);
 1411: 	REGISTER_LONG_CONSTANT("AUTH_REQUIRED",		AUTH_REQUIRED,		CONST_CS | CONST_PERSISTENT);
 1412: 	REGISTER_LONG_CONSTANT("DONE",				DONE,				CONST_CS | CONST_PERSISTENT);
 1413: 	REGISTER_LONG_CONSTANT("SERVER_ERROR",		SERVER_ERROR,		CONST_CS | CONST_PERSISTENT);
 1414: 	REGISTER_LONG_CONSTANT("REDIRECT",			REDIRECT,			CONST_CS | CONST_PERSISTENT);
 1415: 	REGISTER_LONG_CONSTANT("BAD_REQUEST",		BAD_REQUEST,		CONST_CS | CONST_PERSISTENT);
 1416: 	REGISTER_LONG_CONSTANT("NOT_FOUND",			NOT_FOUND,			CONST_CS | CONST_PERSISTENT);
 1417:     REGISTER_LONG_CONSTANT("HTTP_CONTINUE",     HTTP_CONTINUE,   CONST_CS | CONST_PERSISTENT);
 1418:     REGISTER_LONG_CONSTANT("HTTP_SWITCHING_PROTOCOLS",     HTTP_SWITCHING_PROTOCOLS,   CONST_CS | CONST_PERSISTENT);
 1419:     REGISTER_LONG_CONSTANT("HTTP_PROCESSING",     HTTP_PROCESSING,   CONST_CS | CONST_PERSISTENT);
 1420:     REGISTER_LONG_CONSTANT("HTTP_OK",     HTTP_OK,   CONST_CS | CONST_PERSISTENT);
 1421:     REGISTER_LONG_CONSTANT("HTTP_CREATED",     HTTP_CREATED,   CONST_CS | CONST_PERSISTENT);
 1422:     REGISTER_LONG_CONSTANT("HTTP_ACCEPTED",     HTTP_ACCEPTED,   CONST_CS | CONST_PERSISTENT);
 1423:     REGISTER_LONG_CONSTANT("HTTP_NON_AUTHORITATIVE",     HTTP_NON_AUTHORITATIVE,   CONST_CS | CONST_PERSISTENT);
 1424:     REGISTER_LONG_CONSTANT("HTTP_NO_CONTENT",     HTTP_NO_CONTENT,   CONST_CS | CONST_PERSISTENT);
 1425:     REGISTER_LONG_CONSTANT("HTTP_RESET_CONTENT",     HTTP_RESET_CONTENT,   CONST_CS | CONST_PERSISTENT);
 1426:     REGISTER_LONG_CONSTANT("HTTP_PARTIAL_CONTENT",     HTTP_PARTIAL_CONTENT,   CONST_CS | CONST_PERSISTENT);
 1427:     REGISTER_LONG_CONSTANT("HTTP_MULTI_STATUS",     HTTP_MULTI_STATUS,   CONST_CS | CONST_PERSISTENT);
 1428:     REGISTER_LONG_CONSTANT("HTTP_MULTIPLE_CHOICES",     HTTP_MULTIPLE_CHOICES,   CONST_CS | CONST_PERSISTENT);
 1429:     REGISTER_LONG_CONSTANT("HTTP_MOVED_PERMANENTLY",     HTTP_MOVED_PERMANENTLY,   CONST_CS | CONST_PERSISTENT);
 1430:     REGISTER_LONG_CONSTANT("HTTP_MOVED_TEMPORARILY",     HTTP_MOVED_TEMPORARILY,   CONST_CS | CONST_PERSISTENT);
 1431:     REGISTER_LONG_CONSTANT("HTTP_SEE_OTHER",     HTTP_SEE_OTHER,   CONST_CS | CONST_PERSISTENT);
 1432:     REGISTER_LONG_CONSTANT("HTTP_NOT_MODIFIED",     HTTP_NOT_MODIFIED,   CONST_CS | CONST_PERSISTENT);
 1433:     REGISTER_LONG_CONSTANT("HTTP_USE_PROXY",     HTTP_USE_PROXY,   CONST_CS | CONST_PERSISTENT);
 1434:     REGISTER_LONG_CONSTANT("HTTP_TEMPORARY_REDIRECT",     HTTP_TEMPORARY_REDIRECT,   CONST_CS | CONST_PERSISTENT);
 1435:     REGISTER_LONG_CONSTANT("HTTP_BAD_REQUEST",     HTTP_BAD_REQUEST,   CONST_CS | CONST_PERSISTENT);
 1436:     REGISTER_LONG_CONSTANT("HTTP_UNAUTHORIZED",     HTTP_UNAUTHORIZED,   CONST_CS | CONST_PERSISTENT);
 1437:     REGISTER_LONG_CONSTANT("HTTP_PAYMENT_REQUIRED",     HTTP_PAYMENT_REQUIRED,   CONST_CS | CONST_PERSISTENT);
 1438:     REGISTER_LONG_CONSTANT("HTTP_FORBIDDEN",     HTTP_FORBIDDEN,   CONST_CS | CONST_PERSISTENT);
 1439:     REGISTER_LONG_CONSTANT("HTTP_NOT_FOUND",     HTTP_NOT_FOUND,   CONST_CS | CONST_PERSISTENT);
 1440:     REGISTER_LONG_CONSTANT("HTTP_METHOD_NOT_ALLOWED",     HTTP_METHOD_NOT_ALLOWED,   CONST_CS | CONST_PERSISTENT);
 1441:     REGISTER_LONG_CONSTANT("HTTP_NOT_ACCEPTABLE",     HTTP_NOT_ACCEPTABLE,   CONST_CS | CONST_PERSISTENT);
 1442:     REGISTER_LONG_CONSTANT("HTTP_PROXY_AUTHENTICATION_REQUIRED",     HTTP_PROXY_AUTHENTICATION_REQUIRED,   CONST_CS | CONST_PERSISTENT);
 1443:     REGISTER_LONG_CONSTANT("HTTP_REQUEST_TIME_OUT",     HTTP_REQUEST_TIME_OUT,   CONST_CS | CONST_PERSISTENT);
 1444:     REGISTER_LONG_CONSTANT("HTTP_CONFLICT",     HTTP_CONFLICT,   CONST_CS | CONST_PERSISTENT);
 1445:     REGISTER_LONG_CONSTANT("HTTP_GONE",     HTTP_GONE,   CONST_CS | CONST_PERSISTENT);REGISTER_LONG_CONSTANT("HTTP_LENGTH_REQUIRED",     HTTP_LENGTH_REQUIRED,   CONST_CS | CONST_PERSISTENT);
 1446:     REGISTER_LONG_CONSTANT("HTTP_PRECONDITION_FAILED",     HTTP_PRECONDITION_FAILED,   CONST_CS | CONST_PERSISTENT);
 1447:     REGISTER_LONG_CONSTANT("HTTP_REQUEST_ENTITY_TOO_LARGE",     HTTP_REQUEST_ENTITY_TOO_LARGE,   CONST_CS | CONST_PERSISTENT);
 1448:     REGISTER_LONG_CONSTANT("HTTP_REQUEST_URI_TOO_LARGE",     HTTP_REQUEST_URI_TOO_LARGE,   CONST_CS | CONST_PERSISTENT);
 1449:     REGISTER_LONG_CONSTANT("HTTP_UNSUPPORTED_MEDIA_TYPE",     HTTP_UNSUPPORTED_MEDIA_TYPE,   CONST_CS | CONST_PERSISTENT);
 1450:     REGISTER_LONG_CONSTANT("HTTP_RANGE_NOT_SATISFIABLE",     HTTP_RANGE_NOT_SATISFIABLE,   CONST_CS | CONST_PERSISTENT);
 1451:     REGISTER_LONG_CONSTANT("HTTP_EXPECTATION_FAILED",     HTTP_EXPECTATION_FAILED,   CONST_CS | CONST_PERSISTENT);
 1452:     REGISTER_LONG_CONSTANT("HTTP_UNPROCESSABLE_ENTITY",     HTTP_UNPROCESSABLE_ENTITY,   CONST_CS | CONST_PERSISTENT);
 1453:     REGISTER_LONG_CONSTANT("HTTP_LOCKED",     HTTP_LOCKED,   CONST_CS | CONST_PERSISTENT);
 1454:     REGISTER_LONG_CONSTANT("HTTP_FAILED_DEPENDENCY",     HTTP_FAILED_DEPENDENCY,   CONST_CS | CONST_PERSISTENT);
 1455:     REGISTER_LONG_CONSTANT("HTTP_INTERNAL_SERVER_ERROR",     HTTP_INTERNAL_SERVER_ERROR,   CONST_CS | CONST_PERSISTENT);
 1456:     REGISTER_LONG_CONSTANT("HTTP_NOT_IMPLEMENTED",     HTTP_NOT_IMPLEMENTED,   CONST_CS | CONST_PERSISTENT);
 1457:     REGISTER_LONG_CONSTANT("HTTP_BAD_GATEWAY",     HTTP_BAD_GATEWAY,   CONST_CS | CONST_PERSISTENT);
 1458:     REGISTER_LONG_CONSTANT("HTTP_SERVICE_UNAVAILABLE",     HTTP_SERVICE_UNAVAILABLE,   CONST_CS | CONST_PERSISTENT);
 1459:     REGISTER_LONG_CONSTANT("HTTP_GATEWAY_TIME_OUT",     HTTP_GATEWAY_TIME_OUT,   CONST_CS | CONST_PERSISTENT);
 1460:     REGISTER_LONG_CONSTANT("HTTP_VERSION_NOT_SUPPORTED",     HTTP_VERSION_NOT_SUPPORTED,   CONST_CS | CONST_PERSISTENT);
 1461:     REGISTER_LONG_CONSTANT("HTTP_VARIANT_ALSO_VARIES",     HTTP_VARIANT_ALSO_VARIES,   CONST_CS | CONST_PERSISTENT);
 1462:     REGISTER_LONG_CONSTANT("HTTP_INSUFFICIENT_STORAGE",     HTTP_INSUFFICIENT_STORAGE,   CONST_CS | CONST_PERSISTENT);
 1463:     REGISTER_LONG_CONSTANT("HTTP_NOT_EXTENDED",     HTTP_NOT_EXTENDED,   CONST_CS | CONST_PERSISTENT);
 1464: 	REGISTER_LONG_CONSTANT("APLOG_EMERG",		APLOG_EMERG,		CONST_CS | CONST_PERSISTENT);
 1465: 	REGISTER_LONG_CONSTANT("APLOG_ALERT",		APLOG_ALERT,		CONST_CS | CONST_PERSISTENT);
 1466: 	REGISTER_LONG_CONSTANT("APLOG_CRIT",		APLOG_CRIT,			CONST_CS | CONST_PERSISTENT);
 1467: 	REGISTER_LONG_CONSTANT("APLOG_ERR",			APLOG_ERR,  		CONST_CS | CONST_PERSISTENT);
 1468: 	REGISTER_LONG_CONSTANT("APLOG_WARNING",		APLOG_WARNING,		CONST_CS | CONST_PERSISTENT);
 1469: 	REGISTER_LONG_CONSTANT("APLOG_NOTICE",		APLOG_NOTICE,		CONST_CS | CONST_PERSISTENT);
 1470: 	REGISTER_LONG_CONSTANT("APLOG_INFO",		APLOG_INFO,			CONST_CS | CONST_PERSISTENT);
 1471: 	REGISTER_LONG_CONSTANT("APLOG_DEBUG",		APLOG_DEBUG,		CONST_CS | CONST_PERSISTENT);
 1472: 	REGISTER_LONG_CONSTANT("M_GET",				M_GET,				CONST_CS | CONST_PERSISTENT);
 1473: 	REGISTER_LONG_CONSTANT("M_PUT",				M_PUT,				CONST_CS | CONST_PERSISTENT);
 1474: 	REGISTER_LONG_CONSTANT("M_POST",			M_POST,				CONST_CS | CONST_PERSISTENT);
 1475: 	REGISTER_LONG_CONSTANT("M_DELETE",			M_DELETE,			CONST_CS | CONST_PERSISTENT);
 1476: 	REGISTER_LONG_CONSTANT("M_CONNECT",			M_CONNECT,			CONST_CS | CONST_PERSISTENT);
 1477: 	REGISTER_LONG_CONSTANT("M_OPTIONS",			M_OPTIONS,			CONST_CS | CONST_PERSISTENT);
 1478: 	REGISTER_LONG_CONSTANT("M_TRACE",			M_TRACE,			CONST_CS | CONST_PERSISTENT);
 1479: 	REGISTER_LONG_CONSTANT("M_PATCH",			M_PATCH,			CONST_CS | CONST_PERSISTENT);
 1480: 	REGISTER_LONG_CONSTANT("M_PROPFIND",		M_PROPFIND,			CONST_CS | CONST_PERSISTENT);
 1481: 	REGISTER_LONG_CONSTANT("M_PROPPATCH",		M_PROPPATCH,		CONST_CS | CONST_PERSISTENT);
 1482: 	REGISTER_LONG_CONSTANT("M_MKCOL",			M_MKCOL,			CONST_CS | CONST_PERSISTENT);
 1483: 	REGISTER_LONG_CONSTANT("M_COPY",			M_COPY,				CONST_CS | CONST_PERSISTENT);
 1484: 	REGISTER_LONG_CONSTANT("M_MOVE",			M_MOVE,				CONST_CS | CONST_PERSISTENT);
 1485: 	REGISTER_LONG_CONSTANT("M_LOCK",			M_LOCK,				CONST_CS | CONST_PERSISTENT);
 1486: 	REGISTER_LONG_CONSTANT("M_UNLOCK",			M_UNLOCK,			CONST_CS | CONST_PERSISTENT);
 1487: 	REGISTER_LONG_CONSTANT("M_INVALID",			M_INVALID,			CONST_CS | CONST_PERSISTENT);
 1488: 
 1489: 	/* Possible values for request_rec.read_body (set by handling module):
 1490: 	 *    REQUEST_NO_BODY          Send 413 error if message has any body
 1491: 	 *    REQUEST_CHUNKED_ERROR    Send 411 error if body without Content-Length
 1492: 	 *    REQUEST_CHUNKED_DECHUNK  If chunked, remove the chunks for me.
 1493: 	 *    REQUEST_CHUNKED_PASS     Pass the chunks to me without removal.
 1494: 	 */
 1495: 	REGISTER_LONG_CONSTANT("REQUEST_NO_BODY",			REQUEST_NO_BODY,			CONST_CS | CONST_PERSISTENT);
 1496: 	REGISTER_LONG_CONSTANT("REQUEST_CHUNKED_ERROR", 	REQUEST_CHUNKED_ERROR,		CONST_CS | CONST_PERSISTENT);
 1497: 	REGISTER_LONG_CONSTANT("REQUEST_CHUNKED_DECHUNK",	REQUEST_CHUNKED_DECHUNK,	CONST_CS | CONST_PERSISTENT);
 1498: 	REGISTER_LONG_CONSTANT("REQUEST_CHUNKED_PASS",		REQUEST_CHUNKED_PASS,		CONST_CS | CONST_PERSISTENT);
 1499: 	
 1500: 	/* resolve types for remote_host() */
 1501: 	REGISTER_LONG_CONSTANT("REMOTE_HOST",			REMOTE_HOST,			CONST_CS | CONST_PERSISTENT);
 1502: 	REGISTER_LONG_CONSTANT("REMOTE_NAME", 			REMOTE_NAME,			CONST_CS | CONST_PERSISTENT);
 1503: 	REGISTER_LONG_CONSTANT("REMOTE_NOLOOKUP",		REMOTE_NOLOOKUP,		CONST_CS | CONST_PERSISTENT);
 1504: 	REGISTER_LONG_CONSTANT("REMOTE_DOUBLE_REV",		REMOTE_DOUBLE_REV,		CONST_CS | CONST_PERSISTENT);
 1505: 	
 1506: 	return SUCCESS;
 1507: }
 1508: 
 1509: 
 1510: static PHP_MSHUTDOWN_FUNCTION(apache)
 1511: {
 1512: 	UNREGISTER_INI_ENTRIES();
 1513: 	return SUCCESS;
 1514: }
 1515: 
 1516: zend_module_entry apache_module_entry = {
 1517: 	STANDARD_MODULE_HEADER,
 1518: 	"apache", 
 1519: 	apache_functions, 
 1520: 	PHP_MINIT(apache), 
 1521: 	PHP_MSHUTDOWN(apache), 
 1522: 	NULL, 
 1523: 	NULL, 
 1524: 	PHP_MINFO(apache), 
 1525: 	NO_VERSION_YET,
 1526: 	STANDARD_MODULE_PROPERTIES
 1527: };
 1528: 
 1529: /* {{{ proto bool apache_child_terminate(void)
 1530:    Terminate apache process after this request */
 1531: PHP_FUNCTION(apache_child_terminate)
 1532: {
 1533: #ifndef MULTITHREAD
 1534: 	if (AP(terminate_child)) {
 1535: 		ap_child_terminate( ((request_rec *)SG(server_context)) );
 1536: 		RETURN_TRUE;
 1537: 	} else { /* tell them to get lost! */
 1538: 		php_error(E_WARNING, "apache.child_terminate is disabled");
 1539: 		RETURN_FALSE;
 1540: 	}
 1541: #else
 1542: 		php_error(E_WARNING, "apache_child_terminate() is not supported in this build");
 1543: 		RETURN_FALSE;
 1544: #endif
 1545: }
 1546: /* }}} */
 1547: 
 1548: /* {{{ proto string apache_note(string note_name [, string note_value])
 1549:    Get and set Apache request notes */
 1550: PHP_FUNCTION(apache_note)
 1551: {
 1552: 	char *arg_name, *arg_val = NULL;
 1553: 	int arg_name_len, arg_val_len;
 1554: 	char *note_val;
 1555: 
 1556: 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s", &arg_name, &arg_name_len, &arg_val, &arg_val_len) == FAILURE) {
 1557: 		return;
 1558: 	}
 1559: 
 1560: 	note_val = (char *) table_get(((request_rec *)SG(server_context))->notes, arg_name);
 1561: 
 1562: 	if (arg_val) {
 1563: 		table_set(((request_rec *)SG(server_context))->notes, arg_name, arg_val);
 1564: 	}
 1565: 
 1566: 	if (!note_val) {
 1567: 		RETURN_FALSE;
 1568: 	}
 1569: 
 1570: 	RETURN_STRING(note_val, 1);
 1571: }
 1572: /* }}} */
 1573: 
 1574: /* {{{ PHP_MINFO_FUNCTION
 1575:  */
 1576: PHP_MINFO_FUNCTION(apache)
 1577: {
 1578: 	module *modp = NULL;
 1579: 	char output_buf[128];
 1580: #if !defined(WIN32) && !defined(WINNT)
 1581: 	char name[64];
 1582: 	char modulenames[1024];
 1583: 	char *p;
 1584: #endif
 1585: 	server_rec *serv;
 1586: 	extern char server_root[MAX_STRING_LEN];
 1587: 	extern uid_t user_id;
 1588: 	extern char *user_name;
 1589: 	extern gid_t group_id;
 1590: 	extern int max_requests_per_child;
 1591: 
 1592: 	serv = ((request_rec *) SG(server_context))->server;
 1593: 
 1594: 
 1595: 	php_info_print_table_start();
 1596: 
 1597: #ifdef PHP_WIN32
 1598: 	php_info_print_table_row(1, "Apache for Windows 95/NT");
 1599: 	php_info_print_table_end();
 1600: 	php_info_print_table_start();
 1601: #elif defined(NETWARE)
 1602: 	php_info_print_table_row(1, "Apache for NetWare");
 1603: 	php_info_print_table_end();
 1604: 	php_info_print_table_start();
 1605: #else
 1606: 	php_info_print_table_row(2, "APACHE_INCLUDE", PHP_APACHE_INCLUDE);
 1607: 	php_info_print_table_row(2, "APACHE_TARGET", PHP_APACHE_TARGET);
 1608: #endif
 1609: 
 1610: 	php_info_print_table_row(2, "Apache Version", SERVER_VERSION);
 1611: 
 1612: #ifdef APACHE_RELEASE
 1613: 	snprintf(output_buf, sizeof(output_buf), "%d", APACHE_RELEASE);
 1614: 	php_info_print_table_row(2, "Apache Release", output_buf);
 1615: #endif
 1616: 	snprintf(output_buf, sizeof(output_buf), "%d", MODULE_MAGIC_NUMBER);
 1617: 	php_info_print_table_row(2, "Apache API Version", output_buf);
 1618: 	snprintf(output_buf, sizeof(output_buf), "%s:%u", serv->server_hostname, serv->port);
 1619: 	php_info_print_table_row(2, "Hostname:Port", output_buf);
 1620: #if !defined(WIN32) && !defined(WINNT)
 1621: 	snprintf(output_buf, sizeof(output_buf), "%s(%d)/%d", user_name, (int)user_id, (int)group_id);
 1622: 	php_info_print_table_row(2, "User/Group", output_buf);
 1623: 	snprintf(output_buf, sizeof(output_buf), "Per Child: %d - Keep Alive: %s - Max Per Connection: %d", max_requests_per_child, serv->keep_alive ? "on":"off", serv->keep_alive_max);
 1624: 	php_info_print_table_row(2, "Max Requests", output_buf);
 1625: #endif
 1626: 	snprintf(output_buf, sizeof(output_buf), "Connection: %d - Keep-Alive: %d", serv->timeout, serv->keep_alive_timeout);
 1627: 	php_info_print_table_row(2, "Timeouts", output_buf);
 1628: #if !defined(WIN32) && !defined(WINNT)
 1629: /*
 1630: 	This block seems to be working on NetWare; But it seems to be showing
 1631: 	all modules instead of just the loaded ones
 1632: */
 1633: 	php_info_print_table_row(2, "Server Root", server_root);
 1634: 
 1635: 	strcpy(modulenames, "");
 1636: 	for(modp = top_module; modp; modp = modp->next) {
 1637: 		strlcpy(name, modp->name, sizeof(name));
 1638: 		if ((p = strrchr(name, '.'))) {
 1639: 			*p='\0'; /* Cut off ugly .c extensions on module names */
 1640: 		}
 1641: 		strlcat(modulenames, name, sizeof(modulenames));
 1642: 		if (modp->next) {
 1643: 			strlcat(modulenames, ", ", sizeof(modulenames));
 1644: 		}
 1645: 	}
 1646: 	php_info_print_table_row(2, "Loaded Modules", modulenames);
 1647: #endif
 1648: 
 1649: 	php_info_print_table_end();
 1650: 
 1651: 	DISPLAY_INI_ENTRIES();
 1652: 
 1653: 	{
 1654: 		register int i;
 1655: 		array_header *arr;
 1656: 		table_entry *elts;
 1657: 		request_rec *r;
 1658: 
 1659: 		r = ((request_rec *) SG(server_context));
 1660: 		arr = table_elts(r->subprocess_env);
 1661: 		elts = (table_entry *)arr->elts;
 1662: 		
 1663: 		SECTION("Apache Environment");
 1664: 		php_info_print_table_start();	
 1665: 		php_info_print_table_header(2, "Variable", "Value");
 1666: 		for (i=0; i < arr->nelts; i++) {
 1667: 			php_info_print_table_row(2, elts[i].key, elts[i].val);
 1668: 		}
 1669: 		php_info_print_table_end();	
 1670: 	}
 1671: 
 1672: 	{
 1673: 		array_header *env_arr;
 1674: 		table_entry *env;
 1675: 		int i;
 1676: 		request_rec *r;
 1677: 		
 1678: 		r = ((request_rec *) SG(server_context));
 1679: 		SECTION("HTTP Headers Information");
 1680: 		php_info_print_table_start();
 1681: 		php_info_print_table_colspan_header(2, "HTTP Request Headers");
 1682: 		php_info_print_table_row(2, "HTTP Request", r->the_request);
 1683: 		env_arr = table_elts(r->headers_in);
 1684: 		env = (table_entry *)env_arr->elts;
 1685: 		for (i = 0; i < env_arr->nelts; ++i) {
 1686: 			if (env[i].key) {
 1687: 				php_info_print_table_row(2, env[i].key, env[i].val);
 1688: 			}
 1689: 		}
 1690: 		php_info_print_table_colspan_header(2, "HTTP Response Headers");
 1691: 		env_arr = table_elts(r->headers_out);
 1692: 		env = (table_entry *)env_arr->elts;
 1693: 		for(i = 0; i < env_arr->nelts; ++i) {
 1694: 			if (env[i].key) {
 1695: 				php_info_print_table_row(2, env[i].key, env[i].val);
 1696: 			}
 1697: 		}
 1698: 		php_info_print_table_end();
 1699: 	}
 1700: }
 1701: /* }}} */
 1702: 
 1703: /* {{{ proto bool virtual(string filename)
 1704:    Perform an Apache sub-request */
 1705: /* This function is equivalent to <!--#include virtual...-->
 1706:  * in mod_include. It does an Apache sub-request. It is useful
 1707:  * for including CGI scripts or .shtml files, or anything else
 1708:  * that you'd parse through Apache (for .phtml files, you'd probably
 1709:  * want to use <?Include>. This only works when PHP is compiled
 1710:  * as an Apache module, since it uses the Apache API for doing
 1711:  * sub requests.
 1712:  */
 1713: PHP_FUNCTION(virtual)
 1714: {
 1715: 	char *filename;
 1716: 	int filename_len;
 1717: 	request_rec *rr = NULL;
 1718: 
 1719: 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &filename, &filename_len) == FAILURE) {
 1720: 		return;
 1721: 	}
 1722: 
 1723: 	if (!(rr = sub_req_lookup_uri (filename, ((request_rec *) SG(server_context))))) {
 1724: 		php_error(E_WARNING, "Unable to include '%s' - URI lookup failed", filename);
 1725: 		if (rr)
 1726: 			destroy_sub_req (rr);
 1727: 		RETURN_FALSE;
 1728: 	}
 1729: 
 1730: 	if (rr->status != 200) {
 1731: 		php_error(E_WARNING, "Unable to include '%s' - error finding URI", filename);
 1732: 		if (rr)
 1733: 			destroy_sub_req (rr);
 1734: 		RETURN_FALSE;
 1735: 	}
 1736: 
 1737: 	php_output_end_all(TSRMLS_C);
 1738: 	php_header(TSRMLS_C);
 1739: 
 1740: 	if (run_sub_req(rr)) {
 1741: 		php_error(E_WARNING, "Unable to include '%s' - request execution failed", filename);
 1742: 		if (rr)
 1743: 			destroy_sub_req (rr);
 1744: 		RETURN_FALSE;
 1745: 	} 
 1746: 
 1747: 	if (rr)
 1748: 		destroy_sub_req (rr);
 1749: 	RETURN_TRUE;
 1750: }
 1751: /* }}} */
 1752: 
 1753: 
 1754: /* {{{ apache_table_to_zval(table *, zval *return_value)
 1755:    Fetch all HTTP request headers */
 1756: static void apache_table_to_zval(table *t, zval *return_value)
 1757: {
 1758:     array_header *env_arr;
 1759:     table_entry *tenv;
 1760:     int i;
 1761: 	
 1762:     array_init(return_value);
 1763:     env_arr = table_elts(t);
 1764:     tenv = (table_entry *)env_arr->elts;
 1765:     for (i = 0; i < env_arr->nelts; ++i) {
 1766: 		if (!tenv[i].key) {
 1767: 			continue;
 1768: 		}
 1769: 		if (add_assoc_string(return_value, tenv[i].key, (tenv[i].val==NULL) ? "" : tenv[i].val, 1)==FAILURE) {
 1770: 			RETURN_FALSE;
 1771: 		}
 1772:     }
 1773: 
 1774: }
 1775: /* }}} */
 1776: 
 1777: 
 1778: /* {{{ proto array getallheaders(void)
 1779: */
 1780: /*  Alias for apache_request_headers() */
 1781: /* }}} */
 1782: 
 1783: /* {{{ proto array apache_request_headers(void)
 1784:    Fetch all HTTP request headers */
 1785: PHP_FUNCTION(apache_request_headers)
 1786: {
 1787: 	if (zend_parse_parameters_none() == FAILURE) {
 1788:  		return;
 1789:  	}
 1790: 
 1791: 	apache_table_to_zval(((request_rec *)SG(server_context))->headers_in, return_value);
 1792: }
 1793: /* }}} */
 1794: 
 1795: /* {{{ proto array apache_response_headers(void)
 1796:    Fetch all HTTP response headers */
 1797: PHP_FUNCTION(apache_response_headers)
 1798: {
 1799: 	if (zend_parse_parameters_none() == FAILURE) {
 1800:  		return;
 1801:  	}
 1802: 
 1803: 	apache_table_to_zval(((request_rec *) SG(server_context))->headers_out, return_value);
 1804: }
 1805: /* }}} */
 1806: 
 1807: /* {{{ proto bool apache_setenv(string variable, string value [, bool walk_to_top])
 1808:    Set an Apache subprocess_env variable */
 1809: PHP_FUNCTION(apache_setenv)
 1810: {
 1811: 	int var_len, val_len;
 1812: 	zend_bool top=0;
 1813: 	char *var = NULL, *val = NULL;
 1814: 	request_rec *r = (request_rec *) SG(server_context);
 1815: 
 1816:     if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|b", &var, &var_len, &val, &val_len, &top) == FAILURE) {
 1817:         RETURN_FALSE;
 1818: 	}
 1819: 
 1820: 	while(top) {
 1821: 		if (r->prev) {
 1822: 			r = r->prev;
 1823: 		}
 1824: 		else break;
 1825: 	}
 1826: 
 1827: 	ap_table_setn(r->subprocess_env, ap_pstrndup(r->pool, var, var_len), ap_pstrndup(r->pool, val, val_len));
 1828: 	RETURN_TRUE;
 1829: }
 1830: /* }}} */
 1831: 
 1832: /* {{{ proto object apache_lookup_uri(string URI)
 1833:    Perform a partial request of the given URI to obtain information about it */
 1834: PHP_FUNCTION(apache_lookup_uri)
 1835: {
 1836: 	char *filename;
 1837: 	int filename_len;
 1838: 	request_rec *rr=NULL;
 1839: 
 1840: 	if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &filename, &filename_len) == FAILURE) {
 1841: 		return;
 1842: 	}
 1843: 
 1844: 	if(!(rr = sub_req_lookup_uri(filename, ((request_rec *) SG(server_context))))) {
 1845: 		php_error(E_WARNING, "URI lookup failed", filename);
 1846: 		RETURN_FALSE;
 1847: 	}
 1848: 
 1849: 	object_init(return_value);
 1850: 	add_property_long(return_value,"status", rr->status);
 1851: 
 1852: 	if (rr->the_request) {
 1853: 		add_property_string(return_value,"the_request", rr->the_request, 1);
 1854: 	}
 1855: 	if (rr->status_line) {
 1856: 		add_property_string(return_value,"status_line", (char *)rr->status_line, 1);		
 1857: 	}
 1858: 	if (rr->method) {
 1859: 		add_property_string(return_value,"method", (char *)rr->method, 1);		
 1860: 	}
 1861: 	if (rr->content_type) {
 1862: 		add_property_string(return_value,"content_type", (char *)rr->content_type, 1);
 1863: 	}
 1864: 	if (rr->handler) {
 1865: 		add_property_string(return_value,"handler", (char *)rr->handler, 1);		
 1866: 	}
 1867: 	if (rr->uri) {
 1868: 		add_property_string(return_value,"uri", rr->uri, 1);
 1869: 	}
 1870: 	if (rr->filename) {
 1871: 		add_property_string(return_value,"filename", rr->filename, 1);
 1872: 	}
 1873: 	if (rr->path_info) {
 1874: 		add_property_string(return_value,"path_info", rr->path_info, 1);
 1875: 	}
 1876: 	if (rr->args) {
 1877: 		add_property_string(return_value,"args", rr->args, 1);
 1878: 	}
 1879: 	if (rr->boundary) {
 1880: 		add_property_string(return_value,"boundary", rr->boundary, 1);
 1881: 	}
 1882: 	add_property_long(return_value,"no_cache", rr->no_cache);
 1883: 	add_property_long(return_value,"no_local_copy", rr->no_local_copy);
 1884: 	add_property_long(return_value,"allowed", rr->allowed);
 1885: 	add_property_long(return_value,"sent_bodyct", rr->sent_bodyct);
 1886: 	add_property_long(return_value,"bytes_sent", rr->bytes_sent);
 1887: 	add_property_long(return_value,"byterange", rr->byterange);
 1888: 	add_property_long(return_value,"clength", rr->clength);
 1889: 
 1890: #if MODULE_MAGIC_NUMBER >= 19980324
 1891: 	if (rr->unparsed_uri) {
 1892: 		add_property_string(return_value,"unparsed_uri", rr->unparsed_uri, 1);
 1893: 	}
 1894: 	if(rr->mtime) {
 1895: 		add_property_long(return_value,"mtime", rr->mtime);
 1896: 	}
 1897: #endif
 1898: 	if(rr->request_time) {
 1899: 		add_property_long(return_value,"request_time", rr->request_time);
 1900: 	}
 1901: 
 1902: 	destroy_sub_req(rr);
 1903: }
 1904: /* }}} */
 1905: 
 1906: 
 1907: #if 0
 1908: /*
 1909: This function is most likely a bad idea.  Just playing with it for now.
 1910: */
 1911: 
 1912: PHP_FUNCTION(apache_exec_uri)
 1913: {
 1914: 	zval **filename;
 1915: 	request_rec *rr=NULL;
 1916: 
 1917: 	if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &filename) == FAILURE) {
 1918: 		WRONG_PARAM_COUNT;
 1919: 	}
 1920: 	convert_to_string_ex(filename);
 1921: 
 1922: 	if(!(rr = ap_sub_req_lookup_uri((*filename)->value.str.val, ((request_rec *) SG(server_context))))) {
 1923: 		php_error(E_WARNING, "URI lookup failed", (*filename)->value.str.val);
 1924: 		RETURN_FALSE;
 1925: 	}
 1926: 	RETVAL_LONG(ap_run_sub_req(rr));
 1927: 	ap_destroy_sub_req(rr);
 1928: }
 1929: #endif
 1930: 
 1931: /* {{{ proto string apache_get_version(void)
 1932:    Fetch Apache version */
 1933: PHP_FUNCTION(apache_get_version)
 1934: {
 1935: 	char *apv = (char *) ap_get_server_version();
 1936: 
 1937: 	if (apv && *apv) {
 1938: 		RETURN_STRING(apv, 1);
 1939: 	} else {
 1940: 		RETURN_FALSE;
 1941: 	}
 1942: }
 1943: /* }}} */
 1944: 
 1945: /* {{{ proto array apache_get_modules(void)
 1946:    Get a list of loaded Apache modules */
 1947: PHP_FUNCTION(apache_get_modules)
 1948: {
 1949: 	int n;
 1950: 	char *p;
 1951: 	
 1952: 	array_init(return_value);
 1953: 	
 1954: 	for (n = 0; ap_loaded_modules[n]; ++n) {
 1955: 		char *s = (char *) ap_loaded_modules[n]->name;
 1956: 		if ((p = strchr(s, '.'))) {
 1957: 			add_next_index_stringl(return_value, s, (p - s), 1);
 1958: 		} else {
 1959: 			add_next_index_string(return_value, s, 1);
 1960: 		}	
 1961: 	}
 1962: }
 1963: /* }}} */
 1964: 
 1965: /*
 1966:  * Local variables:
 1967:  * tab-width: 4
 1968:  * c-basic-offset: 4
 1969:  * End:
 1970:  * vim600: sw=4 ts=4 fdm=marker
 1971:  * vim<600: sw=4 ts=4
 1972:  */

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>