Back to index

php5  5.3.10
php_apache.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    | Authors: Rasmus Lerdorf <rasmus@lerdorf.on.ca>                       |
00016    |          Stig Sæther Bakken <ssb@php.net>                            |
00017    |          David Sklar <sklar@student.net>                             |
00018    +----------------------------------------------------------------------+
00019  */
00020 /* $Id: php_apache.c 321634 2012-01-01 13:15:04Z felipe $ */
00021 
00022 #include "php_apache_http.h"
00023 
00024 #if defined(PHP_WIN32) || defined(NETWARE)
00025 #include "zend.h"
00026 #include "ap_compat.h"
00027 #else
00028 #include <build-defs.h>
00029 #endif
00030 
00031 #ifdef ZTS
00032 int php_apache_info_id;
00033 #else
00034 php_apache_info_struct php_apache_info;
00035 #endif
00036 
00037 #define SECTION(name)  PUTS("<H2 align=\"center\">" name "</H2>\n")
00038 
00039 #undef offsetof
00040 #define offsetof(s_type,field) ((size_t)&(((s_type*)0)->field))
00041 
00042 extern module *top_module;
00043 extern module **ap_loaded_modules;
00044 static int le_apachereq;
00045 static zend_class_entry *apacherequest_class_entry;
00046 
00047 static void apache_table_to_zval(table *, int safe_mode, zval *return_value);
00048 
00049 PHP_FUNCTION(virtual);
00050 PHP_FUNCTION(apache_request_headers);
00051 PHP_FUNCTION(apache_response_headers);
00052 PHP_FUNCTION(apachelog);
00053 PHP_FUNCTION(apache_note);
00054 PHP_FUNCTION(apache_lookup_uri);
00055 PHP_FUNCTION(apache_child_terminate);
00056 PHP_FUNCTION(apache_setenv);
00057 PHP_FUNCTION(apache_get_version);
00058 PHP_FUNCTION(apache_get_modules);
00059 
00060 PHP_MINFO_FUNCTION(apache);
00061 
00062 ZEND_BEGIN_ARG_INFO_EX(arginfo_apachehooks_virtual, 0, 0, 1)
00063        ZEND_ARG_INFO(0, filename)
00064 ZEND_END_ARG_INFO()
00065 
00066 ZEND_BEGIN_ARG_INFO_EX(arginfo_apachehooks_setenv, 0, 0, 2)
00067        ZEND_ARG_INFO(0, variable)
00068        ZEND_ARG_INFO(0, value)
00069        ZEND_ARG_INFO(0, walk_to_top)
00070 ZEND_END_ARG_INFO()
00071 
00072 ZEND_BEGIN_ARG_INFO_EX(arginfo_apachehooks_lookup_uri, 0, 0, 1)
00073        ZEND_ARG_INFO(0, uri)
00074 ZEND_END_ARG_INFO()
00075 
00076 ZEND_BEGIN_ARG_INFO(arginfo_apachehooks__void, 0)
00077 ZEND_END_ARG_INFO()
00078 
00079 ZEND_BEGIN_ARG_INFO_EX(arginfo_apachehooks_note, 0, 0, 1)
00080        ZEND_ARG_INFO(0, note_name)
00081        ZEND_ARG_INFO(0, note_value)
00082 ZEND_END_ARG_INFO()
00083 
00084 const zend_function_entry apache_functions[] = {
00085        PHP_FE(virtual,                                                              arginfo_apachehooks_virtual)
00086        PHP_FE(apache_request_headers,                                 arginfo_apachehooks__void)
00087        PHP_FE(apache_note,                                                   arginfo_apachehooks_note)
00088        PHP_FE(apache_lookup_uri,                                      arginfo_apachehooks_lookup_uri)
00089        PHP_FE(apache_child_terminate,                                 arginfo_apachehooks__void)
00090        PHP_FE(apache_setenv,                                                 arginfo_apachehooks_setenv)
00091        PHP_FE(apache_response_headers,                                arginfo_apachehooks__void)
00092        PHP_FE(apache_get_version,                                     arginfo_apachehooks__void)
00093        PHP_FE(apache_get_modules,                                     arginfo_apachehooks__void)
00094        PHP_FALIAS(getallheaders, apache_request_headers, arginfo_apachehooks__void)
00095        {NULL, NULL, NULL}
00096 };
00097 
00098 /* {{{ php_apache ini entries
00099  */
00100 PHP_INI_BEGIN()
00101        STD_PHP_INI_ENTRY("xbithack",                    "0",                        PHP_INI_ALL,         OnUpdateLong,        xbithack, php_apache_info_struct, php_apache_info)
00102        STD_PHP_INI_ENTRY("engine",                      "1",                        PHP_INI_ALL,         OnUpdateLong,        engine, php_apache_info_struct, php_apache_info)
00103        STD_PHP_INI_ENTRY("last_modified",        "0",                        PHP_INI_ALL,         OnUpdateLong,        last_modified, php_apache_info_struct, php_apache_info)
00104        STD_PHP_INI_ENTRY("child_terminate",      "0",                        PHP_INI_ALL,         OnUpdateLong,        terminate_child, php_apache_info_struct, php_apache_info)
00105 PHP_INI_END()
00106 /* }}} */
00107 
00108 static void php_apache_globals_ctor(php_apache_info_struct *apache_globals TSRMLS_DC)
00109 {
00110        apache_globals->in_request = 0;
00111 }
00112 
00113 
00114 #define APREQ_GET_THIS(ZVAL)              if (NULL == (ZVAL = getThis())) { \
00115                                                                       php_error(E_WARNING, "%s(): underlying ApacheRequest object missing", \
00116                                                                              get_active_function_name(TSRMLS_C)); \
00117                                                                       RETURN_FALSE; \
00118                                                                }
00119 #define APREQ_GET_REQUEST(ZVAL, R) APREQ_GET_THIS(ZVAL); \
00120                                                                R = get_apache_request(ZVAL TSRMLS_CC)
00121 
00122 static void php_apache_request_free(zend_rsrc_list_entry *rsrc TSRMLS_DC)
00123 {
00124        zval *z = (zval *)rsrc->ptr;
00125 /*     fprintf(stderr, "%s() %p\n", __FUNCTION__, z); */
00126        zval_ptr_dtor(&z);
00127 }
00128 
00129 static request_rec *get_apache_request(zval *z TSRMLS_DC)
00130 {
00131        request_rec *r;
00132        zval **addr;
00133 
00134        if (NULL == z) {
00135               php_error(E_WARNING, "get_apache_request() invalid wrapper passed");
00136               return NULL;
00137        }
00138 
00139        if (Z_TYPE_P(z) != IS_OBJECT) {
00140               php_error(E_WARNING, "%s(): wrapper is not an object", get_active_function_name(TSRMLS_C));
00141               return NULL;
00142        }
00143 
00144        if (zend_hash_index_find(Z_OBJPROP_P(z), 0, (void **)&addr) == FAILURE) {
00145               php_error(E_WARNING, "%s(): underlying object missing", get_active_function_name(TSRMLS_C));
00146               return NULL;
00147        }
00148 
00149        r = (request_rec *)Z_LVAL_PP(addr);
00150        if (!r) {
00151               php_error(E_WARNING, "%s(): request_rec invalid", get_active_function_name(TSRMLS_C));
00152               return NULL;
00153        }
00154 
00155        return r;
00156 }
00157 
00158 /* {{{ php_apache_request_new(request_rec *r)
00159  * create a new zval-instance for ApacheRequest that wraps request_rec
00160  */
00161 zval *php_apache_request_new(request_rec *r)
00162 {
00163        zval *req;
00164        zval *addr;
00165        
00166        TSRMLS_FETCH();
00167 
00168        MAKE_STD_ZVAL(addr);
00169        Z_TYPE_P(addr) = IS_LONG;
00170        Z_LVAL_P(addr) = (int) r;
00171 
00172        MAKE_STD_ZVAL(req);
00173        object_init_ex(req, apacherequest_class_entry);
00174        zend_hash_index_update(Z_OBJPROP_P(req), 0, &addr, sizeof(zval *), NULL);
00175 
00176        return req;
00177 }
00178 /* }}} */
00179 
00180 /* {{{ apache_request_read_string_slot()
00181  */
00182 static void apache_request_read_string_slot(int offset, INTERNAL_FUNCTION_PARAMETERS)
00183 {
00184        zval *id;
00185        request_rec *r;
00186        char *s;
00187 
00188        if (zend_parse_parameters_none() == FAILURE) {
00189               return;
00190        }
00191 
00192        APREQ_GET_REQUEST(id, r);
00193 
00194        s = *(char **)((char*)r + offset);
00195 
00196        if (s) {
00197               RETURN_STRING(s, 1);
00198        }
00199 
00200        RETURN_EMPTY_STRING();
00201 }
00202 /* }}} */
00203 
00204 
00205 /* {{{ apache_request_string_slot()
00206  */
00207 static void apache_request_string_slot(int offset, INTERNAL_FUNCTION_PARAMETERS)
00208 {
00209        zval *id;
00210        request_rec *r;
00211        char *old_value, *new_value = NULL;
00212        int new_value_len;
00213        char **target;
00214 
00215        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s", &new_value, &new_value_len) == FAILURE) {
00216               return;
00217        }
00218 
00219        APREQ_GET_REQUEST(id, r);
00220 
00221        target = (char **)((char*)r + offset);
00222        old_value = *target;
00223 
00224        if (new_value) {
00225               *target = ap_pstrdup(r->pool, new_value);
00226        }
00227 
00228        if (old_value) {
00229               RETURN_STRING(old_value, 1);
00230        }
00231 
00232        RETURN_EMPTY_STRING();
00233 }
00234 /* }}} */
00235 
00236 /* {{{ apache_request_read_int_slot()
00237  */
00238 static void apache_request_read_int_slot(int offset, INTERNAL_FUNCTION_PARAMETERS)
00239 {
00240        zval *id;
00241        request_rec *r;
00242        long l;
00243 
00244        if (zend_parse_parameters_none() == FAILURE) {
00245               return;
00246        }
00247 
00248        APREQ_GET_REQUEST(id, r);
00249 
00250        l = *(long *)((char*)r + offset);
00251 
00252        RETURN_LONG(l);
00253 }
00254 /* }}} */
00255 
00256 /* {{{ apache_request_int_slot()
00257  */
00258 static void apache_request_int_slot(int offset, INTERNAL_FUNCTION_PARAMETERS)
00259 {
00260        zval *id;
00261        request_rec *r;
00262        long old_value, new_value;
00263        long *target;
00264 
00265        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &new_value) == FAILURE) {
00266               return;
00267        }
00268 
00269        APREQ_GET_REQUEST(id, r);
00270 
00271        target = (long *)((char*)r + offset);
00272        old_value = *target;
00273 
00274        switch (ZEND_NUM_ARGS()) {
00275               case 0:
00276                      break;
00277               case 1:
00278                      *target = new_value;
00279                      break;
00280               default:
00281                      WRONG_PARAM_COUNT;
00282                      break;
00283        }
00284 
00285        RETURN_LONG(old_value);
00286 }
00287 /* }}} */
00288 
00289 
00290 /* {{{ access string slots of request rec
00291  */
00292 
00293 /* {{{ proto string ApacheRequest::filename([string new_filename])
00294  */
00295 PHP_FUNCTION(apache_request_filename)
00296 {
00297        apache_request_string_slot(offsetof(request_rec, filename), INTERNAL_FUNCTION_PARAM_PASSTHRU);
00298 }
00299 /* }}} */
00300 
00301 /* {{{ proto string ApacheRequest::uri([string new_uri])
00302  */
00303 PHP_FUNCTION(apache_request_uri)
00304 {
00305        apache_request_string_slot(offsetof(request_rec, uri), INTERNAL_FUNCTION_PARAM_PASSTHRU);
00306 }
00307 /* }}} */
00308 
00309 /* {{{ proto string ApacheRequest::unparsed_uri([string new_unparsed_uri])
00310  */
00311 PHP_FUNCTION(apache_request_unparsed_uri)
00312 {
00313        apache_request_string_slot(offsetof(request_rec, unparsed_uri), INTERNAL_FUNCTION_PARAM_PASSTHRU);
00314 }
00315 /* }}} */
00316 
00317 /* {{{ proto string ApacheRequest::path_info([string new_path_info])
00318  */
00319 PHP_FUNCTION(apache_request_path_info)
00320 {
00321        apache_request_string_slot(offsetof(request_rec, path_info), INTERNAL_FUNCTION_PARAM_PASSTHRU);
00322 }
00323 /* }}} */
00324 
00325 /* {{{ proto string ApacheRequest::args([string new_args])
00326  */
00327 PHP_FUNCTION(apache_request_args)
00328 {
00329        apache_request_string_slot(offsetof(request_rec, args), INTERNAL_FUNCTION_PARAM_PASSTHRU);
00330 }
00331 /* }}} */
00332 
00333 /* {{{ proto string ApacheRequest::boundary()
00334  */
00335 PHP_FUNCTION(apache_request_boundary)
00336 {
00337        apache_request_read_string_slot(offsetof(request_rec, boundary), INTERNAL_FUNCTION_PARAM_PASSTHRU);
00338 }
00339 /* }}} */
00340 
00341 
00342 /* {{{ proto string ApacheRequest::content_type([string new_type])
00343  */
00344 PHP_FUNCTION(apache_request_content_type)
00345 {
00346        apache_request_string_slot(offsetof(request_rec, content_type), INTERNAL_FUNCTION_PARAM_PASSTHRU);
00347 }
00348 /* }}} */
00349 
00350 /* {{{ proto string ApacheRequest::content_encoding([string new_encoding])
00351  */
00352 PHP_FUNCTION(apache_request_content_encoding)
00353 {
00354        apache_request_string_slot(offsetof(request_rec, content_encoding), INTERNAL_FUNCTION_PARAM_PASSTHRU);
00355 }
00356 /* }}} */
00357 
00358 /* {{{ proto string ApacheRequest::handler([string new_handler])
00359  */
00360 PHP_FUNCTION(apache_request_handler)
00361 {
00362        apache_request_string_slot(offsetof(request_rec, handler), INTERNAL_FUNCTION_PARAM_PASSTHRU);
00363 }
00364 /* }}} */
00365 
00366 /* {{{ proto string ApacheRequest::the_request()
00367  */
00368 PHP_FUNCTION(apache_request_the_request)
00369 {
00370        apache_request_read_string_slot(offsetof(request_rec, the_request), INTERNAL_FUNCTION_PARAM_PASSTHRU);
00371 }
00372 /* }}} */
00373 
00374 /* {{{ proto string ApacheRequest::protocol()
00375  */
00376 PHP_FUNCTION(apache_request_protocol)
00377 {
00378        apache_request_read_string_slot(offsetof(request_rec, protocol), INTERNAL_FUNCTION_PARAM_PASSTHRU);
00379 }
00380 /* }}} */
00381 
00382 /* {{{ proto string ApacheRequest::hostname()
00383  */
00384 PHP_FUNCTION(apache_request_hostname)
00385 {
00386        apache_request_read_string_slot(offsetof(request_rec, hostname), INTERNAL_FUNCTION_PARAM_PASSTHRU);
00387 }
00388 /* }}} */
00389 
00390 /* {{{ proto string ApacheRequest::status_line([string new_status_line])
00391  */
00392 PHP_FUNCTION(apache_request_status_line)
00393 {
00394        apache_request_string_slot(offsetof(request_rec, status_line), INTERNAL_FUNCTION_PARAM_PASSTHRU);
00395 }
00396 /* }}} */
00397 
00398 /* {{{ proto string ApacheRequest::method()
00399  */
00400 PHP_FUNCTION(apache_request_method)
00401 {
00402        apache_request_read_string_slot(offsetof(request_rec, method), INTERNAL_FUNCTION_PARAM_PASSTHRU);
00403 }
00404 /* }}} */
00405 
00406 /* }}} access string slots of request rec */
00407 
00408 /* {{{ access int slots of request_rec
00409  */
00410 
00411 /* {{{ proto int ApacheRequest::proto_num()
00412  */
00413 PHP_FUNCTION(apache_request_proto_num)
00414 {
00415        apache_request_read_int_slot(offsetof(request_rec, proto_num), INTERNAL_FUNCTION_PARAM_PASSTHRU);
00416 }
00417 /* }}} */
00418 
00419 /* {{{ proto int ApacheRequest::assbackwards()
00420  */
00421 PHP_FUNCTION(apache_request_assbackwards)
00422 {
00423        apache_request_read_int_slot(offsetof(request_rec, assbackwards), INTERNAL_FUNCTION_PARAM_PASSTHRU);
00424 }
00425 /* }}} */
00426 
00427 
00428 /* {{{ proto int ApacheRequest::proxyreq([int new_proxyreq])
00429  */
00430 PHP_FUNCTION(apache_request_proxyreq)
00431 {
00432        apache_request_int_slot(offsetof(request_rec, proxyreq), INTERNAL_FUNCTION_PARAM_PASSTHRU);
00433 }
00434 /* }}} */
00435 
00436 /* {{{ proto int ApacheRequest::chunked()
00437  */
00438 PHP_FUNCTION(apache_request_chunked)
00439 {
00440        apache_request_read_int_slot(offsetof(request_rec, chunked), INTERNAL_FUNCTION_PARAM_PASSTHRU);
00441 }
00442 /* }}} */
00443 
00444 
00445 /* {{{ proto int ApacheRequest::header_only()
00446  */
00447 PHP_FUNCTION(apache_request_header_only)
00448 {
00449        apache_request_read_int_slot(offsetof(request_rec, header_only), INTERNAL_FUNCTION_PARAM_PASSTHRU);
00450 }
00451 /* }}} */
00452 
00453 /* {{{ proto int ApacheRequest::request_time()
00454  */
00455 PHP_FUNCTION(apache_request_request_time)
00456 {
00457        apache_request_read_int_slot(offsetof(request_rec, request_time), INTERNAL_FUNCTION_PARAM_PASSTHRU);
00458 }
00459 /* }}} */
00460 
00461 /* {{{ proto int ApacheRequest::status([int new_status])
00462  */
00463 PHP_FUNCTION(apache_request_status)
00464 {
00465        apache_request_int_slot(offsetof(request_rec, status), INTERNAL_FUNCTION_PARAM_PASSTHRU);
00466 }
00467 /* }}} */
00468 
00469 /* {{{ proto int ApacheRequest::method_number([int method_number])
00470  */
00471 PHP_FUNCTION(apache_request_method_number)
00472 {
00473        apache_request_read_int_slot(offsetof(request_rec, method_number), INTERNAL_FUNCTION_PARAM_PASSTHRU);
00474 }
00475 /* }}} */
00476 
00477 /* {{{ proto int ApacheRequest::allowed([int allowed])
00478  */
00479 PHP_FUNCTION(apache_request_allowed)
00480 {
00481        apache_request_int_slot(offsetof(request_rec, allowed), INTERNAL_FUNCTION_PARAM_PASSTHRU);
00482 }
00483 /* }}} */
00484 
00485 /* {{{ proto int ApacheRequest::bytes_sent()
00486  */
00487 PHP_FUNCTION(apache_request_bytes_sent)
00488 {
00489        apache_request_read_int_slot(offsetof(request_rec, bytes_sent), INTERNAL_FUNCTION_PARAM_PASSTHRU);
00490 }
00491 /* }}} */
00492 
00493 /* {{{ proto int ApacheRequest::mtime()
00494  */
00495 PHP_FUNCTION(apache_request_mtime)
00496 {
00497        apache_request_read_int_slot(offsetof(request_rec, mtime), INTERNAL_FUNCTION_PARAM_PASSTHRU);
00498 }
00499 /* }}} */
00500 
00501 /* {{{ proto int ApacheRequest::content_length([int new_content_length])
00502  */
00503 PHP_FUNCTION(apache_request_content_length)
00504 {
00505        zval *id;
00506        long zlen;
00507        request_rec *r;
00508 
00509        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &zlen) == FAILURE) {
00510               return;
00511        }
00512 
00513        if (ZEND_NUM_ARGS() == 0) {
00514               apache_request_read_int_slot(offsetof(request_rec, clength), INTERNAL_FUNCTION_PARAM_PASSTHRU);
00515        } else {
00516               APREQ_GET_REQUEST(id, r);
00517 
00518               (void)ap_set_content_length(r, zlen);
00519               RETURN_TRUE;
00520        }
00521 }
00522 /* }}} */
00523 
00524 /* {{{ proto int ApacheRequest::remaining()
00525  */
00526 PHP_FUNCTION(apache_request_remaining)
00527 {
00528        apache_request_read_int_slot(offsetof(request_rec, remaining), INTERNAL_FUNCTION_PARAM_PASSTHRU);
00529 }
00530 /* }}} */
00531 
00532 /* {{{ proto int ApacheRequest::no_cache()
00533  */
00534 PHP_FUNCTION(apache_request_no_cache)
00535 {
00536        apache_request_int_slot(offsetof(request_rec, no_cache), INTERNAL_FUNCTION_PARAM_PASSTHRU);
00537 }
00538 /* }}} */
00539 
00540 /* {{{ proto int ApacheRequest::no_local_copy()
00541  */
00542 PHP_FUNCTION(apache_request_no_local_copy)
00543 {
00544        apache_request_int_slot(offsetof(request_rec, no_local_copy), INTERNAL_FUNCTION_PARAM_PASSTHRU);
00545 }
00546 /* }}} */
00547 
00548 /* {{{ proto int ApacheRequest::read_body()
00549  */
00550 PHP_FUNCTION(apache_request_read_body)
00551 {
00552        apache_request_int_slot(offsetof(request_rec, read_body), INTERNAL_FUNCTION_PARAM_PASSTHRU);
00553 }
00554 /* }}} */
00555 
00556 
00557 /* }}} access int slots of request_rec */
00558 
00559 
00560 /* {{{ proto array apache_request_headers_in()
00561  * fetch all incoming request headers
00562  */
00563 PHP_FUNCTION(apache_request_headers_in)
00564 {
00565        zval *id;
00566        request_rec *r;
00567        
00568        APREQ_GET_REQUEST(id, r);
00569 
00570        apache_table_to_zval(r->headers_in, 0, return_value);
00571 }
00572 /* }}} */
00573 
00574 
00575 /* {{{ add_header_to_table
00576 */
00577 static void add_header_to_table(table *t, INTERNAL_FUNCTION_PARAMETERS)
00578 {
00579        zval *first = NULL;
00580        zval *second = NULL;
00581        zval **entry, **value;
00582        char *string_key;
00583        uint string_key_len;
00584        ulong num_key;
00585        
00586        zend_bool replace = 0;
00587        HashPosition pos;
00588 
00589        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|zb", &first, &second, &replace) == FAILURE) {
00590               RETURN_FALSE;
00591        }
00592 
00593        if (Z_TYPE_P(first) == IS_ARRAY) {
00594               switch(ZEND_NUM_ARGS()) {
00595                      case 1:
00596                      case 3:
00597                             zend_hash_internal_pointer_reset_ex(Z_ARRVAL_P(first), &pos);
00598                             while (zend_hash_get_current_data_ex(Z_ARRVAL_P(first), (void **)&entry, &pos) == SUCCESS) {
00599                                    switch(zend_hash_get_current_key_ex(Z_ARRVAL_P(first), &string_key, &string_key_len, &num_key, 0, &pos)) {
00600                                           case HASH_KEY_IS_STRING:
00601                                                  if (zend_hash_find(Z_ARRVAL_P(first), string_key, string_key_len, (void **)&value) == FAILURE) {
00602                                                         zend_hash_move_forward_ex(Z_ARRVAL_P(first), &pos);
00603                                                         continue;
00604                                                  }
00605                                                  if (!value) {
00606                                                         zend_hash_move_forward_ex(Z_ARRVAL_P(first), &pos);
00607                                                         continue;
00608                                                  }
00609 
00610                                                  convert_to_string_ex(value);
00611                                                  if (replace) {
00612                                                         ap_table_set(t, string_key, Z_STRVAL_PP(value));
00613                                                  } else {
00614                                                         ap_table_merge(t, string_key, Z_STRVAL_PP(value));
00615                                                  }
00616                                                  break;
00617                                           case HASH_KEY_IS_LONG:
00618                                           default:
00619                                                  php_error(E_WARNING, "%s(): Can only add STRING keys to headers!", get_active_function_name(TSRMLS_C));
00620                                                  break;
00621                                    }
00622 
00623                                    zend_hash_move_forward_ex(Z_ARRVAL_P(first), &pos);
00624                             }
00625                             break;
00626                      default:
00627                             WRONG_PARAM_COUNT;
00628                             break;
00629               }
00630        } else if (Z_TYPE_P(first) == IS_STRING) {
00631               switch(ZEND_NUM_ARGS()) {
00632                      case 2:
00633                      case 3:
00634                             convert_to_string_ex(&second);
00635                             if (replace) {
00636                                    ap_table_set(t, Z_STRVAL_P(first), Z_STRVAL_P(second));
00637                             } else {
00638                                    ap_table_merge(t, Z_STRVAL_P(first), Z_STRVAL_P(second));
00639                             }
00640                             break;
00641                      default:
00642                             WRONG_PARAM_COUNT;
00643                             break;
00644               }
00645        } else {
00646               RETURN_FALSE;
00647        }
00648 }
00649 
00650 /* }}} */
00651 
00652 
00653 /* {{{ proto array apache_request_headers_out([{string name|array list} [, string value [, bool replace = false]]])
00654  * fetch all outgoing request headers
00655  */
00656 PHP_FUNCTION(apache_request_headers_out)
00657 {
00658        zval *id;
00659        request_rec *r;
00660        
00661        APREQ_GET_REQUEST(id, r);
00662 
00663        if (ZEND_NUM_ARGS() > 0) {
00664               add_header_to_table(r->headers_out, INTERNAL_FUNCTION_PARAM_PASSTHRU);
00665        }
00666 
00667        apache_table_to_zval(r->headers_out, 0, return_value);
00668 }
00669 /* }}} */
00670 
00671 
00672 /* {{{ proto array apache_request_err_headers_out([{string name|array list} [, string value [, bool replace = false]]])
00673  * fetch all headers that go out in case of an error or a subrequest
00674  */
00675 PHP_FUNCTION(apache_request_err_headers_out)
00676 {
00677        zval *id;
00678        request_rec *r;
00679        
00680        APREQ_GET_REQUEST(id, r);
00681 
00682        if (ZEND_NUM_ARGS() > 0) {
00683               add_header_to_table(r->err_headers_out, INTERNAL_FUNCTION_PARAM_PASSTHRU);
00684        }
00685 
00686        apache_table_to_zval(r->err_headers_out, 0, return_value);
00687 }
00688 /* }}} */
00689 
00690 
00691 /* {{{ proxy functions for the ap_* functions family
00692  */
00693 
00694 /* {{{ proto int apache_request_server_port()
00695  */
00696 PHP_FUNCTION(apache_request_server_port)
00697 {
00698        zval *id;
00699        request_rec *r;
00700 
00701        if (zend_parse_parameters_none() == FAILURE) {
00702               return;
00703        }
00704 
00705        APREQ_GET_REQUEST(id, r);
00706 
00707        RETURN_LONG(ap_get_server_port(r));
00708 }
00709 /* }}} */
00710 
00711 /* {{{ proto int apache_request_remote_host([int type])
00712  */
00713 PHP_FUNCTION(apache_request_remote_host)
00714 {
00715        zval *id;
00716        long type = 0;
00717        request_rec *r;
00718        char *res;
00719 
00720        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &type) == FAILURE) {
00721               return;
00722        }
00723 
00724        if (!type) {
00725               type = REMOTE_NAME;
00726        }
00727 
00728        APREQ_GET_REQUEST(id, r);
00729 
00730        res = (char *)ap_get_remote_host(r->connection, r->per_dir_config, (int)type);
00731 
00732        if (res) {
00733               RETURN_STRING(res, 1);
00734        }
00735 
00736        RETURN_EMPTY_STRING();
00737 }
00738 /* }}} */
00739 
00740 /* {{{ proto long apache_request_update_mtime([int dependency_mtime])
00741  */
00742 PHP_FUNCTION(apache_request_update_mtime)
00743 {
00744        zval *id;
00745        request_rec *r;
00746        long mtime = 0;
00747 
00748        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &mtime) == FAILURE) {
00749               return;
00750        }
00751 
00752        APREQ_GET_REQUEST(id, r);
00753 
00754        RETURN_LONG(ap_update_mtime(r, (int) mtime));
00755 }
00756 /* }}} */
00757 
00758 
00759 /* {{{ proto void apache_request_set_etag()
00760  */
00761 PHP_FUNCTION(apache_request_set_etag)
00762 {
00763        zval *id;
00764        request_rec *r;
00765 
00766        if (zend_parse_parameters_none() == FAILURE) {
00767               return;
00768        }
00769 
00770        APREQ_GET_REQUEST(id, r);
00771 
00772        ap_set_etag(r);
00773        RETURN_TRUE;
00774 }
00775 /* }}} */
00776 
00777 /* {{{ proto void apache_request_set_last_modified()
00778  */
00779 PHP_FUNCTION(apache_request_set_last_modified)
00780 {
00781        zval *id;
00782        request_rec *r;
00783 
00784        if (zend_parse_parameters_none() == FAILURE) {
00785               return;
00786        }
00787 
00788        APREQ_GET_REQUEST(id, r);
00789 
00790        ap_set_last_modified(r);
00791        RETURN_TRUE;
00792 }
00793 /* }}} */
00794 
00795 /* {{{ proto long apache_request_meets_conditions()
00796  */
00797 PHP_FUNCTION(apache_request_meets_conditions)
00798 {
00799        zval *id;
00800        request_rec *r;
00801 
00802        if (zend_parse_parameters_none() == FAILURE) {
00803               return;
00804        }
00805 
00806        APREQ_GET_REQUEST(id, r);
00807 
00808        RETURN_LONG(ap_meets_conditions(r));
00809 }
00810 /* }}} */
00811 
00812 /* {{{ proto long apache_request_discard_request_body()
00813  */
00814 PHP_FUNCTION(apache_request_discard_request_body)
00815 {
00816        zval *id;
00817        request_rec *r;
00818 
00819        if (zend_parse_parameters_none() == FAILURE) {
00820               return;
00821        }
00822 
00823        APREQ_GET_REQUEST(id, r);
00824 
00825        RETURN_LONG(ap_discard_request_body(r));
00826 }
00827 /* }}} */
00828 
00829 /* {{{ proto long apache_request_satisfies()
00830  */
00831 PHP_FUNCTION(apache_request_satisfies)
00832 {
00833        zval *id;
00834        request_rec *r;
00835 
00836        if (zend_parse_parameters_none() == FAILURE) {
00837               return;
00838        }
00839 
00840        APREQ_GET_REQUEST(id, r);
00841 
00842        RETURN_LONG(ap_satisfies(r));
00843 }
00844 /* }}} */
00845 
00846 
00847 /* {{{ proto bool apache_request_is_initial_req()
00848  */
00849 PHP_FUNCTION(apache_request_is_initial_req)
00850 {
00851        zval *id;
00852        request_rec *r;
00853 
00854        if (zend_parse_parameters_none() == FAILURE) {
00855               return;
00856        }
00857 
00858        APREQ_GET_REQUEST(id, r);
00859 
00860        RETURN_BOOL(ap_is_initial_req(r));
00861 }
00862 /* }}} */
00863 
00864 /* {{{ proto bool apache_request_some_auth_required()
00865  */
00866 PHP_FUNCTION(apache_request_some_auth_required)
00867 {
00868        zval *id;
00869        request_rec *r;
00870 
00871        if (zend_parse_parameters_none() == FAILURE) {
00872               return;
00873        }
00874 
00875        APREQ_GET_REQUEST(id, r);
00876 
00877        RETURN_BOOL(ap_some_auth_required(r));
00878 }
00879 /* }}} */
00880 
00881 /* {{{ proto string apache_request_auth_type()
00882  */
00883 PHP_FUNCTION(apache_request_auth_type)
00884 {
00885        zval *id;
00886        request_rec *r;
00887        char *t;
00888 
00889        if (zend_parse_parameters_none() == FAILURE) {
00890               return;
00891        }
00892 
00893        APREQ_GET_REQUEST(id, r);
00894 
00895        t = (char *)ap_auth_type(r);
00896        if (!t) {
00897               RETURN_NULL();
00898        }
00899 
00900        RETURN_STRING(t, 1);
00901 }
00902 /* }}} */
00903 
00904 /* {{{ proto string apache_request_auth_name()
00905  */
00906 PHP_FUNCTION(apache_request_auth_name)
00907 {
00908        zval *id;
00909        request_rec *r;
00910        char *t;
00911 
00912        if (zend_parse_parameters_none() == FAILURE) {
00913               return;
00914        }
00915 
00916        APREQ_GET_REQUEST(id, r);
00917 
00918        t = (char *)ap_auth_name(r);
00919        if (!t) {
00920               RETURN_NULL();
00921        }
00922 
00923        RETURN_STRING(t, 1);
00924 }
00925 /* }}} */
00926 
00927 /* {{{ proto apache_request_basic_auth_pw()
00928  */
00929 PHP_FUNCTION(apache_request_basic_auth_pw)
00930 {
00931        zval *id, *zpw;
00932        request_rec *r;
00933        const char *pw;
00934        long status;
00935 
00936        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &zpw) == FAILURE) {
00937            return;
00938        }
00939 
00940        if (!PZVAL_IS_REF(zpw)) {
00941            zend_error(E_WARNING, "Parameter wasn't passed by reference");
00942            RETURN_NULL();
00943        }
00944 
00945        APREQ_GET_REQUEST(id, r);
00946 
00947        pw = NULL;
00948        status = ap_get_basic_auth_pw(r, &pw);
00949        if (status == OK && pw) {
00950               ZVAL_STRING(zpw, (char *)pw, 1);
00951        } else {
00952               ZVAL_NULL(zpw);
00953        }
00954        RETURN_LONG(status);
00955 }
00956 /* }}} */
00957 
00958 
00959 /* http_protocol.h */
00960 
00961 PHP_FUNCTION(apache_request_send_http_header)
00962 {
00963     zval *id;
00964     request_rec *r;
00965     char *type = NULL;
00966     int typelen;
00967 
00968        if (zend_parse_parameters(ZEND_NUM_ARGS()  TSRMLS_CC, "|s", &type, &typelen) == FAILURE) {
00969         return;
00970        }
00971 
00972     APREQ_GET_REQUEST(id, r);
00973     if(type) {
00974         r->content_type = pstrdup(r->pool, type);
00975     }
00976     ap_send_http_header(r);
00977     SG(headers_sent) = 1;
00978     AP(headers_sent) = 1;
00979     RETURN_TRUE;
00980 }
00981 
00982 PHP_FUNCTION(apache_request_basic_http_header)
00983 {
00984     zval *id;
00985     request_rec *r;
00986 
00987        if (zend_parse_parameters_none() == FAILURE) {
00988               return;
00989        }
00990 
00991     APREQ_GET_REQUEST(id, r);
00992 
00993     ap_basic_http_header((request_rec *)SG(server_context));
00994     SG(headers_sent) = 1;
00995     AP(headers_sent) = 1;
00996     RETURN_TRUE;
00997 }
00998 
00999 PHP_FUNCTION(apache_request_send_http_trace)
01000 {
01001     zval *id;
01002     request_rec *r;
01003 
01004        if (zend_parse_parameters_none() == FAILURE) {
01005               return;
01006        }
01007        
01008     APREQ_GET_REQUEST(id, r);
01009 
01010     ap_send_http_trace((request_rec *)SG(server_context));
01011     SG(headers_sent) = 1;
01012     AP(headers_sent) = 1;
01013     RETURN_TRUE;
01014 }
01015 
01016 PHP_FUNCTION(apache_request_send_http_options)
01017 {
01018     zval *id;
01019     request_rec *r;
01020 
01021        if (zend_parse_parameters_none() == FAILURE) {
01022               return;
01023        }
01024 
01025     APREQ_GET_REQUEST(id, r);
01026 
01027     ap_send_http_options((request_rec *)SG(server_context));
01028     SG(headers_sent) = 1;
01029     AP(headers_sent) = 1;
01030     RETURN_TRUE;
01031 }
01032 
01033 PHP_FUNCTION(apache_request_send_error_response)
01034 {
01035     zval *id;
01036     request_rec *r;
01037        long rec = 0;
01038 
01039        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|l", &rec) == FAILURE) {
01040               return;
01041        }
01042 
01043     APREQ_GET_REQUEST(id, r);
01044        ap_send_error_response(r, (int) rec);
01045     RETURN_TRUE;
01046 }
01047 
01048 PHP_FUNCTION(apache_request_set_content_length)
01049 {
01050        long length;
01051     zval *id;
01052     request_rec *r;
01053 
01054        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l", &length) == FAILURE) {
01055               return;
01056        }
01057 
01058     APREQ_GET_REQUEST(id, r);
01059 
01060     ap_set_content_length(r, length);
01061     RETURN_TRUE;
01062 }
01063 
01064 PHP_FUNCTION(apache_request_set_keepalive)
01065 {
01066     zval *id;
01067     request_rec *r;
01068 
01069        if (zend_parse_parameters_none() == FAILURE) {
01070               return;
01071        }
01072        
01073     APREQ_GET_REQUEST(id, r);
01074     ap_set_keepalive(r);
01075     RETURN_TRUE;
01076 }
01077 
01078 /* This stuff should use streams or however this is implemented now
01079 
01080 PHP_FUNCTION(apache_request_send_fd) 
01081 {
01082 }
01083 
01084 PHP_FUNCTION(apache_request_send_fd_length)
01085 {
01086 }
01087 */
01088 
01089 /* These are for overriding default output behaviour */
01090 PHP_FUNCTION(apache_request_rputs)
01091 {
01092     char *buffer;
01093        int buffer_len;
01094     zval *id;
01095     request_rec *r;
01096 
01097        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &buffer, &buffer_len) == FAILURE) {
01098               return;
01099        }
01100 
01101     APREQ_GET_REQUEST(id, r);
01102     ap_rwrite(buffer, buffer_len, (request_rec*)SG(server_context));
01103 }
01104 
01105 /* This stuff would be useful for custom POST handlers, 
01106    which should be supported.  Probably by not using
01107    sapi_activate at all inside a phpResponseHandler
01108    and instead using a builtin composed of the below
01109    calls as a apache_read_request_body() and allow
01110    people to custom craft their own.
01111     
01112 PHP_FUNCTION(apache_request_setup_client_block)
01113 {
01114 }
01115 
01116 PHP_FUNCTION(apache_request_should_client_block)
01117 {
01118 }
01119 
01120 PHP_FUNCTION(apache_request_get_client_block)
01121 {
01122 }
01123 
01124 PHP_FUNCTION(apache_request_discard_request_body)
01125 {
01126 }
01127 */
01128 
01129 /* http_log.h */
01130 
01131 /* {{{ proto boolean apache_request_log_error(string message, [long facility])
01132  */
01133 PHP_FUNCTION(apache_request_log_error)
01134 {
01135     zval *id;
01136        char *z_errstr;
01137        int z_errstr_len;
01138     long facility = APLOG_ERR;
01139     request_rec *r;
01140 
01141        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|l", &z_errstr, &z_errstr_len, &facility) == FAILURE) {
01142               return;
01143        }
01144 
01145     APREQ_GET_REQUEST(id, r);
01146        ap_log_error(APLOG_MARK, (int) facility, r->server, "%s", z_errstr);
01147     RETURN_TRUE;
01148 }
01149 /* }}} */
01150 /* http_main.h */
01151 
01152 /* {{{ proto object apache_request_sub_req_lookup_uri(string uri)
01153     Returns sub-request for the specified uri.  You would
01154     need to run it yourself with run()
01155 */
01156 PHP_FUNCTION(apache_request_sub_req_lookup_uri)
01157 {
01158     zval *id;
01159        char *file;
01160        int file_len;
01161     request_rec *r, *sub_r;
01162 
01163        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &file, &file_len) == FAILURE) {
01164               return;
01165        }
01166 
01167     APREQ_GET_REQUEST(id, r);
01168     sub_r = ap_sub_req_lookup_uri(file, r);
01169 
01170     if (!sub_r) {
01171         RETURN_FALSE;
01172     }
01173     return_value = php_apache_request_new(sub_r);
01174 }
01175 /* }}} */
01176 
01177 /* {{{ proto object apache_request_sub_req_lookup_file(string file)
01178     Returns sub-request for the specified file.  You would
01179     need to run it yourself with run().
01180 */
01181 PHP_FUNCTION(apache_request_sub_req_lookup_file)
01182 {
01183     zval *id;
01184        char *file;
01185        int file_len;
01186     request_rec *r, *sub_r;
01187 
01188        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &file, &file_len) == FAILURE) {
01189               return;
01190        }
01191 
01192     APREQ_GET_REQUEST(id, r);
01193 
01194     sub_r = ap_sub_req_lookup_file(file, r);
01195 
01196     if (!sub_r) {
01197         RETURN_FALSE;
01198     }
01199     return_value = php_apache_request_new(sub_r);
01200 }
01201 /* }}} */
01202 
01203 /* {{{ proto object apache_request_sub_req_method_uri(string method, string uri)
01204     Returns sub-request for the specified file.  You would
01205     need to run it yourself with run().
01206 */
01207 PHP_FUNCTION(apache_request_sub_req_method_uri)
01208 {
01209     zval *id;
01210        char *file, *method;
01211        int file_len, method_len;
01212     request_rec *r, *sub_r;
01213 
01214        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &method, &method_len, &file, &file_len) == FAILURE) {
01215               return;
01216        }
01217 
01218     APREQ_GET_REQUEST(id, r);
01219 
01220     sub_r = ap_sub_req_method_uri(method, file, r);
01221 
01222     if (!sub_r) {
01223         RETURN_FALSE;
01224     }
01225     return_value = php_apache_request_new(sub_r);
01226 }
01227 /* }}} */
01228 
01229 /* {{{ proto long apache_request_run()
01230     This is a wrapper for ap_sub_run_req and ap_destory_sub_req.  It takes 
01231     sub_request, runs it, destroys it, and returns it's status.
01232 */
01233 PHP_FUNCTION(apache_request_run)
01234 {
01235     zval *id;
01236     request_rec *r;
01237     int status;
01238 
01239     if (zend_parse_parameters_none() == FAILURE) {
01240        return;
01241        }
01242 
01243     APREQ_GET_REQUEST(id, r);
01244     if (!r || ap_is_initial_req(r)) {
01245         RETURN_FALSE;
01246        }
01247     status = ap_run_sub_req(r);
01248     ap_destroy_sub_req(r);
01249     RETURN_LONG(status);
01250 }
01251 /* }}} */
01252 
01253 PHP_FUNCTION(apache_request_internal_redirect)
01254 {
01255     zval *id;
01256        char *new_uri;
01257        int new_uri_len;
01258     request_rec *r;
01259 
01260        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &new_uri, &new_uri_len) == FAILURE) {
01261               return;
01262        }
01263 
01264     APREQ_GET_REQUEST(id, r);
01265 
01266     ap_internal_redirect(new_uri, r);
01267 }
01268 
01269 PHP_FUNCTION(apache_request_send_header_field)
01270 {
01271        char *fieldname, *fieldval;
01272        int fieldname_len, fieldval_len;
01273     zval *id;
01274     request_rec *r;
01275 
01276        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss", &fieldname, &fieldname_len, &fieldval, &fieldval_len) == FAILURE) {
01277               return;
01278        }
01279 
01280     APREQ_GET_REQUEST(id, r);
01281 
01282     ap_send_header_field(r, fieldname, fieldval);
01283     SG(headers_sent) = 1;
01284     AP(headers_sent) = 1;
01285 }
01286 
01287 
01288 
01289 /* }}} */
01290 
01291 /* {{{ php_apache_request_class_functions
01292  */
01293 const static zend_function_entry php_apache_request_class_functions[] = {
01294        /* string slots */
01295        PHP_FALIAS(args,                                        apache_request_args,                      NULL)
01296        PHP_FALIAS(boundary,                             apache_request_boundary,                  NULL)
01297        PHP_FALIAS(content_encoding,                     apache_request_content_encoding,   NULL)
01298        PHP_FALIAS(content_type,                         apache_request_content_type,              NULL)
01299        PHP_FALIAS(filename,                             apache_request_filename,                  NULL)
01300        PHP_FALIAS(handler,                                     apache_request_handler,                          NULL)
01301        PHP_FALIAS(hostname,                             apache_request_hostname,                  NULL)
01302        PHP_FALIAS(method,                                      apache_request_method,                           NULL)
01303        PHP_FALIAS(path_info,                                   apache_request_path_info,                 NULL)
01304        PHP_FALIAS(protocol,                             apache_request_protocol,                  NULL)
01305        PHP_FALIAS(status_line,                                 apache_request_status_line,               NULL)
01306        PHP_FALIAS(the_request,                                 apache_request_the_request,               NULL)
01307        PHP_FALIAS(unparsed_uri,                         apache_request_unparsed_uri,              NULL)
01308        PHP_FALIAS(uri,                                                apache_request_uri,                              NULL)
01309 
01310        /* int slots */
01311        PHP_FALIAS(allowed,                                     apache_request_allowed,                          NULL)
01312        PHP_FALIAS(bytes_sent,                                  apache_request_bytes_sent,                NULL)
01313        PHP_FALIAS(chunked,                                     apache_request_chunked,                          NULL)
01314        PHP_FALIAS(content_length,                       apache_request_content_length,            NULL)
01315        PHP_FALIAS(header_only,                                 apache_request_header_only,               NULL)
01316        PHP_FALIAS(method_number,                        apache_request_method_number,             NULL)
01317        PHP_FALIAS(mtime,                                       apache_request_mtime,                            NULL)
01318        PHP_FALIAS(no_cache,                             apache_request_no_cache,                  NULL)
01319        PHP_FALIAS(no_local_copy,                        apache_request_no_local_copy,             NULL)
01320        PHP_FALIAS(proto_num,                                   apache_request_proto_num,                 NULL)
01321        PHP_FALIAS(proxyreq,                             apache_request_proxyreq,                  NULL)
01322        PHP_FALIAS(read_body,                                   apache_request_read_body,                 NULL)
01323        PHP_FALIAS(remaining,                                   apache_request_remaining,                 NULL)
01324        PHP_FALIAS(request_time,                         apache_request_request_time,              NULL)
01325        PHP_FALIAS(status,                                      apache_request_status,                           NULL)
01326 
01327        /* tables & arrays */
01328        PHP_FALIAS(headers_in,                                  apache_request_headers_in,                NULL)
01329        PHP_FALIAS(headers_out,                                 apache_request_headers_out,               NULL)
01330        PHP_FALIAS(err_headers_out,                      apache_request_err_headers_out,                  NULL)
01331 
01332 
01333        /* proxy functions for the ap_* functions family */
01334 #undef auth_name
01335 #undef auth_type
01336 #undef discard_request_body
01337 #undef is_initial_req
01338 #undef meets_conditions
01339 #undef satisfies
01340 #undef set_etag
01341 #undef set_last_modified
01342 #undef some_auth_required
01343 #undef update_mtime
01344 #undef send_http_header
01345 #undef send_header_field
01346 #undef basic_http_header
01347 #undef send_http_trace
01348 #undef send_http_options
01349 #undef send_error_response
01350 #undef set_content_length
01351 #undef set_keepalive
01352 #undef rputs
01353 #undef log_error
01354 #undef lookup_uri
01355 #undef lookup_file
01356 #undef method_uri
01357 #undef run
01358 #undef internal_redirect
01359        PHP_FALIAS(auth_name,                                   apache_request_auth_name,                        NULL)
01360        PHP_FALIAS(auth_type,                                   apache_request_auth_type,                        NULL)
01361        PHP_FALIAS(basic_auth_pw,                        apache_request_basic_auth_pw,                    NULL)
01362        PHP_FALIAS(discard_request_body,          apache_request_discard_request_body,      NULL)
01363        PHP_FALIAS(is_initial_req,                       apache_request_is_initial_req,                   NULL)
01364        PHP_FALIAS(meets_conditions,                     apache_request_meets_conditions,          NULL)
01365        PHP_FALIAS(remote_host,                                 apache_request_remote_host,                      NULL)
01366        PHP_FALIAS(satisfies,                                   apache_request_satisfies,                        NULL)
01367        PHP_FALIAS(server_port,                                 apache_request_server_port,                      NULL)
01368        PHP_FALIAS(set_etag,                             apache_request_set_etag,                         NULL)
01369        PHP_FALIAS(set_last_modified,                    apache_request_set_last_modified,         NULL)
01370        PHP_FALIAS(some_auth_required,                   apache_request_some_auth_required,        NULL)
01371        PHP_FALIAS(update_mtime,                         apache_request_update_mtime,                     NULL)
01372        PHP_FALIAS(send_http_header,                     apache_request_send_http_header,          NULL)
01373        PHP_FALIAS(basic_http_header,                    apache_request_basic_http_header,         NULL)
01374     PHP_FALIAS(send_header_field,           apache_request_send_header_field,       NULL)
01375        PHP_FALIAS(send_http_trace,                   apache_request_send_http_trace,                  NULL)
01376        PHP_FALIAS(send_http_options,                    apache_request_send_http_trace,               NULL)
01377        PHP_FALIAS(send_error_response,                  apache_request_send_error_response,           NULL)
01378     PHP_FALIAS(set_content_length,          apache_request_set_content_length,      NULL)
01379     PHP_FALIAS(set_keepalive,               apache_request_set_keepalive,           NULL)
01380     PHP_FALIAS(rputs,                       apache_request_rputs,                   NULL)
01381     PHP_FALIAS(log_error,                   apache_request_log_error,               NULL)
01382     PHP_FALIAS(lookup_uri,                  apache_request_sub_req_lookup_uri,      NULL)
01383     PHP_FALIAS(lookup_file,                 apache_request_sub_req_lookup_file,     NULL)
01384     PHP_FALIAS(method_uri,                  apache_request_sub_req_method_uri,      NULL)
01385     PHP_FALIAS(run,                         apache_request_run,                     NULL)
01386     PHP_FALIAS(internal_redirect,           apache_request_internal_redirect,       NULL)
01387        PHP_FE_END
01388 };
01389 /* }}} */
01390 
01391 
01392 static PHP_MINIT_FUNCTION(apache)
01393 {
01394        zend_class_entry ce;
01395 
01396 #ifdef ZTS
01397        ts_allocate_id(&php_apache_info_id, sizeof(php_apache_info_struct), (ts_allocate_ctor) php_apache_globals_ctor, NULL);
01398 #else
01399        php_apache_globals_ctor(&php_apache_info TSRMLS_CC);
01400 #endif
01401        REGISTER_INI_ENTRIES();
01402 
01403 
01404        le_apachereq = zend_register_list_destructors_ex(php_apache_request_free, NULL, "ApacheRequest", module_number);
01405        INIT_OVERLOADED_CLASS_ENTRY(ce, "ApacheRequest", php_apache_request_class_functions, NULL, NULL, NULL);
01406        apacherequest_class_entry = zend_register_internal_class_ex(&ce, NULL, NULL TSRMLS_CC);
01407 
01408        REGISTER_LONG_CONSTANT("OK",                            OK,                                CONST_CS | CONST_PERSISTENT);
01409        REGISTER_LONG_CONSTANT("DECLINED",               DECLINED,                   CONST_CS | CONST_PERSISTENT);
01410        REGISTER_LONG_CONSTANT("FORBIDDEN",                     FORBIDDEN,                  CONST_CS | CONST_PERSISTENT);
01411        REGISTER_LONG_CONSTANT("AUTH_REQUIRED",          AUTH_REQUIRED,              CONST_CS | CONST_PERSISTENT);
01412        REGISTER_LONG_CONSTANT("DONE",                          DONE,                       CONST_CS | CONST_PERSISTENT);
01413        REGISTER_LONG_CONSTANT("SERVER_ERROR",           SERVER_ERROR,        CONST_CS | CONST_PERSISTENT);
01414        REGISTER_LONG_CONSTANT("REDIRECT",               REDIRECT,                   CONST_CS | CONST_PERSISTENT);
01415        REGISTER_LONG_CONSTANT("BAD_REQUEST",            BAD_REQUEST,         CONST_CS | CONST_PERSISTENT);
01416        REGISTER_LONG_CONSTANT("NOT_FOUND",                     NOT_FOUND,                  CONST_CS | CONST_PERSISTENT);
01417     REGISTER_LONG_CONSTANT("HTTP_CONTINUE",     HTTP_CONTINUE,   CONST_CS | CONST_PERSISTENT);
01418     REGISTER_LONG_CONSTANT("HTTP_SWITCHING_PROTOCOLS",     HTTP_SWITCHING_PROTOCOLS,   CONST_CS | CONST_PERSISTENT);
01419     REGISTER_LONG_CONSTANT("HTTP_PROCESSING",     HTTP_PROCESSING,   CONST_CS | CONST_PERSISTENT);
01420     REGISTER_LONG_CONSTANT("HTTP_OK",     HTTP_OK,   CONST_CS | CONST_PERSISTENT);
01421     REGISTER_LONG_CONSTANT("HTTP_CREATED",     HTTP_CREATED,   CONST_CS | CONST_PERSISTENT);
01422     REGISTER_LONG_CONSTANT("HTTP_ACCEPTED",     HTTP_ACCEPTED,   CONST_CS | CONST_PERSISTENT);
01423     REGISTER_LONG_CONSTANT("HTTP_NON_AUTHORITATIVE",     HTTP_NON_AUTHORITATIVE,   CONST_CS | CONST_PERSISTENT);
01424     REGISTER_LONG_CONSTANT("HTTP_NO_CONTENT",     HTTP_NO_CONTENT,   CONST_CS | CONST_PERSISTENT);
01425     REGISTER_LONG_CONSTANT("HTTP_RESET_CONTENT",     HTTP_RESET_CONTENT,   CONST_CS | CONST_PERSISTENT);
01426     REGISTER_LONG_CONSTANT("HTTP_PARTIAL_CONTENT",     HTTP_PARTIAL_CONTENT,   CONST_CS | CONST_PERSISTENT);
01427     REGISTER_LONG_CONSTANT("HTTP_MULTI_STATUS",     HTTP_MULTI_STATUS,   CONST_CS | CONST_PERSISTENT);
01428     REGISTER_LONG_CONSTANT("HTTP_MULTIPLE_CHOICES",     HTTP_MULTIPLE_CHOICES,   CONST_CS | CONST_PERSISTENT);
01429     REGISTER_LONG_CONSTANT("HTTP_MOVED_PERMANENTLY",     HTTP_MOVED_PERMANENTLY,   CONST_CS | CONST_PERSISTENT);
01430     REGISTER_LONG_CONSTANT("HTTP_MOVED_TEMPORARILY",     HTTP_MOVED_TEMPORARILY,   CONST_CS | CONST_PERSISTENT);
01431     REGISTER_LONG_CONSTANT("HTTP_SEE_OTHER",     HTTP_SEE_OTHER,   CONST_CS | CONST_PERSISTENT);
01432     REGISTER_LONG_CONSTANT("HTTP_NOT_MODIFIED",     HTTP_NOT_MODIFIED,   CONST_CS | CONST_PERSISTENT);
01433     REGISTER_LONG_CONSTANT("HTTP_USE_PROXY",     HTTP_USE_PROXY,   CONST_CS | CONST_PERSISTENT);
01434     REGISTER_LONG_CONSTANT("HTTP_TEMPORARY_REDIRECT",     HTTP_TEMPORARY_REDIRECT,   CONST_CS | CONST_PERSISTENT);
01435     REGISTER_LONG_CONSTANT("HTTP_BAD_REQUEST",     HTTP_BAD_REQUEST,   CONST_CS | CONST_PERSISTENT);
01436     REGISTER_LONG_CONSTANT("HTTP_UNAUTHORIZED",     HTTP_UNAUTHORIZED,   CONST_CS | CONST_PERSISTENT);
01437     REGISTER_LONG_CONSTANT("HTTP_PAYMENT_REQUIRED",     HTTP_PAYMENT_REQUIRED,   CONST_CS | CONST_PERSISTENT);
01438     REGISTER_LONG_CONSTANT("HTTP_FORBIDDEN",     HTTP_FORBIDDEN,   CONST_CS | CONST_PERSISTENT);
01439     REGISTER_LONG_CONSTANT("HTTP_NOT_FOUND",     HTTP_NOT_FOUND,   CONST_CS | CONST_PERSISTENT);
01440     REGISTER_LONG_CONSTANT("HTTP_METHOD_NOT_ALLOWED",     HTTP_METHOD_NOT_ALLOWED,   CONST_CS | CONST_PERSISTENT);
01441     REGISTER_LONG_CONSTANT("HTTP_NOT_ACCEPTABLE",     HTTP_NOT_ACCEPTABLE,   CONST_CS | CONST_PERSISTENT);
01442     REGISTER_LONG_CONSTANT("HTTP_PROXY_AUTHENTICATION_REQUIRED",     HTTP_PROXY_AUTHENTICATION_REQUIRED,   CONST_CS | CONST_PERSISTENT);
01443     REGISTER_LONG_CONSTANT("HTTP_REQUEST_TIME_OUT",     HTTP_REQUEST_TIME_OUT,   CONST_CS | CONST_PERSISTENT);
01444     REGISTER_LONG_CONSTANT("HTTP_CONFLICT",     HTTP_CONFLICT,   CONST_CS | CONST_PERSISTENT);
01445     REGISTER_LONG_CONSTANT("HTTP_GONE",     HTTP_GONE,   CONST_CS | CONST_PERSISTENT);REGISTER_LONG_CONSTANT("HTTP_LENGTH_REQUIRED",     HTTP_LENGTH_REQUIRED,   CONST_CS | CONST_PERSISTENT);
01446     REGISTER_LONG_CONSTANT("HTTP_PRECONDITION_FAILED",     HTTP_PRECONDITION_FAILED,   CONST_CS | CONST_PERSISTENT);
01447     REGISTER_LONG_CONSTANT("HTTP_REQUEST_ENTITY_TOO_LARGE",     HTTP_REQUEST_ENTITY_TOO_LARGE,   CONST_CS | CONST_PERSISTENT);
01448     REGISTER_LONG_CONSTANT("HTTP_REQUEST_URI_TOO_LARGE",     HTTP_REQUEST_URI_TOO_LARGE,   CONST_CS | CONST_PERSISTENT);
01449     REGISTER_LONG_CONSTANT("HTTP_UNSUPPORTED_MEDIA_TYPE",     HTTP_UNSUPPORTED_MEDIA_TYPE,   CONST_CS | CONST_PERSISTENT);
01450     REGISTER_LONG_CONSTANT("HTTP_RANGE_NOT_SATISFIABLE",     HTTP_RANGE_NOT_SATISFIABLE,   CONST_CS | CONST_PERSISTENT);
01451     REGISTER_LONG_CONSTANT("HTTP_EXPECTATION_FAILED",     HTTP_EXPECTATION_FAILED,   CONST_CS | CONST_PERSISTENT);
01452     REGISTER_LONG_CONSTANT("HTTP_UNPROCESSABLE_ENTITY",     HTTP_UNPROCESSABLE_ENTITY,   CONST_CS | CONST_PERSISTENT);
01453     REGISTER_LONG_CONSTANT("HTTP_LOCKED",     HTTP_LOCKED,   CONST_CS | CONST_PERSISTENT);
01454     REGISTER_LONG_CONSTANT("HTTP_FAILED_DEPENDENCY",     HTTP_FAILED_DEPENDENCY,   CONST_CS | CONST_PERSISTENT);
01455     REGISTER_LONG_CONSTANT("HTTP_INTERNAL_SERVER_ERROR",     HTTP_INTERNAL_SERVER_ERROR,   CONST_CS | CONST_PERSISTENT);
01456     REGISTER_LONG_CONSTANT("HTTP_NOT_IMPLEMENTED",     HTTP_NOT_IMPLEMENTED,   CONST_CS | CONST_PERSISTENT);
01457     REGISTER_LONG_CONSTANT("HTTP_BAD_GATEWAY",     HTTP_BAD_GATEWAY,   CONST_CS | CONST_PERSISTENT);
01458     REGISTER_LONG_CONSTANT("HTTP_SERVICE_UNAVAILABLE",     HTTP_SERVICE_UNAVAILABLE,   CONST_CS | CONST_PERSISTENT);
01459     REGISTER_LONG_CONSTANT("HTTP_GATEWAY_TIME_OUT",     HTTP_GATEWAY_TIME_OUT,   CONST_CS | CONST_PERSISTENT);
01460     REGISTER_LONG_CONSTANT("HTTP_VERSION_NOT_SUPPORTED",     HTTP_VERSION_NOT_SUPPORTED,   CONST_CS | CONST_PERSISTENT);
01461     REGISTER_LONG_CONSTANT("HTTP_VARIANT_ALSO_VARIES",     HTTP_VARIANT_ALSO_VARIES,   CONST_CS | CONST_PERSISTENT);
01462     REGISTER_LONG_CONSTANT("HTTP_INSUFFICIENT_STORAGE",     HTTP_INSUFFICIENT_STORAGE,   CONST_CS | CONST_PERSISTENT);
01463     REGISTER_LONG_CONSTANT("HTTP_NOT_EXTENDED",     HTTP_NOT_EXTENDED,   CONST_CS | CONST_PERSISTENT);
01464        REGISTER_LONG_CONSTANT("APLOG_EMERG",            APLOG_EMERG,         CONST_CS | CONST_PERSISTENT);
01465        REGISTER_LONG_CONSTANT("APLOG_ALERT",            APLOG_ALERT,         CONST_CS | CONST_PERSISTENT);
01466        REGISTER_LONG_CONSTANT("APLOG_CRIT",             APLOG_CRIT,                 CONST_CS | CONST_PERSISTENT);
01467        REGISTER_LONG_CONSTANT("APLOG_ERR",                     APLOG_ERR,           CONST_CS | CONST_PERSISTENT);
01468        REGISTER_LONG_CONSTANT("APLOG_WARNING",          APLOG_WARNING,              CONST_CS | CONST_PERSISTENT);
01469        REGISTER_LONG_CONSTANT("APLOG_NOTICE",           APLOG_NOTICE,        CONST_CS | CONST_PERSISTENT);
01470        REGISTER_LONG_CONSTANT("APLOG_INFO",             APLOG_INFO,                 CONST_CS | CONST_PERSISTENT);
01471        REGISTER_LONG_CONSTANT("APLOG_DEBUG",            APLOG_DEBUG,         CONST_CS | CONST_PERSISTENT);
01472        REGISTER_LONG_CONSTANT("M_GET",                         M_GET,                      CONST_CS | CONST_PERSISTENT);
01473        REGISTER_LONG_CONSTANT("M_PUT",                         M_PUT,                      CONST_CS | CONST_PERSISTENT);
01474        REGISTER_LONG_CONSTANT("M_POST",                 M_POST,                            CONST_CS | CONST_PERSISTENT);
01475        REGISTER_LONG_CONSTANT("M_DELETE",               M_DELETE,                   CONST_CS | CONST_PERSISTENT);
01476        REGISTER_LONG_CONSTANT("M_CONNECT",                     M_CONNECT,                  CONST_CS | CONST_PERSISTENT);
01477        REGISTER_LONG_CONSTANT("M_OPTIONS",                     M_OPTIONS,                  CONST_CS | CONST_PERSISTENT);
01478        REGISTER_LONG_CONSTANT("M_TRACE",                M_TRACE,                    CONST_CS | CONST_PERSISTENT);
01479        REGISTER_LONG_CONSTANT("M_PATCH",                M_PATCH,                    CONST_CS | CONST_PERSISTENT);
01480        REGISTER_LONG_CONSTANT("M_PROPFIND",             M_PROPFIND,                 CONST_CS | CONST_PERSISTENT);
01481        REGISTER_LONG_CONSTANT("M_PROPPATCH",            M_PROPPATCH,         CONST_CS | CONST_PERSISTENT);
01482        REGISTER_LONG_CONSTANT("M_MKCOL",                M_MKCOL,                    CONST_CS | CONST_PERSISTENT);
01483        REGISTER_LONG_CONSTANT("M_COPY",                 M_COPY,                            CONST_CS | CONST_PERSISTENT);
01484        REGISTER_LONG_CONSTANT("M_MOVE",                 M_MOVE,                            CONST_CS | CONST_PERSISTENT);
01485        REGISTER_LONG_CONSTANT("M_LOCK",                 M_LOCK,                            CONST_CS | CONST_PERSISTENT);
01486        REGISTER_LONG_CONSTANT("M_UNLOCK",               M_UNLOCK,                   CONST_CS | CONST_PERSISTENT);
01487        REGISTER_LONG_CONSTANT("M_INVALID",                     M_INVALID,                  CONST_CS | CONST_PERSISTENT);
01488 
01489        /* Possible values for request_rec.read_body (set by handling module):
01490         *    REQUEST_NO_BODY          Send 413 error if message has any body
01491         *    REQUEST_CHUNKED_ERROR    Send 411 error if body without Content-Length
01492         *    REQUEST_CHUNKED_DECHUNK  If chunked, remove the chunks for me.
01493         *    REQUEST_CHUNKED_PASS     Pass the chunks to me without removal.
01494         */
01495        REGISTER_LONG_CONSTANT("REQUEST_NO_BODY",               REQUEST_NO_BODY,                   CONST_CS | CONST_PERSISTENT);
01496        REGISTER_LONG_CONSTANT("REQUEST_CHUNKED_ERROR",  REQUEST_CHUNKED_ERROR,             CONST_CS | CONST_PERSISTENT);
01497        REGISTER_LONG_CONSTANT("REQUEST_CHUNKED_DECHUNK",       REQUEST_CHUNKED_DECHUNK,    CONST_CS | CONST_PERSISTENT);
01498        REGISTER_LONG_CONSTANT("REQUEST_CHUNKED_PASS",          REQUEST_CHUNKED_PASS,              CONST_CS | CONST_PERSISTENT);
01499        
01500        /* resolve types for remote_host() */
01501        REGISTER_LONG_CONSTANT("REMOTE_HOST",                   REMOTE_HOST,                CONST_CS | CONST_PERSISTENT);
01502        REGISTER_LONG_CONSTANT("REMOTE_NAME",                   REMOTE_NAME,                CONST_CS | CONST_PERSISTENT);
01503        REGISTER_LONG_CONSTANT("REMOTE_NOLOOKUP",        REMOTE_NOLOOKUP,            CONST_CS | CONST_PERSISTENT);
01504        REGISTER_LONG_CONSTANT("REMOTE_DOUBLE_REV",             REMOTE_DOUBLE_REV,          CONST_CS | CONST_PERSISTENT);
01505        
01506        return SUCCESS;
01507 }
01508 
01509 
01510 static PHP_MSHUTDOWN_FUNCTION(apache)
01511 {
01512        UNREGISTER_INI_ENTRIES();
01513        return SUCCESS;
01514 }
01515 
01516 zend_module_entry apache_module_entry = {
01517        STANDARD_MODULE_HEADER,
01518        "apache", 
01519        apache_functions, 
01520        PHP_MINIT(apache), 
01521        PHP_MSHUTDOWN(apache), 
01522        NULL, 
01523        NULL, 
01524        PHP_MINFO(apache), 
01525        NO_VERSION_YET,
01526        STANDARD_MODULE_PROPERTIES
01527 };
01528 
01529 /* {{{ proto bool apache_child_terminate(void)
01530    Terminate apache process after this request */
01531 PHP_FUNCTION(apache_child_terminate)
01532 {
01533 #ifndef MULTITHREAD
01534        if (AP(terminate_child)) {
01535               ap_child_terminate( ((request_rec *)SG(server_context)) );
01536               RETURN_TRUE;
01537        } else { /* tell them to get lost! */
01538               php_error(E_WARNING, "apache.child_terminate is disabled");
01539               RETURN_FALSE;
01540        }
01541 #else
01542               php_error(E_WARNING, "apache_child_terminate() is not supported in this build");
01543               RETURN_FALSE;
01544 #endif
01545 }
01546 /* }}} */
01547 
01548 /* {{{ proto string apache_note(string note_name [, string note_value])
01549    Get and set Apache request notes */
01550 PHP_FUNCTION(apache_note)
01551 {
01552        char *arg_name, *arg_val = NULL;
01553        int arg_name_len, arg_val_len;
01554        char *note_val;
01555 
01556        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s", &arg_name, &arg_name_len, &arg_val, &arg_val_len) == FAILURE) {
01557               return;
01558        }
01559 
01560        note_val = (char *) table_get(((request_rec *)SG(server_context))->notes, arg_name);
01561 
01562        if (arg_val) {
01563               table_set(((request_rec *)SG(server_context))->notes, arg_name, arg_val);
01564        }
01565 
01566        if (!note_val) {
01567               RETURN_FALSE;
01568        }
01569 
01570        RETURN_STRING(note_val, 1);
01571 }
01572 /* }}} */
01573 
01574 /* {{{ PHP_MINFO_FUNCTION
01575  */
01576 PHP_MINFO_FUNCTION(apache)
01577 {
01578        module *modp = NULL;
01579        char output_buf[128];
01580 #if !defined(WIN32) && !defined(WINNT)
01581        char name[64];
01582        char modulenames[1024];
01583        char *p;
01584 #endif
01585        server_rec *serv;
01586        extern char server_root[MAX_STRING_LEN];
01587        extern uid_t user_id;
01588        extern char *user_name;
01589        extern gid_t group_id;
01590        extern int max_requests_per_child;
01591 
01592        serv = ((request_rec *) SG(server_context))->server;
01593 
01594 
01595        php_info_print_table_start();
01596 
01597 #ifdef PHP_WIN32
01598        php_info_print_table_row(1, "Apache for Windows 95/NT");
01599        php_info_print_table_end();
01600        php_info_print_table_start();
01601 #elif defined(NETWARE)
01602        php_info_print_table_row(1, "Apache for NetWare");
01603        php_info_print_table_end();
01604        php_info_print_table_start();
01605 #else
01606        php_info_print_table_row(2, "APACHE_INCLUDE", PHP_APACHE_INCLUDE);
01607        php_info_print_table_row(2, "APACHE_TARGET", PHP_APACHE_TARGET);
01608 #endif
01609 
01610        php_info_print_table_row(2, "Apache Version", SERVER_VERSION);
01611 
01612 #ifdef APACHE_RELEASE
01613        snprintf(output_buf, sizeof(output_buf), "%d", APACHE_RELEASE);
01614        php_info_print_table_row(2, "Apache Release", output_buf);
01615 #endif
01616        snprintf(output_buf, sizeof(output_buf), "%d", MODULE_MAGIC_NUMBER);
01617        php_info_print_table_row(2, "Apache API Version", output_buf);
01618        snprintf(output_buf, sizeof(output_buf), "%s:%u", serv->server_hostname, serv->port);
01619        php_info_print_table_row(2, "Hostname:Port", output_buf);
01620 #if !defined(WIN32) && !defined(WINNT)
01621        snprintf(output_buf, sizeof(output_buf), "%s(%d)/%d", user_name, (int)user_id, (int)group_id);
01622        php_info_print_table_row(2, "User/Group", output_buf);
01623        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);
01624        php_info_print_table_row(2, "Max Requests", output_buf);
01625 #endif
01626        snprintf(output_buf, sizeof(output_buf), "Connection: %d - Keep-Alive: %d", serv->timeout, serv->keep_alive_timeout);
01627        php_info_print_table_row(2, "Timeouts", output_buf);
01628 #if !defined(WIN32) && !defined(WINNT)
01629 /*
01630        This block seems to be working on NetWare; But it seems to be showing
01631        all modules instead of just the loaded ones
01632 */
01633        php_info_print_table_row(2, "Server Root", server_root);
01634 
01635        strcpy(modulenames, "");
01636        for(modp = top_module; modp; modp = modp->next) {
01637               strlcpy(name, modp->name, sizeof(name));
01638               if ((p = strrchr(name, '.'))) {
01639                      *p='\0'; /* Cut off ugly .c extensions on module names */
01640               }
01641               strlcat(modulenames, name, sizeof(modulenames));
01642               if (modp->next) {
01643                      strlcat(modulenames, ", ", sizeof(modulenames));
01644               }
01645        }
01646        php_info_print_table_row(2, "Loaded Modules", modulenames);
01647 #endif
01648 
01649        php_info_print_table_end();
01650 
01651        DISPLAY_INI_ENTRIES();
01652 
01653        {
01654               register int i;
01655               array_header *arr;
01656               table_entry *elts;
01657               request_rec *r;
01658 
01659               r = ((request_rec *) SG(server_context));
01660               arr = table_elts(r->subprocess_env);
01661               elts = (table_entry *)arr->elts;
01662               
01663               SECTION("Apache Environment");
01664               php_info_print_table_start();      
01665               php_info_print_table_header(2, "Variable", "Value");
01666               for (i=0; i < arr->nelts; i++) {
01667                      php_info_print_table_row(2, elts[i].key, elts[i].val);
01668               }
01669               php_info_print_table_end(); 
01670        }
01671 
01672        {
01673               array_header *env_arr;
01674               table_entry *env;
01675               int i;
01676               request_rec *r;
01677               
01678               r = ((request_rec *) SG(server_context));
01679               SECTION("HTTP Headers Information");
01680               php_info_print_table_start();
01681               php_info_print_table_colspan_header(2, "HTTP Request Headers");
01682               php_info_print_table_row(2, "HTTP Request", r->the_request);
01683               env_arr = table_elts(r->headers_in);
01684               env = (table_entry *)env_arr->elts;
01685               for (i = 0; i < env_arr->nelts; ++i) {
01686                      if (env[i].key && (!PG(safe_mode) || (PG(safe_mode) && strncasecmp(env[i].key, "authorization", 13)))) {
01687                             php_info_print_table_row(2, env[i].key, env[i].val);
01688                      }
01689               }
01690               php_info_print_table_colspan_header(2, "HTTP Response Headers");
01691               env_arr = table_elts(r->headers_out);
01692               env = (table_entry *)env_arr->elts;
01693               for(i = 0; i < env_arr->nelts; ++i) {
01694                      if (env[i].key) {
01695                             php_info_print_table_row(2, env[i].key, env[i].val);
01696                      }
01697               }
01698               php_info_print_table_end();
01699        }
01700 }
01701 /* }}} */
01702 
01703 /* {{{ proto bool virtual(string filename)
01704    Perform an Apache sub-request */
01705 /* This function is equivalent to <!--#include virtual...-->
01706  * in mod_include. It does an Apache sub-request. It is useful
01707  * for including CGI scripts or .shtml files, or anything else
01708  * that you'd parse through Apache (for .phtml files, you'd probably
01709  * want to use <?Include>. This only works when PHP is compiled
01710  * as an Apache module, since it uses the Apache API for doing
01711  * sub requests.
01712  */
01713 PHP_FUNCTION(virtual)
01714 {
01715        char *filename;
01716        int filename_len;
01717        request_rec *rr = NULL;
01718 
01719        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &filename, &filename_len) == FAILURE) {
01720               return;
01721        }
01722 
01723        if (!(rr = sub_req_lookup_uri (filename, ((request_rec *) SG(server_context))))) {
01724               php_error(E_WARNING, "Unable to include '%s' - URI lookup failed", filename);
01725               if (rr)
01726                      destroy_sub_req (rr);
01727               RETURN_FALSE;
01728        }
01729 
01730        if (rr->status != 200) {
01731               php_error(E_WARNING, "Unable to include '%s' - error finding URI", filename);
01732               if (rr)
01733                      destroy_sub_req (rr);
01734               RETURN_FALSE;
01735        }
01736 
01737        php_end_ob_buffers(1 TSRMLS_CC);
01738        php_header(TSRMLS_C);
01739 
01740        if (run_sub_req(rr)) {
01741               php_error(E_WARNING, "Unable to include '%s' - request execution failed", filename);
01742               if (rr)
01743                      destroy_sub_req (rr);
01744               RETURN_FALSE;
01745        } 
01746 
01747        if (rr)
01748               destroy_sub_req (rr);
01749        RETURN_TRUE;
01750 }
01751 /* }}} */
01752 
01753 
01754 /* {{{ apache_table_to_zval(table *, int safe_mode, zval *return_value)
01755    Fetch all HTTP request headers */
01756 static void apache_table_to_zval(table *t, int safe_mode, zval *return_value)
01757 {
01758     array_header *env_arr;
01759     table_entry *tenv;
01760     int i;
01761        
01762     array_init(return_value);
01763     env_arr = table_elts(t);
01764     tenv = (table_entry *)env_arr->elts;
01765     for (i = 0; i < env_arr->nelts; ++i) {
01766               if (!tenv[i].key ||
01767                      (safe_mode && !strncasecmp(tenv[i].key, "authorization", 13))) {
01768                      continue;
01769               }
01770               if (add_assoc_string(return_value, tenv[i].key, (tenv[i].val==NULL) ? "" : tenv[i].val, 1)==FAILURE) {
01771                      RETURN_FALSE;
01772               }
01773     }
01774 
01775 }
01776 /* }}} */
01777 
01778 
01779 /* {{{ proto array getallheaders(void)
01780 */
01781 /*  Alias for apache_request_headers() */
01782 /* }}} */
01783 
01784 /* {{{ proto array apache_request_headers(void)
01785    Fetch all HTTP request headers */
01786 PHP_FUNCTION(apache_request_headers)
01787 {
01788        if (zend_parse_parameters_none() == FAILURE) {
01789               return;
01790        }
01791 
01792        apache_table_to_zval(((request_rec *)SG(server_context))->headers_in, PG(safe_mode), return_value);
01793 }
01794 /* }}} */
01795 
01796 /* {{{ proto array apache_response_headers(void)
01797    Fetch all HTTP response headers */
01798 PHP_FUNCTION(apache_response_headers)
01799 {
01800        if (zend_parse_parameters_none() == FAILURE) {
01801               return;
01802        }
01803 
01804        apache_table_to_zval(((request_rec *) SG(server_context))->headers_out, 0, return_value);
01805 }
01806 /* }}} */
01807 
01808 /* {{{ proto bool apache_setenv(string variable, string value [, bool walk_to_top])
01809    Set an Apache subprocess_env variable */
01810 PHP_FUNCTION(apache_setenv)
01811 {
01812        int var_len, val_len;
01813        zend_bool top=0;
01814        char *var = NULL, *val = NULL;
01815        request_rec *r = (request_rec *) SG(server_context);
01816 
01817     if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|b", &var, &var_len, &val, &val_len, &top) == FAILURE) {
01818         RETURN_FALSE;
01819        }
01820 
01821        while(top) {
01822               if (r->prev) {
01823                      r = r->prev;
01824               }
01825               else break;
01826        }
01827 
01828        ap_table_setn(r->subprocess_env, ap_pstrndup(r->pool, var, var_len), ap_pstrndup(r->pool, val, val_len));
01829        RETURN_TRUE;
01830 }
01831 /* }}} */
01832 
01833 /* {{{ proto object apache_lookup_uri(string URI)
01834    Perform a partial request of the given URI to obtain information about it */
01835 PHP_FUNCTION(apache_lookup_uri)
01836 {
01837        char *filename;
01838        int filename_len;
01839        request_rec *rr=NULL;
01840 
01841        if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &filename, &filename_len) == FAILURE) {
01842               return;
01843        }
01844 
01845        if(!(rr = sub_req_lookup_uri(filename, ((request_rec *) SG(server_context))))) {
01846               php_error(E_WARNING, "URI lookup failed", filename);
01847               RETURN_FALSE;
01848        }
01849 
01850        object_init(return_value);
01851        add_property_long(return_value,"status", rr->status);
01852 
01853        if (rr->the_request) {
01854               add_property_string(return_value,"the_request", rr->the_request, 1);
01855        }
01856        if (rr->status_line) {
01857               add_property_string(return_value,"status_line", (char *)rr->status_line, 1);        
01858        }
01859        if (rr->method) {
01860               add_property_string(return_value,"method", (char *)rr->method, 1);           
01861        }
01862        if (rr->content_type) {
01863               add_property_string(return_value,"content_type", (char *)rr->content_type, 1);
01864        }
01865        if (rr->handler) {
01866               add_property_string(return_value,"handler", (char *)rr->handler, 1);         
01867        }
01868        if (rr->uri) {
01869               add_property_string(return_value,"uri", rr->uri, 1);
01870        }
01871        if (rr->filename) {
01872               add_property_string(return_value,"filename", rr->filename, 1);
01873        }
01874        if (rr->path_info) {
01875               add_property_string(return_value,"path_info", rr->path_info, 1);
01876        }
01877        if (rr->args) {
01878               add_property_string(return_value,"args", rr->args, 1);
01879        }
01880        if (rr->boundary) {
01881               add_property_string(return_value,"boundary", rr->boundary, 1);
01882        }
01883        add_property_long(return_value,"no_cache", rr->no_cache);
01884        add_property_long(return_value,"no_local_copy", rr->no_local_copy);
01885        add_property_long(return_value,"allowed", rr->allowed);
01886        add_property_long(return_value,"sent_bodyct", rr->sent_bodyct);
01887        add_property_long(return_value,"bytes_sent", rr->bytes_sent);
01888        add_property_long(return_value,"byterange", rr->byterange);
01889        add_property_long(return_value,"clength", rr->clength);
01890 
01891 #if MODULE_MAGIC_NUMBER >= 19980324
01892        if (rr->unparsed_uri) {
01893               add_property_string(return_value,"unparsed_uri", rr->unparsed_uri, 1);
01894        }
01895        if(rr->mtime) {
01896               add_property_long(return_value,"mtime", rr->mtime);
01897        }
01898 #endif
01899        if(rr->request_time) {
01900               add_property_long(return_value,"request_time", rr->request_time);
01901        }
01902 
01903        destroy_sub_req(rr);
01904 }
01905 /* }}} */
01906 
01907 
01908 #if 0
01909 This function is most likely a bad idea.  Just playing with it for now.
01910 
01911 PHP_FUNCTION(apache_exec_uri)
01912 {
01913        zval **filename;
01914        request_rec *rr=NULL;
01915        TSRMLS_FETCH();
01916 
01917        if (ZEND_NUM_ARGS() != 1 || zend_get_parameters_ex(1, &filename) == FAILURE) {
01918               WRONG_PARAM_COUNT;
01919        }
01920        convert_to_string_ex(filename);
01921 
01922        if(!(rr = ap_sub_req_lookup_uri((*filename)->value.str.val, ((request_rec *) SG(server_context))))) {
01923               php_error(E_WARNING, "URI lookup failed", (*filename)->value.str.val);
01924               RETURN_FALSE;
01925        }
01926        RETVAL_LONG(ap_run_sub_req(rr));
01927        ap_destroy_sub_req(rr);
01928 }
01929 #endif
01930 
01931 /* {{{ proto string apache_get_version(void)
01932    Fetch Apache version */
01933 PHP_FUNCTION(apache_get_version)
01934 {
01935        char *apv = (char *) ap_get_server_version();
01936 
01937        if (apv && *apv) {
01938               RETURN_STRING(apv, 1);
01939        } else {
01940               RETURN_FALSE;
01941        }
01942 }
01943 /* }}} */
01944 
01945 /* {{{ proto array apache_get_modules(void)
01946    Get a list of loaded Apache modules */
01947 PHP_FUNCTION(apache_get_modules)
01948 {
01949        int n;
01950        char *p;
01951        
01952        array_init(return_value);
01953        
01954        for (n = 0; ap_loaded_modules[n]; ++n) {
01955               char *s = (char *) ap_loaded_modules[n]->name;
01956               if ((p = strchr(s, '.'))) {
01957                      add_next_index_stringl(return_value, s, (p - s), 1);
01958               } else {
01959                      add_next_index_string(return_value, s, 1);
01960               }      
01961        }
01962 }
01963 /* }}} */
01964 
01965 /*
01966  * Local variables:
01967  * tab-width: 4
01968  * c-basic-offset: 4
01969  * End:
01970  * vim600: sw=4 ts=4 fdm=marker
01971  * vim<600: sw=4 ts=4
01972  */