📄 mod_php4.c
字号:
/* +----------------------------------------------------------------------+ | PHP Version 4 | +----------------------------------------------------------------------+ | Copyright (c) 1997-2007 The PHP Group | +----------------------------------------------------------------------+ | This source file is subject to version 3.01 of the PHP license, | | that is bundled with this package in the file LICENSE, and is | | available through the world-wide-web at the following url: | | http://www.php.net/license/3_01.txt | | If you did not receive a copy of the PHP license and are unable to | | 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> | | (with helpful hints from Dean Gaudet <dgaudet@arctic.org> | | PHP 4.0 patches by Zeev Suraski <zeev@zend.com> | +----------------------------------------------------------------------+ *//* $Id: mod_php4.c,v 1.146.2.15.2.4 2007/01/01 09:46:51 sebastian Exp $ */#include "php_apache_http.h"#include "http_conf_globals.h"#ifdef NETWARE#define SIGPIPE SIGINT#endif#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);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);static int php_xbithack_handler(request_rec * r);static void php_init_handler(server_rec *s, pool *p);/* }}} */#if MODULE_MAGIC_NUMBER >= 19970728static void php_child_exit_handler(server_rec *s, pool *p);#endif#if MODULE_MAGIC_NUMBER > 19961007#define CONST_PREFIX const#else#define CONST_PREFIX#endifstatic 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#define IGNORE_URL 2module MODULE_VAR_EXPORT php4_module;int saved_umask;static unsigned char apache_php_initialized;typedef struct _php_per_dir_entry { char *key; char *value; uint key_length; uint value_length; int type;} php_per_dir_entry;/* some systems are missing these from their header files *//* {{{ php_save_umask */static void php_save_umask(void){ saved_umask = umask(077); umask(saved_umask);}/* }}} *//* {{{ sapi_apache_ub_write */static int sapi_apache_ub_write(const char *str, uint str_length TSRMLS_DC){ int ret=0; if (SG(server_context)) { ret = rwrite(str, str_length, (request_rec *) SG(server_context)); } if (ret != str_length) { php_handle_aborted_connection(); } return ret;}/* }}} *//* {{{ sapi_apache_flush */static void sapi_apache_flush(void *server_context){ if (server_context) {#if MODULE_MAGIC_NUMBER > 19970110 rflush((request_rec *) server_context);#else bflush((request_rec *) server_context->connection->client);#endif }}/* }}} *//* {{{ sapi_apache_read_post */static int sapi_apache_read_post(char *buffer, uint count_bytes TSRMLS_DC){ int 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 */ read_bytes = get_client_block(r, buffer+total_read_bytes, count_bytes-total_read_bytes); reset_timeout(r); if (read_bytes<=0) { break; } total_read_bytes += read_bytes; } signal(SIGPIPE, handler); return total_read_bytes;}/* }}} *//* {{{ sapi_apache_read_cookies */static char *sapi_apache_read_cookies(TSRMLS_D){ return (char *) table_get(((request_rec *) SG(server_context))->subprocess_env, "HTTP_COOKIE");}/* }}} *//* {{{ sapi_apache_header_handler */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); if(!r) { efree(sapi_header->header); return 0; } header_name = sapi_header->header; header_content = p = strchr(header_name, ':'); if (!p) { efree(sapi_header->header); return 0; } *p = 0; do { header_content++; } while (*header_content==' '); if (!strcasecmp(header_name, "Content-Type")) { r->content_type = pstrdup(r->pool, header_content); } else if (!strcasecmp(header_name, "Set-Cookie")) { table_add(r->headers_out, header_name, header_content); } else if (sapi_header->replace) { table_set(r->headers_out, header_name, header_content); } else { table_add(r->headers_out, header_name, header_content); } *p = ':'; /* a well behaved header handler shouldn't change its original arguments */ efree(sapi_header->header); return 0; /* don't use the default SAPI mechanism, Apache duplicates this functionality */}/* }}} *//* {{{ sapi_apache_send_headers */static int sapi_apache_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC){ request_rec *r = SG(server_context); if(r == NULL) { /* server_context is not here anymore */ return SAPI_HEADER_SEND_FAILED; } r->status = SG(sapi_headers).http_response_code; if(r->status==304) { send_error_response(r,0); } else { send_http_header(r); } return SAPI_HEADER_SENT_SUCCESSFULLY;}/* }}} *//* {{{ sapi_apache_register_server_variables */static void sapi_apache_register_server_variables(zval *track_vars_array TSRMLS_DC){ register int i; array_header *arr = table_elts(((request_rec *) SG(server_context))->subprocess_env); table_entry *elts = (table_entry *) arr->elts; zval **path_translated; HashTable *symbol_table; for (i = 0; i < arr->nelts; i++) { char *val; if (elts[i].val) { val = elts[i].val; } else { val = empty_string; } php_register_variable(elts[i].key, val, track_vars_array TSRMLS_CC); } /* If PATH_TRANSLATED doesn't exist, copy it from SCRIPT_FILENAME */ if (track_vars_array) { symbol_table = track_vars_array->value.ht; } else if (PG(register_globals)) { /* should never happen nowadays */ symbol_table = EG(active_symbol_table); } else { symbol_table = NULL; } if (symbol_table && !zend_hash_exists(symbol_table, "PATH_TRANSLATED", sizeof("PATH_TRANSLATED")) && zend_hash_find(symbol_table, "SCRIPT_FILENAME", sizeof("SCRIPT_FILENAME"), (void **) &path_translated)==SUCCESS) { php_register_variable("PATH_TRANSLATED", Z_STRVAL_PP(path_translated), track_vars_array TSRMLS_CC); } php_register_variable("PHP_SELF", ((request_rec *) SG(server_context))->uri, track_vars_array TSRMLS_CC);}/* }}} *//* {{{ php_apache_startup */static int php_apache_startup(sapi_module_struct *sapi_module){ if (php_module_startup(sapi_module, &apache_module_entry, 1) == FAILURE) { return FAILURE; } else { return SUCCESS; }}/* }}} *//* {{{ php_apache_log_message */static void php_apache_log_message(char *message){ TSRMLS_FETCH(); if (SG(server_context)) {#if MODULE_MAGIC_NUMBER >= 19970831 aplog_error(NULL, 0, APLOG_ERR | APLOG_NOERRNO, ((request_rec *) SG(server_context))->server, "%s", message);#else log_error(message, ((request_rec *) SG(server_context))->server);#endif } else { fprintf(stderr, "%s\n", message); }}/* }}} *//* {{{ php_apache_request_shutdown */static void php_apache_request_shutdown(void *dummy){ TSRMLS_FETCH(); php_output_set_status(0 TSRMLS_CC); if (AP(in_request)) { AP(in_request) = 0; php_request_shutdown(dummy); } SG(server_context) = NULL; /* The server context (request) is NOT invalid by the time * run_cleanups() is called */}/* }}} *//* {{{ php_apache_sapi_activate */static int php_apache_sapi_activate(TSRMLS_D){ request_rec *r = (request_rec *) SG(server_context); /* * For the Apache module version, this bit of code registers a cleanup * function that gets triggered when our request pool is destroyed. * We need this because at any point in our code we can be interrupted * and that may happen before we have had time to free our memory. * The php_request_shutdown function needs to free all outstanding allocated * memory. */ block_alarms(); register_cleanup(r->pool, NULL, php_apache_request_shutdown, php_request_shutdown_for_exec); AP(in_request)=1; unblock_alarms(); /* Override the default headers_only value - sometimes "GET" requests should actually only * send headers. */ SG(request_info).headers_only = r->header_only; return SUCCESS;}/* }}} *//* {{{ php_apache_get_stat */static struct stat *php_apache_get_stat(TSRMLS_D){ return &((request_rec *) SG(server_context))->finfo;}/* }}} *//* {{{ php_apache_getenv */static char *php_apache_getenv(char *name, size_t name_len TSRMLS_DC){ return (char *) table_get(((request_rec *) SG(server_context))->subprocess_env, name);}/* }}} *//* {{{ sapi_apache_get_fd */static int sapi_apache_get_fd(int *nfd TSRMLS_DC){#if PHP_APACHE_HAVE_CLIENT_FD request_rec *r = SG(server_context); int fd; fd = r->connection->client->fd; if (fd >= 0) { if (nfd) *nfd = fd; return SUCCESS; }#endif return FAILURE;}/* }}} *//* {{{ sapi_apache_force_http_10 */static int sapi_apache_force_http_10(TSRMLS_D){ request_rec *r = SG(server_context); r->proto_num = HTTP_VERSION(1,0); return SUCCESS;}/* }}} *//* {{{ sapi_apache_get_target_uid */static int sapi_apache_get_target_uid(uid_t *obj TSRMLS_DC){ *obj = ap_user_id; return SUCCESS;}/* }}} *//* {{{ sapi_apache_get_target_gid */static int sapi_apache_get_target_gid(gid_t *obj TSRMLS_DC){ *obj = ap_group_id; return SUCCESS;}/* }}} *//* {{{ sapi_module_struct apache_sapi_module */static sapi_module_struct apache_sapi_module = { "apache", /* name */ "Apache", /* pretty name */ php_apache_startup, /* startup */ php_module_shutdown_wrapper, /* shutdown */ php_apache_sapi_activate, /* activate */ NULL, /* deactivate */ sapi_apache_ub_write, /* unbuffered write */ sapi_apache_flush, /* flush */ php_apache_get_stat, /* get uid */ php_apache_getenv, /* getenv */ php_error, /* error handler */ sapi_apache_header_handler, /* header handler */ sapi_apache_send_headers, /* send headers handler */ NULL, /* send header handler */ sapi_apache_read_post, /* read POST data */ sapi_apache_read_cookies, /* read Cookies */ sapi_apache_register_server_variables, /* register server variables */ php_apache_log_message, /* Log message */ NULL, /* php.ini path override */#ifdef PHP_WIN32 NULL, NULL,#else block_alarms, /* Block interruptions */ unblock_alarms, /* Unblock interruptions */#endif NULL, /* default post reader */ NULL, /* treat data */ NULL, /* exe location */ 0, /* ini ignore */ sapi_apache_get_fd, sapi_apache_force_http_10, sapi_apache_get_target_uid, sapi_apache_get_target_gid};/* }}} *//* {{{ php_restore_umask */static void php_restore_umask(void){ umask(saved_umask);}/* }}} *//* {{{ init_request_info */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, *tmp_user; SG(request_info).query_string = r->args; SG(request_info).path_translated = r->filename; SG(request_info).request_uri = r->uri; SG(request_info).request_method = (char *)r->method; SG(request_info).content_type = (char *) table_get(r->subprocess_env, "CONTENT_TYPE"); SG(request_info).content_length = (content_length ? atoi(content_length) : 0); SG(sapi_headers).http_response_code = r->status; if (r->headers_in) { authorization = table_get(r->headers_in, "Authorization"); } if (authorization
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -