diff options
author | George Schlossnagle <gschlossnagle@php.net> | 2002-08-26 20:06:31 +0000 |
---|---|---|
committer | George Schlossnagle <gschlossnagle@php.net> | 2002-08-26 20:06:31 +0000 |
commit | f05126e2cf48764dcb50d4ba8d99809a73d2dc3a (patch) | |
tree | aa3ab30ffead0c18b0583ae837198bc09657eb9f | |
parent | ea996e0fa63e88fa1596a132ea5700f1d17d9d81 (diff) | |
download | php-git-f05126e2cf48764dcb50d4ba8d99809a73d2dc3a.tar.gz |
Import of Lukas Schroeder's work to give php a full interface to apache 1.3.x's hook interface, and full class wrappers around the apache request object and it's interfaces.
-rw-r--r-- | sapi/apache/mod_php4.c | 333 | ||||
-rw-r--r-- | sapi/apache/mod_php4.h | 19 | ||||
-rw-r--r-- | sapi/apache/php_apache.c | 1022 | ||||
-rw-r--r-- | sapi/apache/php_apache_http.h | 4 | ||||
-rw-r--r-- | sapi/apache/sapi_apache.c | 81 |
5 files changed, 1184 insertions, 275 deletions
diff --git a/sapi/apache/mod_php4.c b/sapi/apache/mod_php4.c index 167178bf97..51a367728a 100644 --- a/sapi/apache/mod_php4.c +++ b/sapi/apache/mod_php4.c @@ -1,8 +1,8 @@ /* +----------------------------------------------------------------------+ - | PHP version 4.0 | + | PHP Version 4 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2001 The PHP Group | + | Copyright (c) 1997-2002 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 2.02 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -19,63 +19,32 @@ */ /* $Id$ */ -#define NO_REGEX_EXTRA_H -#ifdef WIN32 -#include <winsock2.h> -#include <stddef.h> -#endif - -#include "zend.h" -#include "php.h" -#include "php_variables.h" +#include "php_apache_http.h" -#include "httpd.h" -#include "http_config.h" -#if MODULE_MAGIC_NUMBER > 19980712 -# include "ap_compat.h" -#else -# if MODULE_MAGIC_NUMBER > 19980324 -# include "compat.h" -# endif +#ifdef NETWARE +#define SIGPIPE SIGINT #endif -#include "http_core.h" -#include "http_main.h" -#include "http_protocol.h" -#include "http_request.h" -#include "http_log.h" - -#include "php_ini.h" -#include "php_globals.h" -#include "SAPI.h" -#include "php_main.h" - -#include "zend_compile.h" -#include "zend_execute.h" -#include "zend_highlight.h" -#include "zend_indent.h" - -#include "ext/standard/php_standard.h" - -#include "util_script.h" -#include "mod_php4.h" +#if defined(ZEND_MULTIBYTE) && defined(HAVE_MBSTRING) +#include "ext/mbstring/mbstring.h" +#endif /* defined(ZEND_MULTIBYTE) && defined(HAVE_MBSTRING) */ #undef shutdown /* {{{ Prototypes */ int apache_php_module_main(request_rec *r, int display_source_mode TSRMLS_DC); -void php_save_umask(void); -void php_restore_umask(void); -int sapi_apache_read_post(char *buffer, uint count_bytes TSRMLS_DC); -char *sapi_apache_read_cookies(TSRMLS_D); -int sapi_apache_header_handler(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC); -int sapi_apache_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC); +static void php_save_umask(void); +static void php_restore_umask(void); +static int sapi_apache_read_post(char *buffer, uint count_bytes TSRMLS_DC); +static char *sapi_apache_read_cookies(TSRMLS_D); +static int sapi_apache_header_handler(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC); +static int sapi_apache_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC); static int send_php(request_rec *r, int display_source_mode, char *filename); static int send_parsed_php(request_rec * r); static int send_parsed_php_source(request_rec * r); -int php_xbithack_handler(request_rec * r); -void php_init_handler(server_rec *s, pool *p); +static int php_xbithack_handler(request_rec * r); +static void php_init_handler(server_rec *s, pool *p); /* }}} */ #if MODULE_MAGIC_NUMBER >= 19970728 @@ -87,12 +56,12 @@ static void php_child_exit_handler(server_rec *s, pool *p); #else #define CONST_PREFIX #endif -CONST_PREFIX char *php_apache_value_handler_ex(cmd_parms *cmd, HashTable *conf, char *arg1, char *arg2, int mode); -CONST_PREFIX char *php_apache_value_handler(cmd_parms *cmd, HashTable *conf, char *arg1, char *arg2); -CONST_PREFIX char *php_apache_admin_value_handler(cmd_parms *cmd, HashTable *conf, char *arg1, char *arg2); -CONST_PREFIX char *php_apache_flag_handler(cmd_parms *cmd, HashTable *conf, char *arg1, char *arg2); -CONST_PREFIX char *php_apache_flag_handler_ex(cmd_parms *cmd, HashTable *conf, char *arg1, char *arg2, int mode); -CONST_PREFIX char *php_apache_admin_flag_handler(cmd_parms *cmd, HashTable *conf, char *arg1, char *arg2); +static CONST_PREFIX char *php_apache_value_handler_ex(cmd_parms *cmd, HashTable *conf, char *arg1, char *arg2, int mode); +static CONST_PREFIX char *php_apache_value_handler(cmd_parms *cmd, HashTable *conf, char *arg1, char *arg2); +static CONST_PREFIX char *php_apache_admin_value_handler(cmd_parms *cmd, HashTable *conf, char *arg1, char *arg2); +static CONST_PREFIX char *php_apache_flag_handler(cmd_parms *cmd, HashTable *conf, char *arg1, char *arg2); +static CONST_PREFIX char *php_apache_flag_handler_ex(cmd_parms *cmd, HashTable *conf, char *arg1, char *arg2, int mode); +static CONST_PREFIX char *php_apache_admin_flag_handler(cmd_parms *cmd, HashTable *conf, char *arg1, char *arg2); /* ### these should be defined in mod_php4.h or somewhere else */ #define USE_PATH 1 @@ -101,6 +70,7 @@ CONST_PREFIX char *php_apache_admin_flag_handler(cmd_parms *cmd, HashTable *conf module MODULE_VAR_EXPORT php4_module; int saved_umask; +//static int setup_env = 0; static unsigned char apache_php_initialized; typedef struct _php_per_dir_entry { @@ -115,7 +85,7 @@ typedef struct _php_per_dir_entry { /* {{{ php_save_umask */ -void php_save_umask(void) +static void php_save_umask(void) { saved_umask = umask(077); umask(saved_umask); @@ -154,12 +124,22 @@ static void sapi_apache_flush(void *server_context) /* {{{ sapi_apache_read_post */ -int sapi_apache_read_post(char *buffer, uint count_bytes TSRMLS_DC) +static int sapi_apache_read_post(char *buffer, uint count_bytes TSRMLS_DC) { uint total_read_bytes=0, read_bytes; request_rec *r = (request_rec *) SG(server_context); void (*handler)(int); + /* + * This handles the situation where the browser sends a Expect: 100-continue header + * and needs to recieve confirmation from the server on whether or not it can send + * the rest of the request. RFC 2616 + * + */ + if (!SG(read_post_bytes) && !ap_should_client_block(r)) { + return total_read_bytes; + } + handler = signal(SIGPIPE, SIG_IGN); while (total_read_bytes<count_bytes) { hard_timeout("Read POST information", r); /* start timeout timer */ @@ -177,7 +157,7 @@ int sapi_apache_read_post(char *buffer, uint count_bytes TSRMLS_DC) /* {{{ sapi_apache_read_cookies */ -char *sapi_apache_read_cookies(TSRMLS_D) +static char *sapi_apache_read_cookies(TSRMLS_D) { return (char *) table_get(((request_rec *) SG(server_context))->subprocess_env, "HTTP_COOKIE"); } @@ -185,7 +165,7 @@ char *sapi_apache_read_cookies(TSRMLS_D) /* {{{ sapi_apache_header_handler */ -int sapi_apache_header_handler(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC) +static int sapi_apache_header_handler(sapi_header_struct *sapi_header, sapi_headers_struct *sapi_headers TSRMLS_DC) { char *header_name, *header_content, *p; request_rec *r = (request_rec *) SG(server_context); @@ -194,6 +174,7 @@ int sapi_apache_header_handler(sapi_header_struct *sapi_header, sapi_headers_str header_content = p = strchr(header_name, ':'); if (!p) { + efree(sapi_header->header); return 0; } @@ -220,7 +201,7 @@ int sapi_apache_header_handler(sapi_header_struct *sapi_header, sapi_headers_str /* {{{ sapi_apache_send_headers */ -int sapi_apache_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC) +static int sapi_apache_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC) { if(SG(server_context) == NULL) { /* server_context is not here anymore */ return SAPI_HEADER_SEND_FAILED; @@ -309,13 +290,16 @@ static void php_apache_log_message(char *message) static void php_apache_request_shutdown(void *dummy) { TSRMLS_FETCH(); - php_output_set_status(0 TSRMLS_CC); SG(server_context) = NULL; /* The server context (request) is invalid by the time run_cleanups() is called */ - if (AP(in_request)) { - AP(in_request) = 0; + if(SG(sapi_started)) { php_request_shutdown(dummy); + SG(sapi_started) = 0; } + AP(in_request) = 0; + if(AP(setup_env)) { + AP(setup_env) = 0; + } } /* }}} */ @@ -391,7 +375,7 @@ static sapi_module_struct apache_sapi_module = { sapi_apache_register_server_variables, /* register server variables */ php_apache_log_message, /* Log message */ - NULL, /* php.ini path override */ + NULL, /* php.ini path override */ #ifdef PHP_WIN32 NULL, @@ -407,7 +391,7 @@ static sapi_module_struct apache_sapi_module = { /* {{{ php_restore_umask */ -void php_restore_umask(void) +static void php_restore_umask(void) { umask(saved_umask); } @@ -415,8 +399,9 @@ void php_restore_umask(void) /* {{{ init_request_info */ -static void init_request_info(request_rec *r TSRMLS_DC) +static void init_request_info(TSRMLS_D) { + request_rec *r = ((request_rec *) SG(server_context)); char *content_length = (char *) table_get(r->subprocess_env, "CONTENT_LENGTH"); const char *authorization=NULL; char *tmp; @@ -433,7 +418,7 @@ static void init_request_info(request_rec *r TSRMLS_DC) authorization = table_get(r->headers_in, "Authorization"); } if (authorization -/* && !auth_type(r) */ + && !auth_type(r) && !strcasecmp(getword(r->pool, &authorization, ' '), "Basic")) { tmp = uudecode(r->pool, authorization); SG(request_info).auth_user = getword_nulls_nc(r->pool, &tmp, ':'); @@ -497,28 +482,33 @@ static int send_php(request_rec *r, int display_source_mode, char *filename) fh.opened_path = NULL; fh.free_filename = 0; fh.type = ZEND_HANDLE_FILENAME; + +#if defined(ZEND_MULTIBYTE) && defined(HAVE_MBSTRING) + php_mbstring_set_zend_encoding(TSRMLS_C); +#endif /* defined(ZEND_MULTIBYTE) && defined(HAVE_MBSTRING) */ + zend_execute_scripts(ZEND_INCLUDE TSRMLS_CC, NULL, 1, &fh); return OK; } zend_first_try { - /* We don't accept OPTIONS requests, but take everything else */ - if (r->method_number == M_OPTIONS) { - r->allowed |= (1 << METHODS) - 1; - return DECLINED; - } /* Make sure file exists */ if (filename == NULL && r->finfo.st_mode == 0) { return DECLINED; } - if(!AP(apache_config_loaded)) { - per_dir_conf = (HashTable *) get_module_config(r->per_dir_config, &php4_module); - if (per_dir_conf) { - zend_hash_apply((HashTable *) per_dir_conf, (apply_func_t) php_apache_alter_ini_entries TSRMLS_CC); + per_dir_conf = (HashTable *) get_module_config(r->per_dir_config, &php4_module); + if (per_dir_conf) { + zend_hash_apply((HashTable *) per_dir_conf, (apply_func_t) php_apache_alter_ini_entries TSRMLS_CC); + } + + /* We don't accept OPTIONS requests, but take everything else */ + if (!PG(allow_webdav_methods)) { + if (r->method_number == M_OPTIONS) { + r->allowed |= (1 << METHODS) - 1; + return DECLINED; } - AP(apache_config_loaded) = 1; } /* If PHP parser engine has been turned off with an "engine off" @@ -573,7 +563,7 @@ static int send_php(request_rec *r, int display_source_mode, char *filename) add_common_vars(r); add_cgi_vars(r); - init_request_info(r TSRMLS_CC); + init_request_info(TSRMLS_C); apache_php_module_main(r, display_source_mode TSRMLS_CC); /* Done, restore umask, turn off timeout, close file and return */ @@ -589,16 +579,17 @@ static int send_php(request_rec *r, int display_source_mode, char *filename) */ static int send_parsed_php(request_rec * r) { - int result = send_php(r, 0, NULL); + int result = send_php(r, 0, NULL); #if MEMORY_LIMIT - { - char mem_usage[ 32 ]; - TSRMLS_FETCH(); + { + char *mem_usage; + TSRMLS_FETCH(); - sprintf(mem_usage,"%u", (int) AG(allocated_memory_peak)); - ap_table_setn(r->notes, "mod_php_memory_usage", ap_pstrdup(r->pool, mem_usage)); - } + mem_usage = ap_psprintf(r->pool, "%u", AG(allocated_memory_peak)); + AG(allocated_memory_peak) = 0; + ap_table_setn(r->notes, "mod_php_memory_usage", mem_usage); + } #endif return result; @@ -665,13 +656,13 @@ static void php_destroy_per_dir_info(HashTable *per_dir_info) static void *php_create_dir(pool *p, char *dummy) { HashTable *per_dir_info; - per_dir_info = (HashTable *) malloc(sizeof(HashTable)); - zend_hash_init(per_dir_info, 5, NULL, (void (*)(void *)) destroy_per_dir_entry, 1); + zend_hash_init_ex(per_dir_info, 5, NULL, (void (*)(void *)) destroy_per_dir_entry, 1, 0); register_cleanup(p, (void *) per_dir_info, (void (*)(void *)) php_destroy_per_dir_info, (void (*)(void *)) zend_hash_destroy); return per_dir_info; } + /* }}} */ /* {{{ php_merge_dir @@ -684,9 +675,10 @@ static void *php_merge_dir(pool *p, void *basev, void *addv) } /* }}} */ + /* {{{ php_apache_value_handler_ex */ -CONST_PREFIX char *php_apache_value_handler_ex(cmd_parms *cmd, HashTable *conf, char *arg1, char *arg2, int mode) +static CONST_PREFIX char *php_apache_value_handler_ex(cmd_parms *cmd, HashTable *conf, char *arg1, char *arg2, int mode) { php_per_dir_entry per_dir_entry; @@ -715,14 +707,14 @@ CONST_PREFIX char *php_apache_value_handler_ex(cmd_parms *cmd, HashTable *conf, memcpy(per_dir_entry.value, arg2, per_dir_entry.value_length); per_dir_entry.value[per_dir_entry.value_length] = 0; - zend_hash_update((HashTable *) conf, per_dir_entry.key, per_dir_entry.key_length, &per_dir_entry, sizeof(php_per_dir_entry), NULL); + zend_hash_update(conf, per_dir_entry.key, per_dir_entry.key_length, &per_dir_entry, sizeof(php_per_dir_entry), NULL); return NULL; } /* }}} */ /* {{{ php_apache_value_handler */ -CONST_PREFIX char *php_apache_value_handler(cmd_parms *cmd, HashTable *conf, char *arg1, char *arg2) +static CONST_PREFIX char *php_apache_value_handler(cmd_parms *cmd, HashTable *conf, char *arg1, char *arg2) { return php_apache_value_handler_ex(cmd, conf, arg1, arg2, PHP_INI_PERDIR); } @@ -730,7 +722,7 @@ CONST_PREFIX char *php_apache_value_handler(cmd_parms *cmd, HashTable *conf, cha /* {{{ php_apache_admin_value_handler */ -CONST_PREFIX char *php_apache_admin_value_handler(cmd_parms *cmd, HashTable *conf, char *arg1, char *arg2) +static CONST_PREFIX char *php_apache_admin_value_handler(cmd_parms *cmd, HashTable *conf, char *arg1, char *arg2) { return php_apache_value_handler_ex(cmd, conf, arg1, arg2, PHP_INI_SYSTEM); } @@ -738,7 +730,7 @@ CONST_PREFIX char *php_apache_admin_value_handler(cmd_parms *cmd, HashTable *con /* {{{ php_apache_flag_handler_ex */ -CONST_PREFIX char *php_apache_flag_handler_ex(cmd_parms *cmd, HashTable *conf, char *arg1, char *arg2, int mode) +static CONST_PREFIX char *php_apache_flag_handler_ex(cmd_parms *cmd, HashTable *conf, char *arg1, char *arg2, int mode) { char bool_val[2]; @@ -755,7 +747,7 @@ CONST_PREFIX char *php_apache_flag_handler_ex(cmd_parms *cmd, HashTable *conf, c /* {{{ php_apache_flag_handler */ -CONST_PREFIX char *php_apache_flag_handler(cmd_parms *cmd, HashTable *conf, char *arg1, char *arg2) +static CONST_PREFIX char *php_apache_flag_handler(cmd_parms *cmd, HashTable *conf, char *arg1, char *arg2) { return php_apache_flag_handler_ex(cmd, conf, arg1, arg2, PHP_INI_PERDIR); } @@ -763,7 +755,7 @@ CONST_PREFIX char *php_apache_flag_handler(cmd_parms *cmd, HashTable *conf, char /* {{{ php_apache_admin_flag_handler */ -CONST_PREFIX char *php_apache_admin_flag_handler(cmd_parms *cmd, HashTable *conf, char *arg1, char *arg2) +static CONST_PREFIX char *php_apache_admin_flag_handler(cmd_parms *cmd, HashTable *conf, char *arg1, char *arg2) { return php_apache_flag_handler_ex(cmd, conf, arg1, arg2, PHP_INI_SYSTEM); } @@ -771,23 +763,20 @@ CONST_PREFIX char *php_apache_admin_flag_handler(cmd_parms *cmd, HashTable *conf /* {{{ int php_xbithack_handler(request_rec * r) */ -int php_xbithack_handler(request_rec * r) +static int php_xbithack_handler(request_rec * r) { - HashTable *conf; - - if(!AP(apache_config_loaded)) { - conf = (HashTable *) get_module_config(r->per_dir_config, &php4_module); - if (conf) { - zend_hash_apply((HashTable *)conf, (apply_func_t) php_apache_alter_ini_entries TSRMLS_CC); - } - AP(apache_config_loaded) = 1; - } + HashTable *per_dir_conf; + TSRMLS_FETCH(); if (!(r->finfo.st_mode & S_IXUSR)) { r->allowed |= (1 << METHODS) - 1; return DECLINED; } - if (!AP(xbithack)) { + per_dir_conf = (HashTable *) get_module_config(r->per_dir_config, &php4_module); + if (per_dir_conf) { + zend_hash_apply((HashTable *) per_dir_conf, (apply_func_t) php_apache_alter_ini_entries TSRMLS_CC); + } + if(!AP(xbithack)) { r->allowed |= (1 << METHODS) - 1; return DECLINED; } @@ -832,7 +821,7 @@ static void php_child_exit_handler(server_rec *s, pool *p) /* {{{ void php_init_handler(server_rec *s, pool *p) */ -void php_init_handler(server_rec *s, pool *p) +static void php_init_handler(server_rec *s, pool *p) { register_cleanup(p, NULL, (void (*)(void *))apache_php_module_shutdown_wrapper, (void (*)(void *))php_module_shutdown_for_exec); if (!apache_php_initialized) { @@ -854,6 +843,82 @@ void php_init_handler(server_rec *s, pool *p) } /* }}} */ +static int php_run_hook(request_rec *r, char *handler) +{ + zval *ret = NULL; + HashTable *conf; + + TSRMLS_FETCH(); + + if (!AP(apache_config_loaded)) { + conf = (HashTable *) get_module_config(r->per_dir_config, &php4_module); + if (conf) + zend_hash_apply((HashTable *)conf, (apply_func_t) php_apache_alter_ini_entries TSRMLS_CC); + AP(apache_config_loaded) = 1; + } + + if (!handler) + return DECLINED; + + hard_timeout("send", r); + SG(server_context) = r; + php_save_umask(); + if (!AP(setup_env)) { + add_common_vars(r); + add_cgi_vars(r); + AP(setup_env) = 1; + } + init_request_info(TSRMLS_C); + apache_php_module_hook(r, handler, &ret TSRMLS_CC); + php_restore_umask(); + kill_timeout(r); + + if (ret) { + convert_to_long(ret); + return Z_LVAL_P(ret); + } + + return HTTP_INTERNAL_SERVER_ERROR; +} + + +static int php_uri_translation(request_rec *r) +{ + fprintf(stderr, "HOOK: %s\n", __FUNCTION__); + return php_run_hook(r, AP(uri_handler)); +} + +static int php_auth_hook(request_rec *r) +{ + fprintf(stderr, "HOOK: %s\n", __FUNCTION__); + return php_run_hook(r, AP(auth_handler)); +} + +static int php_access_hook(request_rec *r) +{ + fprintf(stderr, "HOOK: %s\n", __FUNCTION__); + return php_run_hook(r, AP(access_handler)); +} + +static int php_type_hook(request_rec *r) +{ + fprintf(stderr, "HOOK: %s\n", __FUNCTION__); + return php_run_hook(r, AP(type_handler)); +} + +static int php_fixup_hook(request_rec *r) +{ + fprintf(stderr, "HOOK: %s\n", __FUNCTION__); + return php_run_hook(r, AP(fixup_handler)); +} + +static int php_logger_hook(request_rec *r) +{ + fprintf(stderr, "HOOK: %s\n", __FUNCTION__); + return php_run_hook(r, AP(logger_handler)); +} + + /* {{{ handler_rec php_handlers[] */ handler_rec php_handlers[] = @@ -877,50 +942,6 @@ command_rec php_commands[] = }; /* }}} */ -static int php_uri_translation(request_rec *r) -{ - char *handler = NULL; - zval *ret = NULL; - HashTable *conf; - TSRMLS_FETCH(); - - if(!AP(apache_config_loaded)) { - conf = (HashTable *) get_module_config(r->per_dir_config, &php4_module); - if (conf) { - zend_hash_apply((HashTable *)conf, (apply_func_t) php_apache_alter_ini_entries TSRMLS_CC); - } - AP(apache_config_loaded) = 1; - } - - handler = AP(uri_handler); - - if(handler) { - hard_timeout("send", r); - SG(server_context) = r; - php_save_umask(); - add_common_vars(r); - add_cgi_vars(r); - init_request_info(r TSRMLS_CC); - apache_php_module_hook(r, handler, &ret TSRMLS_CC); - php_restore_umask(); - kill_timeout(r); - convert_to_string(ret); - if(Z_STRLEN_P(ret)) { - if (strchr(Z_STRVAL_P(ret), ':')) { - ap_table_setn(r->headers_out, "Location", Z_STRVAL_P(ret)); - return REDIRECT; - } else { - r->filename = ap_pstrdup(r->pool, Z_STRVAL_P(ret)); - } - return OK; - } else { - return DECLINED; - } - } else { - return DECLINED; - } -} - /* {{{ module MODULE_VAR_EXPORT php4_module */ module MODULE_VAR_EXPORT php4_module = @@ -935,11 +956,11 @@ module MODULE_VAR_EXPORT php4_module = php_handlers, /* handlers */ php_uri_translation, /* filename translation */ NULL, /* check_user_id */ - NULL, /* check auth */ - NULL, /* check access */ - NULL, /* type_checker */ - NULL, /* fixups */ - NULL /* logger */ + php_auth_hook, /* check auth */ + php_access_hook, /* check access */ + php_type_hook, /* type_checker */ + php_fixup_hook, /* fixups */ + php_logger_hook /* logger */ #if MODULE_MAGIC_NUMBER >= 19970103 , NULL /* header parser */ #endif @@ -947,7 +968,7 @@ module MODULE_VAR_EXPORT php4_module = , NULL /* child_init */ #endif #if MODULE_MAGIC_NUMBER >= 19970728 - , php_child_exit_handler /* child_exit */ + , php_child_exit_handler /* child_exit */ #endif #if MODULE_MAGIC_NUMBER >= 19970902 , NULL /* post read-request */ @@ -960,6 +981,6 @@ module MODULE_VAR_EXPORT php4_module = * tab-width: 4 * c-basic-offset: 4 * End: - * vim600: sw=4 ts=4 tw=78 fdm=marker - * vim<600: sw=4 ts=4 tw=78 + * vim600: sw=4 ts=4 fdm=marker + * vim<600: sw=4 ts=4 */ diff --git a/sapi/apache/mod_php4.h b/sapi/apache/mod_php4.h index 160ce3661b..97cba24961 100644 --- a/sapi/apache/mod_php4.h +++ b/sapi/apache/mod_php4.h @@ -1,8 +1,8 @@ /* +----------------------------------------------------------------------+ - | PHP version 4.0 | + | PHP Version 4 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2001 The PHP Group | + | Copyright (c) 1997-2002 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 2.02 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -12,7 +12,7 @@ | obtain it through the world-wide-web, please send a note to | | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ - | Authors: Rasmus Lerdorf <rasmus@php.net> | + | Author: Rasmus Lerdorf <rasmus@php.net> | +----------------------------------------------------------------------+ */ /* $Id$ */ @@ -31,26 +31,27 @@ typedef struct { long last_modified; long xbithack; long terminate_child; + long setup_env; zend_bool in_request; zend_bool apache_config_loaded; char *uri_handler; + char *auth_handler; + char *access_handler; + char *type_handler; + char *fixup_handler; + char *logger_handler; } php_apache_info_struct; extern zend_module_entry apache_module_entry; #ifdef ZTS extern int php_apache_info_id; -#define AP(v) TSRMG(alloc_globals_id, php_apache_info_struct *, v) +#define AP(v) TSRMG(php_apache_info_id, php_apache_info_struct *, v) #else extern php_apache_info_struct php_apache_info; #define AP(v) (php_apache_info.v) #endif - -#ifdef WIN32 -#define S_IXUSR _S_IEXEC -#endif - #endif /* MOD_PHP4_H */ /* diff --git a/sapi/apache/php_apache.c b/sapi/apache/php_apache.c index 606d9ad01d..51a2036667 100644 --- a/sapi/apache/php_apache.c +++ b/sapi/apache/php_apache.c @@ -1,8 +1,8 @@ /* +----------------------------------------------------------------------+ - | PHP version 4.0 | + | PHP Version 4 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2001 The PHP Group | + | Copyright (c) 1997-2002 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 2.02 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -13,37 +13,20 @@ | license@php.net so we can mail you a copy immediately. | +----------------------------------------------------------------------+ | Authors: Rasmus Lerdorf <rasmus@lerdorf.on.ca> | - | Stig Sæther Bakken <ssb@guardian.no> | + | Stig Sæther Bakken <ssb@fast.no> | | David Sklar <sklar@student.net> | +----------------------------------------------------------------------+ */ /* $Id$ */ -#define NO_REGEX_EXTRA_H - -#ifdef WIN32 -#include <winsock2.h> -#include <stddef.h> -#endif +#include "php_apache_http.h" -#include "php.h" -#include "ext/standard/head.h" -#include "php_globals.h" -#include "php_ini.h" -#include "SAPI.h" -#include "mod_php4.h" -#include "ext/standard/info.h" - -#include <stdlib.h> -#if HAVE_UNISTD_H -#include <unistd.h> +#if defined(PHP_WIN32) || defined(NETWARE) +#include "zend.h" +#include "ap_compat.h" +#else +#include "build-defs.h" #endif -#include <string.h> -#include <errno.h> -#include <ctype.h> - -#include "php_apache_http.h" -#include "http_request.h" #ifdef ZTS int php_apache_info_id; @@ -51,61 +34,928 @@ int php_apache_info_id; php_apache_info_struct php_apache_info; #endif -#ifdef PHP_WIN32 -#include "zend.h" -#include "ap_compat.h" -#else -#include "build-defs.h" -#endif - #define SECTION(name) PUTS("<H2 align=\"center\">" name "</H2>\n") extern module *top_module; +static int le_apachereq; +static zend_class_entry *apacherequest_class_entry; PHP_FUNCTION(virtual); -PHP_FUNCTION(getallheaders); +PHP_FUNCTION(apache_request_headers); +PHP_FUNCTION(apache_response_headers); PHP_FUNCTION(apachelog); PHP_FUNCTION(apache_note); PHP_FUNCTION(apache_lookup_uri); PHP_FUNCTION(apache_child_terminate); +PHP_FUNCTION(apache_setenv); PHP_MINFO_FUNCTION(apache); + function_entry apache_functions[] = { PHP_FE(virtual, NULL) - PHP_FE(getallheaders, NULL) + PHP_FE(apache_request_headers, NULL) PHP_FE(apache_note, NULL) PHP_FE(apache_lookup_uri, NULL) PHP_FE(apache_child_terminate, NULL) + PHP_FE(apache_setenv, NULL) + PHP_FE(apache_response_headers, NULL) + PHP_FALIAS(getallheaders, apache_request_headers, NULL) {NULL, NULL, NULL} }; - +/* {{{ php_apache ini entries + */ PHP_INI_BEGIN() STD_PHP_INI_ENTRY("xbithack", "0", PHP_INI_ALL, OnUpdateInt, xbithack, php_apache_info_struct, php_apache_info) STD_PHP_INI_ENTRY("engine", "1", PHP_INI_ALL, OnUpdateInt, engine, php_apache_info_struct, php_apache_info) STD_PHP_INI_ENTRY("last_modified", "0", PHP_INI_ALL, OnUpdateInt, last_modified, php_apache_info_struct, php_apache_info) STD_PHP_INI_ENTRY("child_terminate", "0", PHP_INI_ALL, OnUpdateInt, terminate_child, php_apache_info_struct, php_apache_info) - STD_PHP_INI_ENTRY("uri_handler", NULL, PHP_INI_ALL, OnUpdateString, uri_handler, php_apache_info_struct, php_apache_info) -PHP_INI_END() - + STD_PHP_INI_ENTRY("uri_handler", NULL, PHP_INI_ALL, OnUpdateString, uri_handler, php_apache_info_struct, php_apache_info) + STD_PHP_INI_ENTRY("auth_handler", NULL, PHP_INI_ALL, OnUpdateString, auth_handler, php_apache_info_struct, php_apache_info) + STD_PHP_INI_ENTRY("access_handler", NULL, PHP_INI_ALL, OnUpdateString, access_handler, php_apache_info_struct, php_apache_info) + STD_PHP_INI_ENTRY("type_handler", NULL, PHP_INI_ALL, OnUpdateString, type_handler, php_apache_info_struct, php_apache_info) + STD_PHP_INI_ENTRY("fixup_handler", NULL, PHP_INI_ALL, OnUpdateString, fixup_handler, php_apache_info_struct, php_apache_info) + STD_PHP_INI_ENTRY("logger_handler", NULL, PHP_INI_ALL, OnUpdateString, logger_handler, php_apache_info_struct, php_apache_info) +PHP_INI_END() +/* }}} */ static void php_apache_globals_ctor(php_apache_info_struct *apache_globals TSRMLS_DC) { apache_globals->in_request = 0; - apache_globals->apache_config_loaded = 0; } +#define APREQ_GET_THIS(ZVAL) if (NULL == (ZVAL = getThis())) { \ + php_error(E_WARNING, "%s(): underlying ApacheRequest object missing", \ + get_active_function_name(TSRMLS_C)); \ + RETURN_FALSE; \ + } +#define APREQ_GET_REQUEST(ZVAL, R) APREQ_GET_THIS(ZVAL); \ + R = get_apache_request(ZVAL) + +static void php_apache_request_free(zend_rsrc_list_entry *rsrc TSRMLS_DC) +{ + zval *z = (zval *)rsrc->ptr; + fprintf(stderr, "%s() %p\n", __FUNCTION__, z); + zval_ptr_dtor(&z); +} + +static request_rec *get_apache_request(zval *z) +{ + request_rec *r; + zval **addr; + + if (NULL == z) { + php_error(E_WARNING, "get_apache_request() invalid wrapper passed"); + return NULL; + } + + if (Z_TYPE_P(z) != IS_OBJECT) { + php_error(E_WARNING, "%s(): wrapper is not an object", get_active_function_name(TSRMLS_C)); + return NULL; + } + + if (zend_hash_index_find(Z_OBJPROP_P(z), 0, (void **)&addr) == FAILURE) { + php_error(E_WARNING, "%s(): underlying object missing", get_active_function_name(TSRMLS_C)); + return NULL; + } + + r = (request_rec *)Z_LVAL_PP(addr); + if (!r) { + php_error(E_WARNING, "%s(): request_rec invalid", get_active_function_name(TSRMLS_C)); + return NULL; + } + + return r; +} + +/* {{{ + */ +PHPAPI zval *php_apache_request_new(request_rec *r) +{ + zval *req; + zval *addr; + + MAKE_STD_ZVAL(addr); + Z_TYPE_P(addr) = IS_LONG; + Z_LVAL_P(addr) = (int) r; + + MAKE_STD_ZVAL(req); + object_init_ex(req, apacherequest_class_entry); + zend_hash_index_update(Z_OBJPROP_P(req), 0, &addr, sizeof(zval *), NULL); + + return req; +} +/* }}} */ + +/* {{{ apache_request_read_string_slot() + */ +static void apache_request_read_string_slot(int offset, INTERNAL_FUNCTION_PARAMETERS) +{ + zval *id, **new_value; + request_rec *r; + char *s; + + if (ZEND_NUM_ARGS() > 0) { + WRONG_PARAM_COUNT; + } + + APREQ_GET_REQUEST(id, r); + + s = *(char **)((char*)r + offset); + + if (s) + RETURN_STRING(s, 1); + + RETURN_EMPTY_STRING(); +} +/* }}} */ + + +/* {{{ apache_request_string_slot() + */ +static void apache_request_string_slot(int offset, INTERNAL_FUNCTION_PARAMETERS) +{ + zval *id, **new_value; + request_rec *r; + char *old_value; + char **target; + + APREQ_GET_REQUEST(id, r); + + target = (char **)((char*)r + offset); + old_value = *target; + + switch (ZEND_NUM_ARGS()) { + case 0: + break; + case 1: + if (zend_get_parameters_ex(1, &new_value) == FAILURE) { + RETURN_FALSE; + } + convert_to_string_ex(new_value); + *target = ap_pstrdup(r->pool, Z_STRVAL_PP(new_value)); + break; + default: + WRONG_PARAM_COUNT; + break; + } + + if (old_value) + RETURN_STRING(old_value, 1); + + RETURN_EMPTY_STRING(); +} +/* }}} */ + +/* {{{ apache_request_read_int_slot() + */ +static void apache_request_read_int_slot(int offset, INTERNAL_FUNCTION_PARAMETERS) +{ + zval *id; + request_rec *r; + long l; + + if (ZEND_NUM_ARGS() > 0) { + WRONG_PARAM_COUNT; + } + + APREQ_GET_REQUEST(id, r); + + l = *(long *)((char*)r + offset); + + RETURN_LONG(l); +} +/* }}} */ + +/* {{{ apache_request_int_slot() + */ +static void apache_request_int_slot(int offset, INTERNAL_FUNCTION_PARAMETERS) +{ + zval *id, **new_value; + request_rec *r; + long old_value; + long *target; + + APREQ_GET_REQUEST(id, r); + + target = (long *)((char*)r + offset); + old_value = *target; + + switch (ZEND_NUM_ARGS()) { + case 0: + break; + case 1: + if (zend_get_parameters_ex(1, &new_value) == FAILURE) { + RETURN_FALSE; + } + convert_to_long_ex(new_value); + *target = Z_LVAL_PP(new_value); + break; + default: + WRONG_PARAM_COUNT; + break; + } + + RETURN_LONG(old_value); +} +/* }}} */ + + +/* {{{ access string slots of request rec + */ + +/* {{{ proto string $request->filename([string new_filename]) + */ +PHP_FUNCTION(apache_request_filename) +{ + apache_request_string_slot(offsetof(request_rec, filename), INTERNAL_FUNCTION_PARAM_PASSTHRU); +} +/* }}} */ + +/* {{{ proto string $request->uri([string new_uri]) + */ +PHP_FUNCTION(apache_request_uri) +{ + apache_request_string_slot(offsetof(request_rec, uri), INTERNAL_FUNCTION_PARAM_PASSTHRU); +} +/* }}} */ + +/* {{{ proto string $request->unparsed_uri([string new_unparsed_uri]) + */ +PHP_FUNCTION(apache_request_unparsed_uri) +{ + apache_request_string_slot(offsetof(request_rec, unparsed_uri), INTERNAL_FUNCTION_PARAM_PASSTHRU); +} +/* }}} */ + +/* {{{ proto string $request->path_info([string new_path_info]) + */ +PHP_FUNCTION(apache_request_path_info) +{ + apache_request_string_slot(offsetof(request_rec, path_info), INTERNAL_FUNCTION_PARAM_PASSTHRU); +} +/* }}} */ + +/* {{{ proto string $request->args([string new_args]) + */ +PHP_FUNCTION(apache_request_args) +{ + apache_request_string_slot(offsetof(request_rec, args), INTERNAL_FUNCTION_PARAM_PASSTHRU); +} +/* }}} */ + +/* {{{ proto string $request->boundary() + */ +PHP_FUNCTION(apache_request_boundary) +{ + apache_request_read_string_slot(offsetof(request_rec, boundary), INTERNAL_FUNCTION_PARAM_PASSTHRU); +} +/* }}} */ + + +/* {{{ proto string $request->content_type([string new_type]) + */ +PHP_FUNCTION(apache_request_content_type) +{ + apache_request_string_slot(offsetof(request_rec, content_type), INTERNAL_FUNCTION_PARAM_PASSTHRU); +} +/* }}} */ + +/* {{{ proto string $request->content_encoding([string new_encoding]) + */ +PHP_FUNCTION(apache_request_content_encoding) +{ + apache_request_string_slot(offsetof(request_rec, content_encoding), INTERNAL_FUNCTION_PARAM_PASSTHRU); +} +/* }}} */ + +/* {{{ proto string $request->handler([string new_handler]) + */ +PHP_FUNCTION(apache_request_handler) +{ + apache_request_string_slot(offsetof(request_rec, handler), INTERNAL_FUNCTION_PARAM_PASSTHRU); +} +/* }}} */ + +/* {{{ proto string $request->the_request() + */ +PHP_FUNCTION(apache_request_the_request) +{ + apache_request_read_string_slot(offsetof(request_rec, the_request), INTERNAL_FUNCTION_PARAM_PASSTHRU); +} +/* }}} */ + +/* {{{ proto string $request->protocol() + */ +PHP_FUNCTION(apache_request_protocol) +{ + apache_request_read_string_slot(offsetof(request_rec, protocol), INTERNAL_FUNCTION_PARAM_PASSTHRU); +} +/* }}} */ + +/* {{{ proto string $request->hostname() + */ +PHP_FUNCTION(apache_request_hostname) +{ + apache_request_read_string_slot(offsetof(request_rec, hostname), INTERNAL_FUNCTION_PARAM_PASSTHRU); +} +/* }}} */ + +/* {{{ proto string $request->status_line([string new_status_line]) + */ +PHP_FUNCTION(apache_request_status_line) +{ + apache_request_string_slot(offsetof(request_rec, status_line), INTERNAL_FUNCTION_PARAM_PASSTHRU); +} +/* }}} */ + +/* {{{ proto string $request->method() + */ +PHP_FUNCTION(apache_request_method) +{ + apache_request_read_string_slot(offsetof(request_rec, method), INTERNAL_FUNCTION_PARAM_PASSTHRU); +} +/* }}} */ + +/* }}} access string slots of request rec */ + +/* {{{ access int slots of request_rec + */ + +/* {{{ proto int $request->proto_num() + */ +PHP_FUNCTION(apache_request_proto_num) +{ + apache_request_read_int_slot(offsetof(request_rec, proto_num), INTERNAL_FUNCTION_PARAM_PASSTHRU); +} +/* }}} */ + +/* {{{ proto int $request->assbackwards() + */ +PHP_FUNCTION(apache_request_assbackwards) +{ + apache_request_read_int_slot(offsetof(request_rec, assbackwards), INTERNAL_FUNCTION_PARAM_PASSTHRU); +} +/* }}} */ + + +/* {{{ proto int $request->proxyreq([int new_proxyreq]) + */ +PHP_FUNCTION(apache_request_proxyreq) +{ + apache_request_int_slot(offsetof(request_rec, proxyreq), INTERNAL_FUNCTION_PARAM_PASSTHRU); +} +/* }}} */ + +/* {{{ proto int $request->chunked() + */ +PHP_FUNCTION(apache_request_chunked) +{ + apache_request_read_int_slot(offsetof(request_rec, chunked), INTERNAL_FUNCTION_PARAM_PASSTHRU); +} +/* }}} */ + + +/* {{{ proto int $request->header_only() + */ +PHP_FUNCTION(apache_request_header_only) +{ + apache_request_read_int_slot(offsetof(request_rec, header_only), INTERNAL_FUNCTION_PARAM_PASSTHRU); +} +/* }}} */ + +/* {{{ proto int $request->request_time() + */ +PHP_FUNCTION(apache_request_request_time) +{ + apache_request_read_int_slot(offsetof(request_rec, request_time), INTERNAL_FUNCTION_PARAM_PASSTHRU); +} +/* }}} */ + +/* {{{ proto int $request->status([int new_status]) + */ +PHP_FUNCTION(apache_request_status) +{ + apache_request_int_slot(offsetof(request_rec, status), INTERNAL_FUNCTION_PARAM_PASSTHRU); +} +/* }}} */ + +/* {{{ proto int $request->method_number([int method_number]) + */ +PHP_FUNCTION(apache_request_method_number) +{ + apache_request_read_int_slot(offsetof(request_rec, method_number), INTERNAL_FUNCTION_PARAM_PASSTHRU); +} +/* }}} */ + +/* {{{ proto int $request->allowed([int allowed]) + */ +PHP_FUNCTION(apache_request_allowed) +{ + apache_request_int_slot(offsetof(request_rec, allowed), INTERNAL_FUNCTION_PARAM_PASSTHRU); +} +/* }}} */ + +/* {{{ proto int $request->bytes_sent() + */ +PHP_FUNCTION(apache_request_bytes_sent) +{ + apache_request_read_int_slot(offsetof(request_rec, bytes_sent), INTERNAL_FUNCTION_PARAM_PASSTHRU); +} +/* }}} */ + +/* {{{ proto int $request->mtime() + */ +PHP_FUNCTION(apache_request_mtime) +{ + apache_request_read_int_slot(offsetof(request_rec, mtime), INTERNAL_FUNCTION_PARAM_PASSTHRU); +} +/* }}} */ + +/* {{{ proto int $request->content_length([int new_content_length]) + */ +PHP_FUNCTION(apache_request_content_length) +{ + zval *id, **zlen; + request_rec *r; + + if (ZEND_NUM_ARGS() == 0) { + apache_request_read_int_slot(offsetof(request_rec, clength), INTERNAL_FUNCTION_PARAM_PASSTHRU); + } + else if (ZEND_NUM_ARGS() > 1) { + WRONG_PARAM_COUNT; + } + else { + if (zend_get_parameters_ex(1, &zlen) == FAILURE) { + RETURN_FALSE; + } + + APREQ_GET_REQUEST(id, r); + + convert_to_long_ex(zlen); + (void)ap_set_content_length(r, Z_LVAL_PP(zlen)); + RETURN_TRUE; + } +} +/* }}} */ + +/* {{{ proto int $request->remaining() + */ +PHP_FUNCTION(apache_request_remaining) +{ + apache_request_read_int_slot(offsetof(request_rec, remaining), INTERNAL_FUNCTION_PARAM_PASSTHRU); +} +/* }}} */ + +/* {{{ proto int $request->no_cache() + */ +PHP_FUNCTION(apache_request_no_cache) +{ + apache_request_int_slot(offsetof(request_rec, no_cache), INTERNAL_FUNCTION_PARAM_PASSTHRU); +} +/* }}} */ + +/* {{{ proto int $request->no_local_copy() + */ +PHP_FUNCTION(apache_request_no_local_copy) +{ + apache_request_int_slot(offsetof(request_rec, no_local_copy), INTERNAL_FUNCTION_PARAM_PASSTHRU); +} +/* }}} */ + +/* {{{ proto int $request->read_body() + */ +PHP_FUNCTION(apache_request_read_body) +{ + apache_request_int_slot(offsetof(request_rec, read_body), INTERNAL_FUNCTION_PARAM_PASSTHRU); +} +/* }}} */ + + +/* }}} access int slots of request_rec */ + +/* {{{ proxy functions for the ap_* functions family + */ + +/* {{{ proto int apache_request_server_port() + */ +PHP_FUNCTION(apache_request_server_port) +{ + zval *id; + request_rec *r; + + if (ZEND_NUM_ARGS() > 0) { + WRONG_PARAM_COUNT; + } + + APREQ_GET_REQUEST(id, r); + + RETURN_LONG(ap_get_server_port(r)); +} +/* }}} */ + +/* {{{ proto int apache_request_remote_host([int type]) + */ +PHP_FUNCTION(apache_request_remote_host) +{ + zval *id, **ztype; + request_rec *r; + char *res; + int type = REMOTE_NAME; + + switch (ZEND_NUM_ARGS()) { + case 0: + break; + case 1: + if (zend_get_parameters_ex(1, &ztype) == FAILURE) { + RETURN_FALSE; + } + convert_to_long_ex(ztype); + type = Z_LVAL_PP(ztype); + break; + default: + WRONG_PARAM_COUNT; + break; + } + + + APREQ_GET_REQUEST(id, r); + + res = (char *)ap_get_remote_host(r->connection, r->per_dir_config, type); + if (res) + RETURN_STRING(res, 1); + + RETURN_EMPTY_STRING(); +} +/* }}} */ + +/* {{{ proto long apache_request_update_mtime([int dependency_mtime]) + */ +PHP_FUNCTION(apache_request_update_mtime) +{ + zval *id, **zmtime; + request_rec *r; + int mtime = 0; + + switch (ZEND_NUM_ARGS()) { + case 0: + break; + case 1: + if (zend_get_parameters_ex(1, &zmtime) == FAILURE) { + RETURN_FALSE; + } + convert_to_long_ex(zmtime); + mtime = Z_LVAL_PP(zmtime); + break; + default: + WRONG_PARAM_COUNT; + break; + } + + + APREQ_GET_REQUEST(id, r); + + RETURN_LONG(ap_update_mtime(r, mtime)); +} +/* }}} */ + + +/* {{{ proto void apache_request_set_etag() + */ +PHP_FUNCTION(apache_request_set_etag) +{ + zval *id; + request_rec *r; + + if (ZEND_NUM_ARGS() > 0) { + WRONG_PARAM_COUNT; + } + + APREQ_GET_REQUEST(id, r); + + ap_set_etag(r); + RETURN_TRUE; +} +/* }}} */ + +/* {{{ proto void apache_request_set_last_modified() + */ +PHP_FUNCTION(apache_request_set_last_modified) +{ + zval *id; + request_rec *r; + + if (ZEND_NUM_ARGS() > 0) { + WRONG_PARAM_COUNT; + } + + APREQ_GET_REQUEST(id, r); + + ap_set_last_modified(r); + RETURN_TRUE; +} +/* }}} */ + +/* {{{ proto long apache_request_meets_conditions() + */ +PHP_FUNCTION(apache_request_meets_conditions) +{ + zval *id; + request_rec *r; + + if (ZEND_NUM_ARGS() > 0) { + WRONG_PARAM_COUNT; + } + + APREQ_GET_REQUEST(id, r); + + RETURN_LONG(ap_meets_conditions(r)); +} +/* }}} */ + +/* {{{ proto long apache_request_discard_request_body() + */ +PHP_FUNCTION(apache_request_discard_request_body) +{ + zval *id; + request_rec *r; + + if (ZEND_NUM_ARGS() > 0) { + WRONG_PARAM_COUNT; + } + + APREQ_GET_REQUEST(id, r); + + RETURN_LONG(ap_discard_request_body(r)); +} +/* }}} */ + +/* {{{ proto long apache_request_satisfies() + */ +PHP_FUNCTION(apache_request_satisfies) +{ + zval *id; + request_rec *r; + + if (ZEND_NUM_ARGS() > 0) { + WRONG_PARAM_COUNT; + } + + APREQ_GET_REQUEST(id, r); + + RETURN_LONG(ap_satisfies(r)); +} +/* }}} */ + + +/* {{{ proto bool apache_request_is_initial_req() + */ +PHP_FUNCTION(apache_request_is_initial_req) +{ + zval *id; + request_rec *r; + + if (ZEND_NUM_ARGS() > 0) { + WRONG_PARAM_COUNT; + } + + APREQ_GET_REQUEST(id, r); + + RETURN_BOOL(ap_is_initial_req(r)); +} +/* }}} */ + +/* {{{ proto bool apache_request_some_auth_required() + */ +PHP_FUNCTION(apache_request_some_auth_required) +{ + zval *id; + request_rec *r; + + if (ZEND_NUM_ARGS() > 0) { + WRONG_PARAM_COUNT; + } + + APREQ_GET_REQUEST(id, r); + + RETURN_BOOL(ap_some_auth_required(r)); +} +/* }}} */ + +/* {{{ proto string apache_request_auth_type() + */ +PHP_FUNCTION(apache_request_auth_type) +{ + zval *id; + request_rec *r; + char *t; + + if (ZEND_NUM_ARGS() > 0) { + WRONG_PARAM_COUNT; + } + + APREQ_GET_REQUEST(id, r); + + t = (char *)ap_auth_type(r); + if (!t) + RETURN_NULL(); + + RETURN_STRING(t, 1); +} +/* }}} */ + +/* {{{ proto string apache_request_auth_name() + */ +PHP_FUNCTION(apache_request_auth_name) +{ + zval *id; + request_rec *r; + char *t; + + if (ZEND_NUM_ARGS() > 0) { + WRONG_PARAM_COUNT; + } + + APREQ_GET_REQUEST(id, r); + + t = (char *)ap_auth_name(r); + if (!t) + RETURN_NULL(); + + RETURN_STRING(t, 1); +} +/* }}} */ + +/* {{{ proto apache_request_basic_auth_pw() + */ +PHP_FUNCTION(apache_request_basic_auth_pw) +{ + zval *id, *zpw; + request_rec *r; + const char *pw; + long status; + + if (ZEND_NUM_ARGS() != 1) { + WRONG_PARAM_COUNT; + } + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z", &zpw) == FAILURE) { + RETURN_NULL(); + } + + if (!PZVAL_IS_REF(zpw)) { + zend_error(E_WARNING, "Parameter wasn't passed by reference"); + RETURN_NULL(); + } + + + APREQ_GET_REQUEST(id, r); + + pw = NULL; + status = ap_get_basic_auth_pw(r, &pw); + if (status == OK && pw) { + ZVAL_STRING(zpw, (char *)pw, 1); + } + else + ZVAL_NULL(zpw); + RETURN_LONG(status); +} +/* }}} */ + + + + +/* }}} */ + +/* {{{ php_apache_request_class_functions + */ +static function_entry php_apache_request_class_functions[] = { + /* string slots */ + PHP_FALIAS(args, apache_request_args, NULL) + PHP_FALIAS(boundary, apache_request_boundary, NULL) + PHP_FALIAS(content_encoding, apache_request_content_encoding, NULL) + PHP_FALIAS(content_type, apache_request_content_type, NULL) + PHP_FALIAS(filename, apache_request_filename, NULL) + PHP_FALIAS(handler, apache_request_handler, NULL) + PHP_FALIAS(hostname, apache_request_hostname, NULL) + PHP_FALIAS(method, apache_request_method, NULL) + PHP_FALIAS(path_info, apache_request_path_info, NULL) + PHP_FALIAS(protocol, apache_request_protocol, NULL) + PHP_FALIAS(status_line, apache_request_status_line, NULL) + PHP_FALIAS(the_request, apache_request_the_request, NULL) + PHP_FALIAS(unparsed_uri, apache_request_unparsed_uri, NULL) + PHP_FALIAS(uri, apache_request_uri, NULL) + + /* int slots */ + PHP_FALIAS(allowed, apache_request_allowed, NULL) + PHP_FALIAS(bytes_sent, apache_request_bytes_sent, NULL) + PHP_FALIAS(chunked, apache_request_chunked, NULL) + PHP_FALIAS(content_length, apache_request_content_length, NULL) + PHP_FALIAS(header_only, apache_request_header_only, NULL) + PHP_FALIAS(method_number, apache_request_method_number, NULL) + PHP_FALIAS(mtime, apache_request_mtime, NULL) + PHP_FALIAS(no_cache, apache_request_no_cache, NULL) + PHP_FALIAS(no_local_copy, apache_request_no_local_copy, NULL) + PHP_FALIAS(proto_num, apache_request_proto_num, NULL) + PHP_FALIAS(proxyreq, apache_request_proxyreq, NULL) + PHP_FALIAS(read_body, apache_request_read_body, NULL) + PHP_FALIAS(remaining, apache_request_remaining, NULL) + PHP_FALIAS(request_time, apache_request_request_time, NULL) + PHP_FALIAS(status, apache_request_status, NULL) + + /* proxy functions for the ap_* functions family */ +#undef auth_name +#undef auth_type +#undef discard_request_body +#undef is_initial_req +#undef meets_conditions +#undef satisfies +#undef set_etag +#undef set_last_modified +#undef some_auth_required +#undef update_mtime + PHP_FALIAS(auth_name, apache_request_auth_name, NULL) + PHP_FALIAS(auth_type, apache_request_auth_type, NULL) + PHP_FALIAS(basic_auth_pw, apache_request_basic_auth_pw, NULL) + PHP_FALIAS(discard_request_body, apache_request_discard_request_body, NULL) + PHP_FALIAS(is_initial_req, apache_request_is_initial_req, NULL) + PHP_FALIAS(meets_conditions, apache_request_meets_conditions, NULL) + PHP_FALIAS(remote_host, apache_request_remote_host, NULL) + PHP_FALIAS(satisfies, apache_request_satisfies, NULL) + PHP_FALIAS(server_port, apache_request_server_port, NULL) + PHP_FALIAS(set_etag, apache_request_set_etag, NULL) + PHP_FALIAS(set_last_modified, apache_request_set_last_modified, NULL) + PHP_FALIAS(some_auth_required, apache_request_some_auth_required, NULL) + PHP_FALIAS(update_mtime, apache_request_update_mtime, NULL) + + { NULL, NULL, NULL } +}; +/* }}} */ + + static PHP_MINIT_FUNCTION(apache) { + zend_class_entry ce; + #ifdef ZTS - ts_allocate_id(&php_apache_info_id, sizeof(php_apache_info_struct), php_apache_globals_ctor, NULL); + ts_allocate_id(&php_apache_info_id, sizeof(php_apache_info_struct), (ts_allocate_ctor) php_apache_globals_ctor, NULL); #else php_apache_globals_ctor(&php_apache_info TSRMLS_CC); #endif REGISTER_INI_ENTRIES(); + + + le_apachereq = zend_register_list_destructors_ex(php_apache_request_free, NULL, "ApacheRequest", module_number); + INIT_OVERLOADED_CLASS_ENTRY(ce, "ApacheRequest", php_apache_request_class_functions, NULL, NULL, NULL); + apacherequest_class_entry = zend_register_internal_class_ex(&ce, NULL, NULL TSRMLS_CC); + + REGISTER_LONG_CONSTANT("OK", OK, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("DECLINED", DECLINED, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("FORBIDDEN", FORBIDDEN, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("AUTH_REQUIRED", AUTH_REQUIRED, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("DONE", DONE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("SERVER_ERROR", SERVER_ERROR, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("REDIRECT", REDIRECT, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("BAD_REQUEST", BAD_REQUEST, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("NOT_FOUND", NOT_FOUND, CONST_CS | CONST_PERSISTENT); + + REGISTER_LONG_CONSTANT("M_GET", M_GET, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("M_PUT", M_PUT, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("M_POST", M_POST, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("M_DELETE", M_DELETE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("M_CONNECT", M_CONNECT, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("M_OPTIONS", M_OPTIONS, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("M_TRACE", M_TRACE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("M_PATCH", M_PATCH, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("M_PROPFIND", M_PROPFIND, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("M_PROPPATCH", M_PROPPATCH, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("M_MKCOL", M_MKCOL, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("M_COPY", M_COPY, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("M_MOVE", M_MOVE, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("M_LOCK", M_LOCK, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("M_UNLOCK", M_UNLOCK, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("M_INVALID", M_INVALID, CONST_CS | CONST_PERSISTENT); + + /* Possible values for request_rec.read_body (set by handling module): + * REQUEST_NO_BODY Send 413 error if message has any body + * REQUEST_CHUNKED_ERROR Send 411 error if body without Content-Length + * REQUEST_CHUNKED_DECHUNK If chunked, remove the chunks for me. + * REQUEST_CHUNKED_PASS Pass the chunks to me without removal. + */ + REGISTER_LONG_CONSTANT("REQUEST_NO_BODY", REQUEST_NO_BODY, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("REQUEST_CHUNKED_ERROR", REQUEST_CHUNKED_ERROR, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("REQUEST_CHUNKED_DECHUNK", REQUEST_CHUNKED_DECHUNK, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("REQUEST_CHUNKED_PASS", REQUEST_CHUNKED_PASS, CONST_CS | CONST_PERSISTENT); + + /* resolve types for remote_host() */ + REGISTER_LONG_CONSTANT("REMOTE_HOST", REMOTE_HOST, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("REMOTE_NAME", REMOTE_NAME, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("REMOTE_NOLOOKUP", REMOTE_NOLOOKUP, CONST_CS | CONST_PERSISTENT); + REGISTER_LONG_CONSTANT("REMOTE_DOUBLE_REV", REMOTE_DOUBLE_REV, CONST_CS | CONST_PERSISTENT); + return SUCCESS; } @@ -116,23 +966,34 @@ static PHP_MSHUTDOWN_FUNCTION(apache) return SUCCESS; } - zend_module_entry apache_module_entry = { - "apache", apache_functions, PHP_MINIT(apache), PHP_MSHUTDOWN(apache), NULL, NULL, PHP_MINFO(apache), STANDARD_MODULE_PROPERTIES + STANDARD_MODULE_HEADER, + "apache", + apache_functions, + PHP_MINIT(apache), + PHP_MSHUTDOWN(apache), + NULL, + NULL, + PHP_MINFO(apache), + NO_VERSION_YET, + STANDARD_MODULE_PROPERTIES }; -/* {{{ proto string child_terminate() - Get and set Apache request notes */ +/* {{{ proto bool apache_child_terminate(void) + Terminate apache process after this request */ PHP_FUNCTION(apache_child_terminate) { #ifndef MULTITHREAD if (AP(terminate_child)) { ap_child_terminate( ((request_rec *)SG(server_context)) ); + RETURN_TRUE; } else { /* tell them to get lost! */ php_error(E_WARNING, "apache.child_terminate is disabled"); + RETURN_FALSE; } #else php_error(E_WARNING, "apache_child_terminate() is not supported in this build"); + RETURN_FALSE; #endif } /* }}} */ @@ -193,6 +1054,10 @@ PHP_MINFO_FUNCTION(apache) php_info_print_table_row(1, "Apache for Windows 95/NT"); php_info_print_table_end(); php_info_print_table_start(); +#elif defined(NETWARE) + php_info_print_table_row(1, "Apache for NetWare"); + php_info_print_table_end(); + php_info_print_table_start(); #else php_info_print_table_row(2, "APACHE_INCLUDE", PHP_APACHE_INCLUDE); php_info_print_table_row(2, "APACHE_TARGET", PHP_APACHE_TARGET); @@ -211,12 +1076,16 @@ PHP_MINFO_FUNCTION(apache) #if !defined(WIN32) && !defined(WINNT) sprintf(output_buf, "%s(%d)/%d", user_name, (int)user_id, (int)group_id); php_info_print_table_row(2, "User/Group", output_buf); - sprintf(output_buf, "Per Child: %d<br>Keep Alive: %s<br>Max Per Connection: %d", max_requests_per_child, serv->keep_alive ? "on":"off", serv->keep_alive_max); + sprintf(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); php_info_print_table_row(2, "Max Requests", output_buf); #endif - sprintf(output_buf, "Connection: %d<br>Keep-Alive: %d", serv->timeout, serv->keep_alive_timeout); + sprintf(output_buf, "Connection: %d - Keep-Alive: %d", serv->timeout, serv->keep_alive_timeout); php_info_print_table_row(2, "Timeouts", output_buf); #if !defined(WIN32) && !defined(WINNT) +/* + This block seems to be working on NetWare; But it seems to be showing + all modules instead of just the loaded ones +*/ php_info_print_table_row(2, "Server Root", server_root); strcpy(modulenames, ""); @@ -270,7 +1139,7 @@ PHP_MINFO_FUNCTION(apache) env_arr = table_elts(r->headers_in); env = (table_entry *)env_arr->elts; for (i = 0; i < env_arr->nelts; ++i) { - if (env[i].key) { + if (env[i].key && (!PG(safe_mode) || (PG(safe_mode) && strncasecmp(env[i].key, "authorization", 13)))) { php_info_print_table_row(2, env[i].key, env[i].val); } } @@ -287,7 +1156,7 @@ PHP_MINFO_FUNCTION(apache) } /* }}} */ -/* {{{ proto int virtual(string filename) +/* {{{ proto bool virtual(string filename) Perform an Apache sub-request */ /* This function is equivalent to <!--#include virtual...--> * in mod_include. It does an Apache sub-request. It is useful @@ -334,8 +1203,11 @@ PHP_FUNCTION(virtual) /* }}} */ /* {{{ proto array getallheaders(void) + Alias for apache_request_headers() */ +/* }}} */ +/* {{{ proto array apache_request_headers(void) Fetch all HTTP request headers */ -PHP_FUNCTION(getallheaders) +PHP_FUNCTION(apache_request_headers) { array_header *env_arr; table_entry *tenv; @@ -359,7 +1231,51 @@ PHP_FUNCTION(getallheaders) } /* }}} */ -/* {{{ proto class apache_lookup_uri(string URI) +/* {{{ proto array apache_response_headers(void) + Fetch all HTTP response headers */ +PHP_FUNCTION(apache_response_headers) +{ + array_header *env_arr; + table_entry *tenv; + int i; + + if (array_init(return_value) == FAILURE) { + RETURN_FALSE; + } + env_arr = table_elts(((request_rec *) SG(server_context))->headers_out); + tenv = (table_entry *)env_arr->elts; + for (i = 0; i < env_arr->nelts; ++i) { + if (!tenv[i].key) continue; + if (add_assoc_string(return_value, tenv[i].key, (tenv[i].val==NULL) ? "" : tenv[i].val, 1)==FAILURE) { + RETURN_FALSE; + } + } +} +/* }}} */ + +/* {{{ proto bool apache_setenv(string variable, string value [, bool walk_to_top]) + Set an Apache subprocess_env variable */ +PHP_FUNCTION(apache_setenv) +{ + int var_len, val_len, top=0; + char *var = NULL, *val = NULL; + request_rec *r = (request_rec *) SG(server_context); + + if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|b", &var, &var_len, &val, &val_len, &top) == FAILURE) { + RETURN_FALSE; + } + + while(top) { + if(r->prev) r = r->prev; + else break; + } + + ap_table_setn(r->subprocess_env, ap_pstrndup(r->pool, var, var_len), ap_pstrndup(r->pool, val, val_len)); + RETURN_TRUE; +} +/* }}} */ + +/* {{{ proto object apache_lookup_uri(string URI) Perform a partial request of the given URI to obtain information about it */ PHP_FUNCTION(apache_lookup_uri) { @@ -460,6 +1376,6 @@ PHP_FUNCTION(apache_exec_uri) * tab-width: 4 * c-basic-offset: 4 * End: - * vim600: sw=4 ts=4 tw=78 fdm=marker - * vim<600: sw=4 ts=4 tw=78 + * vim600: sw=4 ts=4 fdm=marker + * vim<600: sw=4 ts=4 */ diff --git a/sapi/apache/php_apache_http.h b/sapi/apache/php_apache_http.h index 56590fb822..ed2ce6fb99 100644 --- a/sapi/apache/php_apache_http.h +++ b/sapi/apache/php_apache_http.h @@ -36,3 +36,7 @@ #include "ext/standard/php_standard.h" #include "mod_php4.h" + + +PHPAPI zval *php_apache_request_new(request_rec *r); + diff --git a/sapi/apache/sapi_apache.c b/sapi/apache/sapi_apache.c index 0599863241..2516a02c43 100644 --- a/sapi/apache/sapi_apache.c +++ b/sapi/apache/sapi_apache.c @@ -1,8 +1,8 @@ /* +----------------------------------------------------------------------+ - | PHP version 4.0 | + | PHP Version 4 | +----------------------------------------------------------------------+ - | Copyright (c) 1997-2001 The PHP Group | + | Copyright (c) 1997-2002 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 2.02 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | @@ -21,42 +21,7 @@ */ /* $Id$ */ -#define NO_REGEX_EXTRA_H -#ifdef WIN32 -#include <winsock2.h> -#include <stddef.h> -#endif - -#include "php.h" - -#include "httpd.h" -#include "http_config.h" -#if MODULE_MAGIC_NUMBER > 19980712 -# include "ap_compat.h" -#else -# if MODULE_MAGIC_NUMBER > 19980324 -# include "compat.h" -# endif -#endif -#include "http_core.h" -#include "http_main.h" -#include "http_protocol.h" -#include "http_request.h" -#include "http_log.h" - -#include "zend.h" -#include "php_ini.h" -#include "php_globals.h" -#include "SAPI.h" -#include "php_main.h" -#include "zend_compile.h" -#include "zend_execute.h" -#include "zend_highlight.h" -#include "zend_indent.h" -#include "ext/standard/php_standard.h" -#include "util_script.h" -#include "php_version.h" -#include "mod_php4.h" +#include "php_apache_http.h" /* {{{ apache_php_module_main */ @@ -92,10 +57,6 @@ int apache_php_module_main(request_rec *r, int display_source_mode TSRMLS_DC) AP(in_request) = 0; - zend_try { - php_request_shutdown(NULL); - } zend_end_try(); - return (OK); } /* }}} */ @@ -105,40 +66,46 @@ int apache_php_module_main(request_rec *r, int display_source_mode TSRMLS_DC) int apache_php_module_hook(request_rec *r, char *filename, zval **ret TSRMLS_DC) { zend_file_handle file_handle; + zval *req; #if PHP_SIGCHILD - signal(SIGCHLD, sigchld_handler); + signal(SIGCHLD, sigchld_handler); #endif - if (php_request_startup_for_hook(TSRMLS_C) == FAILURE) { - return FAILURE; - } + if (php_request_startup_for_hook(TSRMLS_C) == FAILURE) + return FAILURE; + /* Add PHP_SELF_HOOK - Absolute path */ php_register_variable("PHP_SELF_HOOK", filename, PG(http_globals)[TRACK_VARS_SERVER] TSRMLS_CC); + req = php_apache_request_new(r); + if(PG(register_globals)) { + php_register_variable_ex("request", req, NULL TSRMLS_CC); + } + else { + php_register_variable_ex("request", req, PG(http_globals)[TRACK_VARS_SERVER] TSRMLS_CC); + } + memset(&file_handle, 0, sizeof(file_handle)); file_handle.type = ZEND_HANDLE_FILENAME; - file_handle.handle.fd = 0; file_handle.filename = filename; - file_handle.opened_path = NULL; - file_handle.free_filename = 0; (void) php_execute_simple_script(&file_handle, ret TSRMLS_CC); + zval_dtor(&req); AP(in_request) = 0; - - zend_try { - php_request_shutdown_for_hook(NULL); - } zend_end_try(); - - return (OK); + + return OK; } +/* }}} */ + + /* * Local variables: * tab-width: 4 * c-basic-offset: 4 * End: - * vim600: sw=4 ts=4 tw=78 fdm=marker - * vim<600: sw=4 ts=4 tw=78 + * vim600: sw=4 ts=4 fdm=marker + * vim<600: sw=4 ts=4 */ |