2003-02-11 17:40:11 +00:00
/*
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2004-01-08 08:18:22 +00:00
| PHP Version 5 |
2003-02-11 17:40:11 +00:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2006-01-01 12:51:34 +00:00
| Copyright ( c ) 1997 - 2006 The PHP Group |
2003-02-11 17:40:11 +00:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2006-01-01 12:51:34 +00:00
| This source file is subject to version 3.01 of the PHP license , |
2003-02-11 17:40:11 +00:00
| that is bundled with this package in the file LICENSE , and is |
2003-06-10 20:04:29 +00:00
| available through the world - wide - web at the following url : |
2006-01-01 12:51:34 +00:00
| http : //www.php.net/license/3_01.txt |
2003-02-11 17:40:11 +00:00
| 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 : Sascha Schumann < sascha @ schumann . cx > |
| Parts based on Apache 1.3 SAPI module by |
| Rasmus Lerdorf and Zeev Suraski |
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
*/
/* $Id$ */
2003-03-25 11:50:18 +00:00
# define ZEND_INCLUDE_FULL_WINDOWS_HEADERS
2003-02-11 17:40:11 +00:00
# include "php.h"
# include "php_main.h"
# include "php_ini.h"
# include "php_variables.h"
# include "SAPI.h"
2003-12-19 18:28:56 +00:00
# include <fcntl.h>
2003-02-11 17:40:11 +00:00
# include "ext/standard/php_smart_str.h"
# ifndef NETWARE
# include "ext/standard/php_standard.h"
# else
# include "ext/standard/basic_functions.h"
# endif
# include "apr_strings.h"
# include "ap_config.h"
# include "util_filter.h"
# include "httpd.h"
# include "http_config.h"
# include "http_request.h"
# include "http_core.h"
# include "http_protocol.h"
# include "http_log.h"
# include "http_main.h"
# include "util_script.h"
2004-06-25 13:00:48 +00:00
# include "http_core.h"
2003-02-11 17:40:11 +00:00
# include "ap_mpm.h"
# include "php_apache.h"
2003-03-05 16:12:23 +00:00
/* UnixWare and Netware define shutdown to _shutdown, which causes problems later
* on when using a structure member named shutdown . Since this source
2004-03-16 22:38:07 +00:00
* file does not use the system call shutdown , it is safe to # undef it . K
2003-03-05 16:12:23 +00:00
*/
# undef shutdown
2004-06-25 13:00:48 +00:00
2003-02-20 18:20:03 +00:00
# define PHP_MAGIC_TYPE "application / x-httpd-php"
# define PHP_SOURCE_MAGIC_TYPE "application / x-httpd-php-source"
2003-10-21 11:48:31 +00:00
# define PHP_SCRIPT "php5-script"
2003-02-20 18:20:03 +00:00
2003-02-11 17:40:11 +00:00
/* A way to specify the location of the php.ini dir in an apache directive */
char * apache2_php_ini_path_override = NULL ;
static int
php_apache_sapi_ub_write ( const char * str , uint str_length TSRMLS_DC )
{
2003-02-20 18:20:03 +00:00
request_rec * r ;
2003-02-11 17:40:11 +00:00
php_struct * ctx ;
ctx = SG ( server_context ) ;
2003-02-20 18:20:03 +00:00
r = ctx - > r ;
2003-02-11 17:40:11 +00:00
2004-06-25 13:00:48 +00:00
if ( ap_rwrite ( str , str_length , r ) < 0 ) {
2003-02-11 17:40:11 +00:00
php_handle_aborted_connection ( ) ;
}
2004-06-25 13:00:48 +00:00
2003-02-11 17:40:11 +00:00
return str_length ; /* we always consume all the data passed to us. */
}
static int
2003-02-20 18:20:03 +00:00
php_apache_sapi_header_handler ( sapi_header_struct * sapi_header , sapi_headers_struct * sapi_headers TSRMLS_DC )
2003-02-11 17:40:11 +00:00
{
php_struct * ctx ;
2006-03-19 14:54:53 +00:00
char * val , * ptr ;
2003-02-11 17:40:11 +00:00
ctx = SG ( server_context ) ;
val = strchr ( sapi_header - > header , ' : ' ) ;
if ( ! val ) {
sapi_free_header ( sapi_header ) ;
return 0 ;
}
2006-03-19 14:54:53 +00:00
ptr = val ;
2003-02-11 17:40:11 +00:00
* val = ' \0 ' ;
do {
val + + ;
} while ( * val = = ' ' ) ;
2003-02-20 18:20:03 +00:00
if ( ! strcasecmp ( sapi_header - > header , " content-type " ) ) {
2006-05-28 20:32:00 +00:00
if ( ctx - > content_type ) {
efree ( ctx - > content_type ) ;
}
ctx - > content_type = estrdup ( val ) ;
2003-03-07 13:45:33 +00:00
} else if ( sapi_header - > replace ) {
2003-02-11 17:40:11 +00:00
apr_table_set ( ctx - > r - > headers_out , sapi_header - > header , val ) ;
2003-03-07 13:45:33 +00:00
} else {
2003-02-11 17:40:11 +00:00
apr_table_add ( ctx - > r - > headers_out , sapi_header - > header , val ) ;
2003-02-20 18:20:03 +00:00
}
2006-03-19 14:54:53 +00:00
* ptr = ' : ' ;
2003-02-11 17:40:11 +00:00
2005-06-20 12:46:34 +00:00
return SAPI_HEADER_ADD ;
2003-02-11 17:40:11 +00:00
}
static int
php_apache_sapi_send_headers ( sapi_headers_struct * sapi_headers TSRMLS_DC )
{
php_struct * ctx = SG ( server_context ) ;
2005-01-17 12:24:40 +00:00
const char * sline = SG ( sapi_headers ) . http_status_line ;
2003-02-11 17:40:11 +00:00
ctx - > r - > status = SG ( sapi_headers ) . http_response_code ;
2005-01-17 12:24:40 +00:00
/* httpd requires that r->status_line is set to the first digit of
* the status - code : */
if ( sline & & strlen ( sline ) > 12 & & strncmp ( sline , " HTTP/1. " , 7 ) = = 0
& & sline [ 8 ] = = ' ' ) {
ctx - > r - > status_line = apr_pstrdup ( ctx - > r - > pool , sline + 9 ) ;
}
2006-05-28 20:32:00 +00:00
/* call ap_set_content_type only once, else each time we call it,
configured output filters for that content type will be added */
if ( ! ctx - > content_type ) {
ctx - > content_type = sapi_get_default_content_type ( TSRMLS_C ) ;
}
ap_set_content_type ( ctx - > r , apr_pstrdup ( ctx - > r - > pool , ctx - > content_type ) ) ;
efree ( ctx - > content_type ) ;
ctx - > content_type = NULL ;
2005-01-17 12:24:40 +00:00
2003-02-11 17:40:11 +00:00
return SAPI_HEADER_SENT_SUCCESSFULLY ;
}
static int
php_apache_sapi_read_post ( char * buf , uint count_bytes TSRMLS_DC )
{
2003-03-25 01:34:32 +00:00
apr_size_t len , tlen = 0 ;
2003-02-20 18:20:03 +00:00
php_struct * ctx = SG ( server_context ) ;
request_rec * r ;
apr_bucket_brigade * brigade ;
2003-02-11 17:40:11 +00:00
2003-02-20 18:20:03 +00:00
r = ctx - > r ;
brigade = ctx - > brigade ;
len = count_bytes ;
2003-02-11 17:40:11 +00:00
2003-03-25 01:34:32 +00:00
/*
* This loop is needed because ap_get_brigade ( ) can return us partial data
* which would cause premature termination of request read . Therefor we
2004-12-16 12:34:32 +00:00
* need to make sure that if data is available we fill the buffer completely .
2003-03-25 01:34:32 +00:00
*/
2003-02-20 18:20:03 +00:00
2003-03-25 01:34:32 +00:00
while ( ap_get_brigade ( r - > input_filters , brigade , AP_MODE_READBYTES , APR_BLOCK_READ , len ) = = APR_SUCCESS ) {
2003-02-20 18:20:03 +00:00
apr_brigade_flatten ( brigade , buf , & len ) ;
2003-03-25 01:34:32 +00:00
apr_brigade_cleanup ( brigade ) ;
tlen + = len ;
if ( tlen = = count_bytes | | ! len ) {
break ;
}
buf + = len ;
len = count_bytes - tlen ;
2003-02-20 18:20:03 +00:00
}
2003-02-11 17:40:11 +00:00
2003-03-25 01:34:32 +00:00
return tlen ;
2003-02-11 17:40:11 +00:00
}
static struct stat *
php_apache_sapi_get_stat ( TSRMLS_D )
{
php_struct * ctx = SG ( server_context ) ;
ctx - > finfo . st_uid = ctx - > r - > finfo . user ;
ctx - > finfo . st_gid = ctx - > r - > finfo . group ;
2004-06-18 00:36:58 +00:00
ctx - > finfo . st_dev = ctx - > r - > finfo . device ;
2003-02-11 17:40:11 +00:00
ctx - > finfo . st_ino = ctx - > r - > finfo . inode ;
# if defined(NETWARE) && defined(CLIB_STAT_PATCH)
2004-10-23 13:48:05 +00:00
ctx - > finfo . st_atime . tv_sec = apr_time_sec ( ctx - > r - > finfo . atime ) ;
ctx - > finfo . st_mtime . tv_sec = apr_time_sec ( ctx - > r - > finfo . mtime ) ;
ctx - > finfo . st_ctime . tv_sec = apr_time_sec ( ctx - > r - > finfo . ctime ) ;
2003-02-11 17:40:11 +00:00
# else
2004-10-23 13:48:05 +00:00
ctx - > finfo . st_atime = apr_time_sec ( ctx - > r - > finfo . atime ) ;
ctx - > finfo . st_mtime = apr_time_sec ( ctx - > r - > finfo . mtime ) ;
ctx - > finfo . st_ctime = apr_time_sec ( ctx - > r - > finfo . ctime ) ;
2003-02-11 17:40:11 +00:00
# endif
ctx - > finfo . st_size = ctx - > r - > finfo . size ;
ctx - > finfo . st_nlink = ctx - > r - > finfo . nlink ;
return & ctx - > finfo ;
}
static char *
php_apache_sapi_read_cookies ( TSRMLS_D )
{
php_struct * ctx = SG ( server_context ) ;
const char * http_cookie ;
http_cookie = apr_table_get ( ctx - > r - > headers_in , " cookie " ) ;
/* The SAPI interface should use 'const char *' */
return ( char * ) http_cookie ;
}
static char *
php_apache_sapi_getenv ( char * name , size_t name_len TSRMLS_DC )
{
php_struct * ctx = SG ( server_context ) ;
const char * env_var ;
env_var = apr_table_get ( ctx - > r - > subprocess_env , name ) ;
return ( char * ) env_var ;
}
static void
php_apache_sapi_register_variables ( zval * track_vars_array TSRMLS_DC )
{
php_struct * ctx = SG ( server_context ) ;
const apr_array_header_t * arr = apr_table_elts ( ctx - > r - > subprocess_env ) ;
char * key , * val ;
2003-05-14 18:15:01 +00:00
2003-02-11 17:40:11 +00:00
APR_ARRAY_FOREACH_OPEN ( arr , key , val )
2004-07-19 07:19:50 +00:00
if ( ! val ) val = " " ;
2003-02-11 17:40:11 +00:00
php_register_variable ( key , val , track_vars_array TSRMLS_CC ) ;
APR_ARRAY_FOREACH_CLOSE ( )
php_register_variable ( " PHP_SELF " , ctx - > r - > uri , track_vars_array TSRMLS_CC ) ;
}
static void
php_apache_sapi_flush ( void * server_context )
{
php_struct * ctx ;
2003-02-20 18:20:03 +00:00
request_rec * r ;
2003-08-03 11:22:53 +00:00
TSRMLS_FETCH ( ) ;
2003-02-20 18:20:03 +00:00
2003-02-11 17:40:11 +00:00
ctx = server_context ;
/* If we haven't registered a server_context yet,
* then don ' t bother flushing . */
2003-02-20 18:20:03 +00:00
if ( ! server_context ) {
2003-02-11 17:40:11 +00:00
return ;
2003-02-20 18:20:03 +00:00
}
r = ctx - > r ;
2004-03-08 03:15:45 +00:00
sapi_send_headers ( TSRMLS_C ) ;
2003-08-02 18:29:30 +00:00
r - > status = SG ( sapi_headers ) . http_response_code ;
2003-10-02 03:24:36 +00:00
SG ( headers_sent ) = 1 ;
2003-08-02 18:29:30 +00:00
2004-06-25 13:00:48 +00:00
if ( ap_rflush ( r ) < 0 | | r - > connection - > aborted ) {
2003-02-11 17:40:11 +00:00
php_handle_aborted_connection ( ) ;
}
}
static void php_apache_sapi_log_message ( char * msg )
{
php_struct * ctx ;
TSRMLS_FETCH ( ) ;
ctx = SG ( server_context ) ;
2004-06-25 13:00:48 +00:00
2003-02-11 17:40:11 +00:00
if ( ctx = = NULL ) { /* we haven't initialized our ctx yet, oh well */
2004-03-16 22:38:07 +00:00
ap_log_error ( APLOG_MARK , APLOG_ERR | APLOG_STARTUP , 0 , NULL , " %s " , msg ) ;
2003-03-07 13:45:33 +00:00
} else {
2005-04-08 20:32:14 +00:00
ap_log_rerror ( APLOG_MARK , APLOG_ERR , 0 , ctx - > r , " %s " , msg ) ;
2004-03-16 22:38:07 +00:00
}
}
static void php_apache_sapi_log_message_ex ( char * msg , request_rec * r )
{
if ( r ) {
2005-04-08 20:32:14 +00:00
ap_log_rerror ( APLOG_MARK , APLOG_ERR , 0 , r , msg , r - > filename ) ;
2004-03-16 22:38:07 +00:00
} else {
php_apache_sapi_log_message ( msg ) ;
2003-02-11 17:40:11 +00:00
}
}
2004-10-23 12:56:20 +00:00
static time_t php_apache_sapi_get_request_time ( TSRMLS_D ) {
php_struct * ctx = SG ( server_context ) ;
return apr_time_sec ( ctx - > r - > request_time ) ;
2004-08-10 17:40:00 +00:00
}
2003-02-11 17:40:11 +00:00
extern zend_module_entry php_apache_module ;
static int php_apache2_startup ( sapi_module_struct * sapi_module )
{
if ( php_module_startup ( sapi_module , & php_apache_module , 1 ) = = FAILURE ) {
return FAILURE ;
}
return SUCCESS ;
}
static sapi_module_struct apache2_sapi_module = {
2003-02-20 18:20:03 +00:00
" apache2handler " ,
" Apache 2.0 Handler " ,
2003-02-11 17:40:11 +00:00
2003-03-07 13:45:33 +00:00
php_apache2_startup , /* startup */
2003-02-11 17:40:11 +00:00
php_module_shutdown_wrapper , /* shutdown */
2003-03-07 13:45:33 +00:00
NULL , /* activate */
NULL , /* deactivate */
2003-02-11 17:40:11 +00:00
2003-03-07 13:45:33 +00:00
php_apache_sapi_ub_write , /* unbuffered write */
php_apache_sapi_flush , /* flush */
php_apache_sapi_get_stat , /* get uid */
php_apache_sapi_getenv , /* getenv */
2003-02-11 17:40:11 +00:00
2003-03-07 13:45:33 +00:00
php_error , /* error handler */
2003-02-11 17:40:11 +00:00
php_apache_sapi_header_handler , /* header handler */
php_apache_sapi_send_headers , /* send headers handler */
2003-03-07 13:45:33 +00:00
NULL , /* send header handler */
2003-02-11 17:40:11 +00:00
2003-03-07 13:45:33 +00:00
php_apache_sapi_read_post , /* read POST data */
2003-02-11 17:40:11 +00:00
php_apache_sapi_read_cookies , /* read Cookies */
php_apache_sapi_register_variables ,
php_apache_sapi_log_message , /* Log message */
2004-08-10 17:40:00 +00:00
php_apache_sapi_get_request_time , /* Request Time */
2003-02-11 17:40:11 +00:00
STANDARD_SAPI_MODULE_PROPERTIES
} ;
static apr_status_t
php_apache_server_shutdown ( void * tmp )
{
apache2_sapi_module . shutdown ( & apache2_sapi_module ) ;
sapi_shutdown ( ) ;
# ifdef ZTS
tsrm_shutdown ( ) ;
# endif
return APR_SUCCESS ;
}
static void php_apache_add_version ( apr_pool_t * p )
{
TSRMLS_FETCH ( ) ;
if ( PG ( expose_php ) ) {
2003-02-20 18:20:03 +00:00
ap_add_version_component ( p , " PHP/ " PHP_VERSION ) ;
2003-02-11 17:40:11 +00:00
}
}
static int php_pre_config ( apr_pool_t * pconf , apr_pool_t * plog , apr_pool_t * ptemp )
{
# ifndef ZTS
int threaded_mpm ;
ap_mpm_query ( AP_MPMQ_IS_THREADED , & threaded_mpm ) ;
if ( threaded_mpm ) {
ap_log_error ( APLOG_MARK , APLOG_CRIT , 0 , 0 , " Apache is running a threaded MPM, but your PHP Module is not compiled to be threadsafe. You need to recompile PHP. " ) ;
return DONE ;
}
# endif
2003-02-20 18:20:03 +00:00
/* When this is NULL, apache won't override the hard-coded default
* php . ini path setting . */
apache2_php_ini_path_override = NULL ;
return OK ;
2003-02-11 17:40:11 +00:00
}
static int
2003-03-07 13:45:33 +00:00
php_apache_server_startup ( apr_pool_t * pconf , apr_pool_t * plog , apr_pool_t * ptemp , server_rec * s )
2003-02-11 17:40:11 +00:00
{
void * data = NULL ;
const char * userdata_key = " apache2hook_post_config " ;
/* Apache will load, unload and then reload a DSO module. This
* prevents us from starting PHP until the second load . */
apr_pool_userdata_get ( & data , userdata_key , s - > process - > pool ) ;
if ( data = = NULL ) {
/* We must use set() here and *not* setn(), otherwise the
* static string pointed to by userdata_key will be mapped
* to a different location when the DSO is reloaded and the
* pointers won ' t match , causing get ( ) to return NULL when
* we expected it to return non - NULL . */
2003-03-07 13:45:33 +00:00
apr_pool_userdata_set ( ( const void * ) 1 , userdata_key , apr_pool_cleanup_null , s - > process - > pool ) ;
2003-02-11 17:40:11 +00:00
return OK ;
}
/* Set up our overridden path. */
if ( apache2_php_ini_path_override ) {
apache2_sapi_module . php_ini_path_override = apache2_php_ini_path_override ;
}
# ifdef ZTS
tsrm_startup ( 1 , 1 , 0 , NULL ) ;
# endif
sapi_startup ( & apache2_sapi_module ) ;
apache2_sapi_module . startup ( & apache2_sapi_module ) ;
apr_pool_cleanup_register ( pconf , NULL , php_apache_server_shutdown , apr_pool_cleanup_null ) ;
php_apache_add_version ( pconf ) ;
return OK ;
}
static apr_status_t php_server_context_cleanup ( void * data_ )
{
void * * data = data_ ;
* data = NULL ;
return APR_SUCCESS ;
}
2004-12-06 18:55:30 +00:00
static int php_apache_request_ctor ( request_rec * r , php_struct * ctx TSRMLS_DC )
2003-02-11 17:40:11 +00:00
{
2003-02-20 18:20:03 +00:00
char * content_type ;
2004-02-09 23:27:43 +00:00
char * content_length ;
2003-02-11 17:40:11 +00:00
const char * auth ;
2003-05-23 02:41:59 +00:00
SG ( sapi_headers ) . http_response_code = ! r - > status ? HTTP_OK : r - > status ;
2003-03-07 13:45:33 +00:00
SG ( request_info ) . content_type = apr_table_get ( r - > headers_in , " Content-Type " ) ;
2003-02-11 17:40:11 +00:00
SG ( request_info ) . query_string = apr_pstrdup ( r - > pool , r - > args ) ;
SG ( request_info ) . request_method = r - > method ;
2005-03-14 19:25:39 +00:00
SG ( request_info ) . proto_num = r - > proto_num ;
2003-02-11 17:40:11 +00:00
SG ( request_info ) . request_uri = apr_pstrdup ( r - > pool , r - > uri ) ;
2003-04-10 11:33:45 +00:00
SG ( request_info ) . path_translated = apr_pstrdup ( r - > pool , r - > filename ) ;
2003-02-11 17:40:11 +00:00
r - > no_local_copy = 1 ;
2003-02-20 18:20:03 +00:00
2004-02-11 00:45:07 +00:00
content_length = ( char * ) apr_table_get ( r - > headers_in , " Content-Length " ) ;
2004-02-09 23:27:43 +00:00
SG ( request_info ) . content_length = ( content_length ? atoi ( content_length ) : 0 ) ;
2003-02-11 17:40:11 +00:00
apr_table_unset ( r - > headers_out , " Content-Length " ) ;
apr_table_unset ( r - > headers_out , " Last-Modified " ) ;
apr_table_unset ( r - > headers_out , " Expires " ) ;
apr_table_unset ( r - > headers_out , " ETag " ) ;
2003-04-16 23:31:23 +00:00
if ( ! PG ( safe_mode ) | | ( PG ( safe_mode ) & & ! ap_auth_type ( r ) ) ) {
2003-02-11 17:40:11 +00:00
auth = apr_table_get ( r - > headers_in , " Authorization " ) ;
php_handle_auth_data ( auth TSRMLS_CC ) ;
2003-03-18 01:24:18 +00:00
ctx - > r - > user = apr_pstrdup ( ctx - > r - > pool , SG ( request_info ) . auth_user ) ;
2003-02-11 17:40:11 +00:00
} else {
SG ( request_info ) . auth_user = NULL ;
SG ( request_info ) . auth_password = NULL ;
}
2004-12-06 18:55:30 +00:00
return php_request_startup ( TSRMLS_C ) ;
2003-02-20 18:20:03 +00:00
}
static void php_apache_request_dtor ( request_rec * r TSRMLS_DC )
{
php_request_shutdown ( NULL ) ;
}
2005-11-18 18:59:49 +00:00
static void php_apache_ini_dtor ( request_rec * r , request_rec * p TSRMLS_DC )
{
if ( strcmp ( r - > protocol , " INCLUDED " ) ) {
zend_try { zend_ini_deactivate ( TSRMLS_C ) ; } zend_end_try ( ) ;
}
if ( p ) {
( ( php_struct * ) SG ( server_context ) ) - > r = p ;
} else {
apr_pool_cleanup_run ( r - > pool , ( void * ) & SG ( server_context ) , php_server_context_cleanup ) ;
}
}
2003-02-20 18:20:03 +00:00
static int php_handler ( request_rec * r )
{
php_struct * ctx ;
void * conf ;
apr_bucket_brigade * brigade ;
apr_bucket * bucket ;
apr_status_t rv ;
request_rec * parent_req = NULL ;
TSRMLS_FETCH ( ) ;
2005-11-18 18:59:49 +00:00
# define PHPAP_INI_OFF php_apache_ini_dtor(r, parent_req TSRMLS_CC);
2005-10-05 00:43:38 +00:00
2003-03-29 04:52:46 +00:00
conf = ap_get_module_config ( r - > per_dir_config , & php5_module ) ;
2005-07-25 22:38:11 +00:00
/* apply_config() needs r in some cases, so allocate server_context early */
ctx = SG ( server_context ) ;
2005-12-14 03:36:44 +00:00
if ( ctx = = NULL | | ( ctx & & ctx - > request_processed & & ! strcmp ( r - > protocol , " INCLUDED " ) ) ) {
2005-08-18 01:14:42 +00:00
normal :
2005-07-25 22:38:11 +00:00
ctx = SG ( server_context ) = apr_pcalloc ( r - > pool , sizeof ( * ctx ) ) ;
/* register a cleanup so we clear out the SG(server_context)
* after each request . Note : We pass in the pointer to the
* server_context in case this is handled by a different thread .
*/
apr_pool_cleanup_register ( r - > pool , ( void * ) & SG ( server_context ) , php_server_context_cleanup , apr_pool_cleanup_null ) ;
ctx - > r = r ;
ctx = NULL ; /* May look weird to null it here, but it is to catch the right case in the first_try later on */
} else {
2005-10-12 21:24:09 +00:00
parent_req = ctx - > r ;
2005-07-25 22:38:11 +00:00
ctx - > r = r ;
}
2003-02-22 04:42:34 +00:00
apply_config ( conf ) ;
2003-03-07 13:45:33 +00:00
if ( strcmp ( r - > handler , PHP_MAGIC_TYPE ) & & strcmp ( r - > handler , PHP_SOURCE_MAGIC_TYPE ) & & strcmp ( r - > handler , PHP_SCRIPT ) ) {
2003-02-22 04:42:34 +00:00
/* Check for xbithack in this case. */
2003-03-07 13:45:33 +00:00
if ( ! AP2 ( xbithack ) | | strcmp ( r - > handler , " text/html " ) | | ! ( r - > finfo . protection & APR_UEXECUTE ) ) {
2005-10-05 00:43:38 +00:00
PHPAP_INI_OFF ;
2003-02-22 04:42:34 +00:00
return DECLINED ;
}
2003-02-20 18:20:03 +00:00
}
2005-03-10 11:09:32 +00:00
/* Give a 404 if PATH_INFO is used but is explicitly disabled in
* the configuration ; default behaviour is to accept . */
if ( r - > used_path_info = = AP_REQ_REJECT_PATH_INFO
& & r - > path_info & & r - > path_info [ 0 ] ) {
2005-10-05 00:43:38 +00:00
PHPAP_INI_OFF ;
2005-03-10 11:09:32 +00:00
return HTTP_NOT_FOUND ;
}
2003-02-20 18:20:03 +00:00
/* handle situations where user turns the engine off */
2003-03-07 13:45:33 +00:00
if ( ! AP2 ( engine ) ) {
2005-10-05 00:43:38 +00:00
PHPAP_INI_OFF ;
2003-02-20 18:20:03 +00:00
return DECLINED ;
}
2003-08-06 22:33:18 +00:00
if ( r - > finfo . filetype = = 0 ) {
2004-03-16 22:38:07 +00:00
php_apache_sapi_log_message_ex ( " script '%s' not found or unable to stat " , r ) ;
2005-10-05 00:43:38 +00:00
PHPAP_INI_OFF ;
2003-08-06 22:33:18 +00:00
return HTTP_NOT_FOUND ;
}
if ( r - > finfo . filetype = = APR_DIR ) {
2004-03-16 22:38:07 +00:00
php_apache_sapi_log_message_ex ( " attempt to invoke directory '%s' as script " , r ) ;
2005-10-05 00:43:38 +00:00
PHPAP_INI_OFF ;
2003-08-06 22:33:18 +00:00
return HTTP_FORBIDDEN ;
}
2003-07-11 04:23:34 +00:00
/* Setup the CGI variables if this is the main request */
2004-06-25 13:00:48 +00:00
if ( r - > main = = NULL | |
/* .. or if the sub-request envinronment differs from the main-request. */
2003-07-11 04:23:34 +00:00
r - > subprocess_env ! = r - > main - > subprocess_env
) {
/* setup standard CGI variables */
ap_add_common_vars ( r ) ;
ap_add_cgi_vars ( r ) ;
}
2003-02-20 18:20:03 +00:00
2003-09-19 00:44:50 +00:00
zend_first_try {
2003-02-11 17:40:11 +00:00
if ( ctx = = NULL ) {
2003-02-20 18:20:03 +00:00
brigade = apr_brigade_create ( r - > pool , r - > connection - > bucket_alloc ) ;
2005-07-25 22:38:11 +00:00
ctx = SG ( server_context ) ;
2003-02-20 18:20:03 +00:00
ctx - > brigade = brigade ;
2004-12-06 18:55:30 +00:00
if ( php_apache_request_ctor ( r , ctx TSRMLS_CC ) ! = SUCCESS ) {
zend_bailout ( ) ;
}
2003-03-07 13:45:33 +00:00
} else {
2005-10-12 21:24:09 +00:00
if ( ! parent_req ) {
parent_req = ctx - > r ;
}
2005-10-26 15:08:23 +00:00
if ( parent_req & & parent_req - > handler & &
strcmp ( parent_req - > handler , PHP_MAGIC_TYPE ) & &
strcmp ( parent_req - > handler , PHP_SOURCE_MAGIC_TYPE ) & &
strcmp ( parent_req - > handler , PHP_SCRIPT ) ) {
2005-10-12 21:24:09 +00:00
if ( php_apache_request_ctor ( r , ctx TSRMLS_CC ) ! = SUCCESS ) {
zend_bailout ( ) ;
}
}
2005-08-18 01:14:42 +00:00
/* check if comming due to ErrorDocument */
2005-09-02 13:51:47 +00:00
if ( parent_req & & parent_req - > status ! = HTTP_OK ) {
2005-08-18 01:14:42 +00:00
parent_req = NULL ;
goto normal ;
}
2003-02-20 18:20:03 +00:00
ctx - > r = r ;
brigade = ctx - > brigade ;
2003-02-11 17:40:11 +00:00
}
2003-03-07 13:45:33 +00:00
if ( AP2 ( last_modified ) ) {
ap_update_mtime ( r , r - > finfo . mtime ) ;
ap_set_last_modified ( r ) ;
}
2003-02-20 18:20:03 +00:00
/* Determine if we need to parse the file or show the source */
2003-03-07 13:45:33 +00:00
if ( strncmp ( r - > handler , PHP_SOURCE_MAGIC_TYPE , sizeof ( PHP_SOURCE_MAGIC_TYPE ) - 1 ) = = 0 ) {
2003-02-20 18:20:03 +00:00
zend_syntax_highlighter_ini syntax_highlighter_ini ;
php_get_highlight_struct ( & syntax_highlighter_ini ) ;
2003-03-07 13:45:33 +00:00
highlight_file ( ( char * ) r - > filename , & syntax_highlighter_ini TSRMLS_CC ) ;
} else {
2003-02-20 18:20:03 +00:00
zend_file_handle zfd ;
2003-02-11 17:40:11 +00:00
2003-02-20 18:20:03 +00:00
zfd . type = ZEND_HANDLE_FILENAME ;
zfd . filename = ( char * ) r - > filename ;
zfd . free_filename = 0 ;
zfd . opened_path = NULL ;
2003-02-11 17:40:11 +00:00
2003-02-20 18:20:03 +00:00
if ( ! parent_req ) {
php_execute_script ( & zfd TSRMLS_CC ) ;
2003-03-07 13:45:33 +00:00
} else {
2003-02-20 18:20:03 +00:00
zend_execute_scripts ( ZEND_INCLUDE TSRMLS_CC , NULL , 1 , & zfd ) ;
}
2003-02-11 17:40:11 +00:00
# if MEMORY_LIMIT
2003-02-20 18:20:03 +00:00
{
char * mem_usage ;
2003-02-11 17:40:11 +00:00
2006-07-18 09:06:33 +00:00
mem_usage = apr_psprintf ( ctx - > r - > pool , " %u " , zend_memory_peak_usage ( TSRMLS_C ) ) ;
2003-02-20 18:20:03 +00:00
apr_table_set ( r - > notes , " mod_php_memory_usage " , mem_usage ) ;
}
2003-02-11 17:40:11 +00:00
# endif
2003-02-20 18:20:03 +00:00
}
2003-02-11 17:40:11 +00:00
2004-07-17 21:29:50 +00:00
} zend_end_try ( ) ;
2003-02-20 18:20:03 +00:00
if ( ! parent_req ) {
php_apache_request_dtor ( r TSRMLS_CC ) ;
ctx - > request_processed = 1 ;
bucket = apr_bucket_eos_create ( r - > connection - > bucket_alloc ) ;
APR_BRIGADE_INSERT_TAIL ( brigade , bucket ) ;
rv = ap_pass_brigade ( r - > output_filters , brigade ) ;
2003-08-01 20:20:11 +00:00
if ( rv ! = APR_SUCCESS | | r - > connection - > aborted ) {
2004-10-20 09:28:47 +00:00
zend_first_try {
2003-02-20 18:20:03 +00:00
php_handle_aborted_connection ( ) ;
2004-10-20 09:28:47 +00:00
} zend_end_try ( ) ;
2003-02-20 18:20:03 +00:00
}
apr_brigade_cleanup ( brigade ) ;
2003-03-07 13:45:33 +00:00
} else {
2003-02-20 18:20:03 +00:00
ctx - > r = parent_req ;
2003-02-11 17:40:11 +00:00
}
2003-02-20 18:20:03 +00:00
return OK ;
2003-02-11 17:40:11 +00:00
}
2003-02-20 18:20:03 +00:00
2003-10-21 11:48:31 +00:00
void php_ap2_register_hook ( apr_pool_t * p )
2003-02-11 17:40:11 +00:00
{
ap_hook_pre_config ( php_pre_config , NULL , NULL , APR_HOOK_MIDDLE ) ;
ap_hook_post_config ( php_apache_server_startup , NULL , NULL , APR_HOOK_MIDDLE ) ;
2003-02-20 18:20:03 +00:00
ap_hook_handler ( php_handler , NULL , NULL , APR_HOOK_MIDDLE ) ;
2003-02-11 17:40:11 +00:00
}
/*
* Local variables :
* tab - width : 4
* c - basic - offset : 4
* End :
* vim600 : sw = 4 ts = 4 fdm = marker
* vim < 600 : sw = 4 ts = 4
*/