2000-10-29 17:43:23 +00:00
/*
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2001-12-11 15:32:16 +00:00
| PHP Version 4 |
2000-10-29 17:43:23 +00:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2001-12-11 15:32:16 +00:00
| Copyright ( c ) 1997 - 2002 The PHP Group |
2000-10-29 17:43:23 +00:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
| 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 |
| available at through the world - wide - web at |
| http : //www.php.net/license/2_02.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 : Sascha Schumann < sascha @ schumann . cx > |
| Parts based on Apache 1.3 SAPI module by |
| Rasmus Lerdorf and Zeev Suraski |
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
*/
2002-11-02 16:04:27 +00:00
/* $Id$ */
2000-10-26 17:55:05 +00:00
# include <fcntl.h>
# include "php.h"
# include "php_main.h"
# include "php_ini.h"
# include "php_variables.h"
# include "SAPI.h"
# include "ext/standard/php_smart_str.h"
2002-10-04 21:15:59 +00:00
# include "ext/standard/php_standard.h"
2000-10-26 17:55:05 +00:00
# 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"
# include "http_core.h"
2002-06-24 16:04:20 +00:00
# include "ap_mpm.h"
2000-10-26 17:55:05 +00:00
# include "php_apache.h"
2002-04-18 22:10:57 +00:00
/* A way to specify the location of the php.ini dir in an apache directive */
char * apache2_php_ini_path_override = NULL ;
2000-10-26 17:55:05 +00:00
static int
2001-08-05 15:29:47 +00:00
php_apache_sapi_ub_write ( const char * str , uint str_length TSRMLS_DC )
2000-10-26 17:55:05 +00:00
{
2001-02-28 14:03:58 +00:00
apr_bucket * b ;
apr_bucket_brigade * bb ;
2002-03-29 15:42:18 +00:00
apr_bucket_alloc_t * ba ;
2002-04-11 20:34:56 +00:00
ap_filter_t * f ; /* remaining output filters */
2000-10-26 17:55:05 +00:00
php_struct * ctx ;
ctx = SG ( server_context ) ;
2002-04-11 20:34:56 +00:00
f = ctx - > f ;
2000-10-26 17:55:05 +00:00
2001-02-28 14:19:15 +00:00
if ( str_length = = 0 ) return 0 ;
2000-11-11 18:24:27 +00:00
PHP filters and Apache 2 aren't quite a perfect match yet, so we have
to do some trickery with the server_context to make sure it is always
valid within the current thread.
This patch makes sure the server_context is created in apache's
post_read_request hook phase, and then registeres a cleanup that
will NULL out the server context when the request goes out of scope.
Then, inside the output filters, if the server_context is null we
throw an error. Finally, instead of saving the output filter in
the server_context, now we store the entire request_rec pointer
in there.
POST bodies appear to be working now, although they are very inefficient.
The input filter is still just realloc()ing for whatever data comes
down the input pipe, and then sending this to PHP. This means that
we are doing some really nasty memory management on big POST bodies.
For now this it allows for unlimited input bodies, which means that
a big POST could potentially DoS a box by making it run out of memory.
We might want to put a limit on here just in case, at least until
we figure out how to consume input data more efficiently into php.
2002-04-11 19:25:08 +00:00
ba = f - > c - > bucket_alloc ;
bb = apr_brigade_create ( ctx - > r - > pool , ba ) ;
2002-04-11 06:01:54 +00:00
b = apr_bucket_transient_create ( str , str_length , ba ) ;
APR_BRIGADE_INSERT_TAIL ( bb , b ) ;
2002-06-08 18:11:03 +00:00
#if 0
2002-04-11 06:01:54 +00:00
/* Add a Flush bucket to the end of this brigade, so that
* the transient buckets above are more likely to make it out
* the end of the filter instead of having to be copied into
* someone ' s setaside . */
b = apr_bucket_flush_create ( ba ) ;
APR_BRIGADE_INSERT_TAIL ( bb , b ) ;
2002-06-08 18:11:03 +00:00
# endif
PHP filters and Apache 2 aren't quite a perfect match yet, so we have
to do some trickery with the server_context to make sure it is always
valid within the current thread.
This patch makes sure the server_context is created in apache's
post_read_request hook phase, and then registeres a cleanup that
will NULL out the server context when the request goes out of scope.
Then, inside the output filters, if the server_context is null we
throw an error. Finally, instead of saving the output filter in
the server_context, now we store the entire request_rec pointer
in there.
POST bodies appear to be working now, although they are very inefficient.
The input filter is still just realloc()ing for whatever data comes
down the input pipe, and then sending this to PHP. This means that
we are doing some really nasty memory management on big POST bodies.
For now this it allows for unlimited input bodies, which means that
a big POST could potentially DoS a box by making it run out of memory.
We might want to put a limit on here just in case, at least until
we figure out how to consume input data more efficiently into php.
2002-04-11 19:25:08 +00:00
if ( ap_pass_brigade ( f - > next , bb ) ! = APR_SUCCESS ) {
2000-10-29 16:01:02 +00:00
php_handle_aborted_connection ( ) ;
2000-10-29 15:10:49 +00:00
}
2000-10-26 17:55:05 +00:00
2002-04-11 17:22:11 +00:00
return str_length ; /* we always consume all the data passed to us. */
2000-10-26 17:55:05 +00:00
}
static int
2001-07-28 11:36:37 +00:00
php_apache_sapi_header_handler ( sapi_header_struct * sapi_header , sapi_headers_struct * sapi_headers TSRMLS_DC )
2000-10-26 17:55:05 +00:00
{
PHP filters and Apache 2 aren't quite a perfect match yet, so we have
to do some trickery with the server_context to make sure it is always
valid within the current thread.
This patch makes sure the server_context is created in apache's
post_read_request hook phase, and then registeres a cleanup that
will NULL out the server context when the request goes out of scope.
Then, inside the output filters, if the server_context is null we
throw an error. Finally, instead of saving the output filter in
the server_context, now we store the entire request_rec pointer
in there.
POST bodies appear to be working now, although they are very inefficient.
The input filter is still just realloc()ing for whatever data comes
down the input pipe, and then sending this to PHP. This means that
we are doing some really nasty memory management on big POST bodies.
For now this it allows for unlimited input bodies, which means that
a big POST could potentially DoS a box by making it run out of memory.
We might want to put a limit on here just in case, at least until
we figure out how to consume input data more efficiently into php.
2002-04-11 19:25:08 +00:00
php_struct * ctx ;
ap_filter_t * f ;
2000-10-26 17:55:05 +00:00
char * val ;
PHP filters and Apache 2 aren't quite a perfect match yet, so we have
to do some trickery with the server_context to make sure it is always
valid within the current thread.
This patch makes sure the server_context is created in apache's
post_read_request hook phase, and then registeres a cleanup that
will NULL out the server context when the request goes out of scope.
Then, inside the output filters, if the server_context is null we
throw an error. Finally, instead of saving the output filter in
the server_context, now we store the entire request_rec pointer
in there.
POST bodies appear to be working now, although they are very inefficient.
The input filter is still just realloc()ing for whatever data comes
down the input pipe, and then sending this to PHP. This means that
we are doing some really nasty memory management on big POST bodies.
For now this it allows for unlimited input bodies, which means that
a big POST could potentially DoS a box by making it run out of memory.
We might want to put a limit on here just in case, at least until
we figure out how to consume input data more efficiently into php.
2002-04-11 19:25:08 +00:00
ctx = SG ( server_context ) ;
f = ctx - > r - > output_filters ;
2000-10-26 17:55:05 +00:00
val = strchr ( sapi_header - > header , ' : ' ) ;
2002-06-21 14:47:59 +00:00
if ( ! val ) {
sapi_free_header ( sapi_header ) ;
return 0 ;
}
2000-10-26 17:55:05 +00:00
* val = ' \0 ' ;
do {
val + + ;
} while ( * val = = ' ' ) ;
if ( ! strcasecmp ( sapi_header - > header , " content-type " ) )
PHP filters and Apache 2 aren't quite a perfect match yet, so we have
to do some trickery with the server_context to make sure it is always
valid within the current thread.
This patch makes sure the server_context is created in apache's
post_read_request hook phase, and then registeres a cleanup that
will NULL out the server context when the request goes out of scope.
Then, inside the output filters, if the server_context is null we
throw an error. Finally, instead of saving the output filter in
the server_context, now we store the entire request_rec pointer
in there.
POST bodies appear to be working now, although they are very inefficient.
The input filter is still just realloc()ing for whatever data comes
down the input pipe, and then sending this to PHP. This means that
we are doing some really nasty memory management on big POST bodies.
For now this it allows for unlimited input bodies, which means that
a big POST could potentially DoS a box by making it run out of memory.
We might want to put a limit on here just in case, at least until
we figure out how to consume input data more efficiently into php.
2002-04-11 19:25:08 +00:00
ctx - > r - > content_type = apr_pstrdup ( ctx - > r - > pool , val ) ;
2000-10-26 17:55:05 +00:00
else if ( sapi_header - > replace )
PHP filters and Apache 2 aren't quite a perfect match yet, so we have
to do some trickery with the server_context to make sure it is always
valid within the current thread.
This patch makes sure the server_context is created in apache's
post_read_request hook phase, and then registeres a cleanup that
will NULL out the server context when the request goes out of scope.
Then, inside the output filters, if the server_context is null we
throw an error. Finally, instead of saving the output filter in
the server_context, now we store the entire request_rec pointer
in there.
POST bodies appear to be working now, although they are very inefficient.
The input filter is still just realloc()ing for whatever data comes
down the input pipe, and then sending this to PHP. This means that
we are doing some really nasty memory management on big POST bodies.
For now this it allows for unlimited input bodies, which means that
a big POST could potentially DoS a box by making it run out of memory.
We might want to put a limit on here just in case, at least until
we figure out how to consume input data more efficiently into php.
2002-04-11 19:25:08 +00:00
apr_table_set ( ctx - > r - > headers_out , sapi_header - > header , val ) ;
2000-10-26 17:55:05 +00:00
else
PHP filters and Apache 2 aren't quite a perfect match yet, so we have
to do some trickery with the server_context to make sure it is always
valid within the current thread.
This patch makes sure the server_context is created in apache's
post_read_request hook phase, and then registeres a cleanup that
will NULL out the server context when the request goes out of scope.
Then, inside the output filters, if the server_context is null we
throw an error. Finally, instead of saving the output filter in
the server_context, now we store the entire request_rec pointer
in there.
POST bodies appear to be working now, although they are very inefficient.
The input filter is still just realloc()ing for whatever data comes
down the input pipe, and then sending this to PHP. This means that
we are doing some really nasty memory management on big POST bodies.
For now this it allows for unlimited input bodies, which means that
a big POST could potentially DoS a box by making it run out of memory.
We might want to put a limit on here just in case, at least until
we figure out how to consume input data more efficiently into php.
2002-04-11 19:25:08 +00:00
apr_table_add ( ctx - > r - > headers_out , sapi_header - > header , val ) ;
2000-10-26 17:55:05 +00:00
sapi_free_header ( sapi_header ) ;
return 0 ;
}
static int
2001-07-28 11:36:37 +00:00
php_apache_sapi_send_headers ( sapi_headers_struct * sapi_headers TSRMLS_DC )
2000-10-26 17:55:05 +00:00
{
php_struct * ctx = SG ( server_context ) ;
PHP filters and Apache 2 aren't quite a perfect match yet, so we have
to do some trickery with the server_context to make sure it is always
valid within the current thread.
This patch makes sure the server_context is created in apache's
post_read_request hook phase, and then registeres a cleanup that
will NULL out the server context when the request goes out of scope.
Then, inside the output filters, if the server_context is null we
throw an error. Finally, instead of saving the output filter in
the server_context, now we store the entire request_rec pointer
in there.
POST bodies appear to be working now, although they are very inefficient.
The input filter is still just realloc()ing for whatever data comes
down the input pipe, and then sending this to PHP. This means that
we are doing some really nasty memory management on big POST bodies.
For now this it allows for unlimited input bodies, which means that
a big POST could potentially DoS a box by making it run out of memory.
We might want to put a limit on here just in case, at least until
we figure out how to consume input data more efficiently into php.
2002-04-11 19:25:08 +00:00
ctx - > r - > status = SG ( sapi_headers ) . http_response_code ;
2000-10-26 17:55:05 +00:00
return SAPI_HEADER_SENT_SUCCESSFULLY ;
}
static int
2001-07-28 11:36:37 +00:00
php_apache_sapi_read_post ( char * buf , uint count_bytes TSRMLS_DC )
2000-10-26 17:55:05 +00:00
{
2000-10-29 14:52:15 +00:00
int n ;
int to_read ;
2000-10-27 23:02:20 +00:00
php_struct * ctx = SG ( server_context ) ;
2000-10-26 17:55:05 +00:00
2000-10-29 14:52:15 +00:00
to_read = ctx - > post_len - ctx - > post_idx ;
n = MIN ( to_read , count_bytes ) ;
if ( n > 0 ) {
memcpy ( buf , ctx - > post_data + ctx - > post_idx , n ) ;
ctx - > post_idx + = n ;
} else {
if ( ctx - > post_data ) free ( ctx - > post_data ) ;
ctx - > post_data = NULL ;
2000-10-27 23:02:20 +00:00
}
2000-10-29 14:52:15 +00:00
return n ;
2000-10-26 17:55:05 +00:00
}
2002-09-23 18:51:34 +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 ;
ctx - > finfo . st_ino = ctx - > r - > finfo . inode ;
ctx - > finfo . st_atime = ctx - > r - > finfo . atime / 1000000 ;
ctx - > finfo . st_mtime = ctx - > r - > finfo . mtime / 1000000 ;
ctx - > finfo . st_ctime = ctx - > r - > finfo . ctime / 1000000 ;
ctx - > finfo . st_size = ctx - > r - > finfo . size ;
ctx - > finfo . st_nlink = ctx - > r - > finfo . nlink ;
return & ctx - > finfo ;
}
2000-10-26 17:55:05 +00:00
static char *
2001-07-28 11:36:37 +00:00
php_apache_sapi_read_cookies ( TSRMLS_D )
2000-10-26 17:55:05 +00:00
{
2000-10-27 10:19:40 +00:00
php_struct * ctx = SG ( server_context ) ;
const char * http_cookie ;
2000-10-26 17:55:05 +00:00
PHP filters and Apache 2 aren't quite a perfect match yet, so we have
to do some trickery with the server_context to make sure it is always
valid within the current thread.
This patch makes sure the server_context is created in apache's
post_read_request hook phase, and then registeres a cleanup that
will NULL out the server context when the request goes out of scope.
Then, inside the output filters, if the server_context is null we
throw an error. Finally, instead of saving the output filter in
the server_context, now we store the entire request_rec pointer
in there.
POST bodies appear to be working now, although they are very inefficient.
The input filter is still just realloc()ing for whatever data comes
down the input pipe, and then sending this to PHP. This means that
we are doing some really nasty memory management on big POST bodies.
For now this it allows for unlimited input bodies, which means that
a big POST could potentially DoS a box by making it run out of memory.
We might want to put a limit on here just in case, at least until
we figure out how to consume input data more efficiently into php.
2002-04-11 19:25:08 +00:00
http_cookie = apr_table_get ( ctx - > r - > headers_in , " cookie " ) ;
2000-10-27 10:19:40 +00:00
2000-10-27 13:19:23 +00:00
/* The SAPI interface should use 'const char *' */
2000-10-27 10:19:40 +00:00
return ( char * ) http_cookie ;
2000-10-26 17:55:05 +00:00
}
2002-09-23 04:10:25 +00:00
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 ;
}
2000-10-26 17:55:05 +00:00
static void
2001-08-02 15:14:30 +00:00
php_apache_sapi_register_variables ( zval * track_vars_array TSRMLS_DC )
2000-10-26 17:55:05 +00:00
{
php_struct * ctx = SG ( server_context ) ;
PHP filters and Apache 2 aren't quite a perfect match yet, so we have
to do some trickery with the server_context to make sure it is always
valid within the current thread.
This patch makes sure the server_context is created in apache's
post_read_request hook phase, and then registeres a cleanup that
will NULL out the server context when the request goes out of scope.
Then, inside the output filters, if the server_context is null we
throw an error. Finally, instead of saving the output filter in
the server_context, now we store the entire request_rec pointer
in there.
POST bodies appear to be working now, although they are very inefficient.
The input filter is still just realloc()ing for whatever data comes
down the input pipe, and then sending this to PHP. This means that
we are doing some really nasty memory management on big POST bodies.
For now this it allows for unlimited input bodies, which means that
a big POST could potentially DoS a box by making it run out of memory.
We might want to put a limit on here just in case, at least until
we figure out how to consume input data more efficiently into php.
2002-04-11 19:25:08 +00:00
const apr_array_header_t * arr = apr_table_elts ( ctx - > r - > subprocess_env ) ;
2000-11-11 18:24:27 +00:00
char * key , * val ;
2000-10-26 17:55:05 +00:00
2000-11-11 18:24:27 +00:00
APR_ARRAY_FOREACH_OPEN ( arr , key , val )
if ( ! val ) val = empty_string ;
2001-07-28 11:36:37 +00:00
php_register_variable ( key , val , track_vars_array TSRMLS_CC ) ;
2000-11-11 18:24:27 +00:00
APR_ARRAY_FOREACH_CLOSE ( )
PHP filters and Apache 2 aren't quite a perfect match yet, so we have
to do some trickery with the server_context to make sure it is always
valid within the current thread.
This patch makes sure the server_context is created in apache's
post_read_request hook phase, and then registeres a cleanup that
will NULL out the server context when the request goes out of scope.
Then, inside the output filters, if the server_context is null we
throw an error. Finally, instead of saving the output filter in
the server_context, now we store the entire request_rec pointer
in there.
POST bodies appear to be working now, although they are very inefficient.
The input filter is still just realloc()ing for whatever data comes
down the input pipe, and then sending this to PHP. This means that
we are doing some really nasty memory management on big POST bodies.
For now this it allows for unlimited input bodies, which means that
a big POST could potentially DoS a box by making it run out of memory.
We might want to put a limit on here just in case, at least until
we figure out how to consume input data more efficiently into php.
2002-04-11 19:25:08 +00:00
php_register_variable ( " PHP_SELF " , ctx - > r - > uri , track_vars_array TSRMLS_CC ) ;
2000-10-26 17:55:05 +00:00
}
static void
php_apache_sapi_flush ( void * server_context )
{
PHP filters and Apache 2 aren't quite a perfect match yet, so we have
to do some trickery with the server_context to make sure it is always
valid within the current thread.
This patch makes sure the server_context is created in apache's
post_read_request hook phase, and then registeres a cleanup that
will NULL out the server context when the request goes out of scope.
Then, inside the output filters, if the server_context is null we
throw an error. Finally, instead of saving the output filter in
the server_context, now we store the entire request_rec pointer
in there.
POST bodies appear to be working now, although they are very inefficient.
The input filter is still just realloc()ing for whatever data comes
down the input pipe, and then sending this to PHP. This means that
we are doing some really nasty memory management on big POST bodies.
For now this it allows for unlimited input bodies, which means that
a big POST could potentially DoS a box by making it run out of memory.
We might want to put a limit on here just in case, at least until
we figure out how to consume input data more efficiently into php.
2002-04-11 19:25:08 +00:00
php_struct * ctx ;
2001-02-28 14:03:58 +00:00
apr_bucket_brigade * bb ;
2002-03-29 15:42:18 +00:00
apr_bucket_alloc_t * ba ;
2001-02-28 14:03:58 +00:00
apr_bucket * b ;
PHP filters and Apache 2 aren't quite a perfect match yet, so we have
to do some trickery with the server_context to make sure it is always
valid within the current thread.
This patch makes sure the server_context is created in apache's
post_read_request hook phase, and then registeres a cleanup that
will NULL out the server context when the request goes out of scope.
Then, inside the output filters, if the server_context is null we
throw an error. Finally, instead of saving the output filter in
the server_context, now we store the entire request_rec pointer
in there.
POST bodies appear to be working now, although they are very inefficient.
The input filter is still just realloc()ing for whatever data comes
down the input pipe, and then sending this to PHP. This means that
we are doing some really nasty memory management on big POST bodies.
For now this it allows for unlimited input bodies, which means that
a big POST could potentially DoS a box by making it run out of memory.
We might want to put a limit on here just in case, at least until
we figure out how to consume input data more efficiently into php.
2002-04-11 19:25:08 +00:00
ap_filter_t * f ; /* output filters */
ctx = server_context ;
2000-10-26 17:55:05 +00:00
PHP filters and Apache 2 aren't quite a perfect match yet, so we have
to do some trickery with the server_context to make sure it is always
valid within the current thread.
This patch makes sure the server_context is created in apache's
post_read_request hook phase, and then registeres a cleanup that
will NULL out the server context when the request goes out of scope.
Then, inside the output filters, if the server_context is null we
throw an error. Finally, instead of saving the output filter in
the server_context, now we store the entire request_rec pointer
in there.
POST bodies appear to be working now, although they are very inefficient.
The input filter is still just realloc()ing for whatever data comes
down the input pipe, and then sending this to PHP. This means that
we are doing some really nasty memory management on big POST bodies.
For now this it allows for unlimited input bodies, which means that
a big POST could potentially DoS a box by making it run out of memory.
We might want to put a limit on here just in case, at least until
we figure out how to consume input data more efficiently into php.
2002-04-11 19:25:08 +00:00
/* If we haven't registered a server_context yet,
* then don ' t bother flushing . */
2001-08-18 01:36:29 +00:00
if ( ! server_context )
return ;
2001-08-18 01:34:19 +00:00
2002-04-11 20:34:56 +00:00
f = ctx - > f ;
PHP filters and Apache 2 aren't quite a perfect match yet, so we have
to do some trickery with the server_context to make sure it is always
valid within the current thread.
This patch makes sure the server_context is created in apache's
post_read_request hook phase, and then registeres a cleanup that
will NULL out the server context when the request goes out of scope.
Then, inside the output filters, if the server_context is null we
throw an error. Finally, instead of saving the output filter in
the server_context, now we store the entire request_rec pointer
in there.
POST bodies appear to be working now, although they are very inefficient.
The input filter is still just realloc()ing for whatever data comes
down the input pipe, and then sending this to PHP. This means that
we are doing some really nasty memory management on big POST bodies.
For now this it allows for unlimited input bodies, which means that
a big POST could potentially DoS a box by making it run out of memory.
We might want to put a limit on here just in case, at least until
we figure out how to consume input data more efficiently into php.
2002-04-11 19:25:08 +00:00
2000-10-27 13:19:23 +00:00
/* Send a flush bucket down the filter chain. The current default
* handler seems to act on the first flush bucket , but ignores
* all further flush buckets .
*/
PHP filters and Apache 2 aren't quite a perfect match yet, so we have
to do some trickery with the server_context to make sure it is always
valid within the current thread.
This patch makes sure the server_context is created in apache's
post_read_request hook phase, and then registeres a cleanup that
will NULL out the server context when the request goes out of scope.
Then, inside the output filters, if the server_context is null we
throw an error. Finally, instead of saving the output filter in
the server_context, now we store the entire request_rec pointer
in there.
POST bodies appear to be working now, although they are very inefficient.
The input filter is still just realloc()ing for whatever data comes
down the input pipe, and then sending this to PHP. This means that
we are doing some really nasty memory management on big POST bodies.
For now this it allows for unlimited input bodies, which means that
a big POST could potentially DoS a box by making it run out of memory.
We might want to put a limit on here just in case, at least until
we figure out how to consume input data more efficiently into php.
2002-04-11 19:25:08 +00:00
ba = ctx - > r - > connection - > bucket_alloc ;
bb = apr_brigade_create ( ctx - > r - > pool , ba ) ;
2002-03-29 15:42:18 +00:00
b = apr_bucket_flush_create ( ba ) ;
2001-02-28 14:11:34 +00:00
APR_BRIGADE_INSERT_TAIL ( bb , b ) ;
PHP filters and Apache 2 aren't quite a perfect match yet, so we have
to do some trickery with the server_context to make sure it is always
valid within the current thread.
This patch makes sure the server_context is created in apache's
post_read_request hook phase, and then registeres a cleanup that
will NULL out the server context when the request goes out of scope.
Then, inside the output filters, if the server_context is null we
throw an error. Finally, instead of saving the output filter in
the server_context, now we store the entire request_rec pointer
in there.
POST bodies appear to be working now, although they are very inefficient.
The input filter is still just realloc()ing for whatever data comes
down the input pipe, and then sending this to PHP. This means that
we are doing some really nasty memory management on big POST bodies.
For now this it allows for unlimited input bodies, which means that
a big POST could potentially DoS a box by making it run out of memory.
We might want to put a limit on here just in case, at least until
we figure out how to consume input data more efficiently into php.
2002-04-11 19:25:08 +00:00
if ( ap_pass_brigade ( f - > next , bb ) ! = APR_SUCCESS ) {
2000-10-29 16:01:02 +00:00
php_handle_aborted_connection ( ) ;
2000-10-29 15:10:49 +00:00
}
2000-10-27 13:19:23 +00:00
}
static void php_apache_sapi_log_message ( char * msg )
{
php_struct * ctx ;
2001-07-28 11:36:37 +00:00
TSRMLS_FETCH ( ) ;
2000-10-27 13:19:23 +00:00
ctx = SG ( server_context ) ;
2001-08-16 06:09:12 +00:00
/* We use APLOG_STARTUP because it keeps us from printing the
* data and time information at the beginning of the error log
* line . Not sure if this is correct , but it mirrors what happens
* with Apache 1.3 - - rbb
*/
2002-04-18 16:34:06 +00:00
if ( ctx = = NULL ) { /* we haven't initialized our ctx yet, oh well */
ap_log_error ( APLOG_MARK , APLOG_ERR | APLOG_NOERRNO | APLOG_STARTUP ,
0 , NULL , " %s " , msg ) ;
}
else {
ap_log_error ( APLOG_MARK , APLOG_ERR | APLOG_NOERRNO | APLOG_STARTUP ,
0 , ctx - > r - > server , " %s " , msg ) ;
}
2000-10-26 17:55:05 +00:00
}
2002-12-27 19:59:09 +00:00
static int
php_apache_disable_caching ( ap_filter_t * f )
{
/* Identify PHP scripts as non-cacheable, thus preventing
* Apache from sending a 304 status when the browser sends
* If - Modified - Since header .
*/
f - > r - > no_local_copy = 1 ;
return OK ;
}
2002-09-18 21:57:42 +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 ;
}
2001-01-02 22:49:31 +00:00
static sapi_module_struct apache2_sapi_module = {
2000-10-26 17:55:05 +00:00
" apache2filter " ,
" Apache 2.0 Filter " ,
2002-09-18 21:57:42 +00:00
php_apache2_startup , /* startup */
2000-10-26 17:55:05 +00:00
php_module_shutdown_wrapper , /* shutdown */
2001-08-03 05:05:47 +00:00
NULL , /* activate */
NULL , /* deactivate */
2000-10-26 17:55:05 +00:00
2002-04-14 12:38:33 +00:00
php_apache_sapi_ub_write , /* unbuffered write */
2001-08-03 05:05:47 +00:00
php_apache_sapi_flush , /* flush */
2002-09-23 18:51:34 +00:00
php_apache_sapi_get_stat , /* get uid */
2002-09-23 04:10:25 +00:00
php_apache_sapi_getenv , /* getenv */
2000-10-26 17:55:05 +00:00
2001-08-03 05:05:47 +00:00
php_error , /* error handler */
2000-10-26 17:55:05 +00:00
2002-04-14 12:38:33 +00:00
php_apache_sapi_header_handler , /* header handler */
php_apache_sapi_send_headers , /* send headers handler */
2001-08-03 05:05:47 +00:00
NULL , /* send header handler */
2000-10-26 17:55:05 +00:00
2002-04-14 12:38:33 +00:00
php_apache_sapi_read_post , /* read POST data */
php_apache_sapi_read_cookies , /* read Cookies */
2000-10-26 17:55:05 +00:00
php_apache_sapi_register_variables ,
2000-10-27 13:19:23 +00:00
php_apache_sapi_log_message , /* Log message */
2000-10-26 17:55:05 +00:00
STANDARD_SAPI_MODULE_PROPERTIES
} ;
2001-02-28 14:03:58 +00:00
static int php_input_filter ( ap_filter_t * f , apr_bucket_brigade * bb ,
2002-01-25 04:03:42 +00:00
ap_input_mode_t mode , apr_read_type_e block , apr_off_t readbytes )
2000-10-29 14:52:15 +00:00
{
php_struct * ctx ;
long old_index ;
2001-02-28 14:03:58 +00:00
apr_bucket * b ;
2000-10-29 14:52:15 +00:00
const char * str ;
2002-04-12 22:25:29 +00:00
apr_size_t n ;
2002-12-18 19:32:44 +00:00
const char * prev_fetched_str ;
apr_size_t prev_fetched_str_len ;
2000-11-01 19:19:46 +00:00
apr_status_t rv ;
2001-07-28 11:36:37 +00:00
TSRMLS_FETCH ( ) ;
2000-10-29 14:52:15 +00:00
2001-08-19 21:07:50 +00:00
if ( f - > r - > proxyreq ) {
2002-01-20 18:44:15 +00:00
return ap_get_brigade ( f - > next , bb , mode , block , readbytes ) ;
2001-08-19 21:07:50 +00:00
}
PHP filters and Apache 2 aren't quite a perfect match yet, so we have
to do some trickery with the server_context to make sure it is always
valid within the current thread.
This patch makes sure the server_context is created in apache's
post_read_request hook phase, and then registeres a cleanup that
will NULL out the server context when the request goes out of scope.
Then, inside the output filters, if the server_context is null we
throw an error. Finally, instead of saving the output filter in
the server_context, now we store the entire request_rec pointer
in there.
POST bodies appear to be working now, although they are very inefficient.
The input filter is still just realloc()ing for whatever data comes
down the input pipe, and then sending this to PHP. This means that
we are doing some really nasty memory management on big POST bodies.
For now this it allows for unlimited input bodies, which means that
a big POST could potentially DoS a box by making it run out of memory.
We might want to put a limit on here just in case, at least until
we figure out how to consume input data more efficiently into php.
2002-04-11 19:25:08 +00:00
ctx = SG ( server_context ) ;
if ( ctx = = NULL ) {
ap_log_rerror ( APLOG_MARK , APLOG_ERR | APLOG_NOERRNO , 0 , f - > r ,
" php failed to get server context " ) ;
return HTTP_INTERNAL_SERVER_ERROR ;
2002-04-11 06:01:54 +00:00
}
2000-10-29 14:52:15 +00:00
2002-01-20 18:44:15 +00:00
if ( ( rv = ap_get_brigade ( f - > next , bb , mode , block , readbytes ) ) ! = APR_SUCCESS ) {
2000-11-01 19:19:46 +00:00
return rv ;
}
2002-12-18 19:32:44 +00:00
prev_fetched_str = NULL ;
prev_fetched_str_len = - 1 ;
2002-12-09 18:45:32 +00:00
for ( b = APR_BRIGADE_FIRST ( bb ) ; b ! = APR_BRIGADE_SENTINEL ( bb ) ; b = APR_BUCKET_NEXT ( b ) ) {
2001-02-28 14:03:58 +00:00
apr_bucket_read ( b , & str , & n , 1 ) ;
2002-12-21 06:33:19 +00:00
/*
2002-12-21 06:34:31 +00:00
* An intuitive brigade bug detection
2002-12-21 06:33:19 +00:00
* ( http : //bugs.php.net/18648)
*
2002-12-21 21:50:28 +00:00
* This has something to do with the issue mentioned in the thread
2002-12-21 06:34:31 +00:00
* on dev @ httpd . apache . org :
2002-12-21 06:33:19 +00:00
*
2002-12-21 06:34:31 +00:00
* http : //marc.theaimsgroup.com/?l=apr-dev&m=104039770818472&w=2
*/
2002-12-18 19:32:44 +00:00
if ( APR_BUCKET_IS_HEAP ( b ) ) {
if ( ( str = = prev_fetched_str & & n = = prev_fetched_str_len ) ) {
char * brigade_dump = NULL ;
apr_bucket * tmp ;
for ( tmp = APR_BRIGADE_FIRST ( bb ) ; tmp ! = APR_BRIGADE_SENTINEL ( bb ) ; tmp = APR_BUCKET_NEXT ( tmp ) ) {
brigade_dump = apr_psprintf ( f - > r - > pool , " %s[%s %x] " , ( brigade_dump ? brigade_dump : " " ) , tmp - > type - > name , ( int ) tmp ) ;
}
ap_log_error ( APLOG_MARK , APLOG_WARNING , 0 , 0 , " * BUG * You encountered an apr bug. Please contact to php-dev@lists.php.net with the following information: %s " , ( brigade_dump ? brigade_dump : " (empty) " ) ) ;
}
prev_fetched_str = str ;
prev_fetched_str_len = n ;
}
2000-10-29 14:52:15 +00:00
if ( n > 0 ) {
old_index = ctx - > post_len ;
ctx - > post_len + = n ;
ctx - > post_data = realloc ( ctx - > post_data , ctx - > post_len + 1 ) ;
memcpy ( ctx - > post_data + old_index , str , n ) ;
}
}
2000-11-01 19:19:46 +00:00
return APR_SUCCESS ;
2000-10-29 14:52:15 +00:00
}
2001-07-28 11:36:37 +00:00
static void php_apache_request_ctor ( ap_filter_t * f , php_struct * ctx TSRMLS_DC )
2000-11-11 18:24:27 +00:00
{
char * content_type ;
const char * auth ;
2002-12-21 21:50:28 +00:00
2000-11-11 18:24:27 +00:00
PG ( during_request_startup ) = 0 ;
SG ( sapi_headers ) . http_response_code = 200 ;
SG ( request_info ) . content_type = apr_table_get ( f - > r - > headers_in , " Content-Type " ) ;
# undef safe_strdup
# define safe_strdup(x) ((x)?strdup((x)):NULL)
SG ( request_info ) . query_string = safe_strdup ( f - > r - > args ) ;
SG ( request_info ) . request_method = f - > r - > method ;
SG ( request_info ) . request_uri = safe_strdup ( f - > r - > uri ) ;
f - > r - > no_local_copy = 1 ;
2001-07-28 11:36:37 +00:00
content_type = sapi_get_default_content_type ( TSRMLS_C ) ;
2000-11-11 18:24:27 +00:00
f - > r - > content_type = apr_pstrdup ( f - > r - > pool , content_type ) ;
SG ( request_info ) . post_data = ctx - > post_data ;
SG ( request_info ) . post_data_length = ctx - > post_len ;
2002-12-21 21:50:28 +00:00
2000-11-11 18:24:27 +00:00
efree ( content_type ) ;
apr_table_unset ( f - > r - > headers_out , " Content-Length " ) ;
apr_table_unset ( f - > r - > headers_out , " Last-Modified " ) ;
apr_table_unset ( f - > r - > headers_out , " Expires " ) ;
apr_table_unset ( f - > r - > headers_out , " ETag " ) ;
apr_table_unset ( f - > r - > headers_in , " Connection " ) ;
2002-12-21 21:50:28 +00:00
if ( ! PG ( safe_mode ) ) {
auth = apr_table_get ( f - > r - > headers_in , " Authorization " ) ;
php_handle_auth_data ( auth TSRMLS_CC ) ;
} else {
SG ( request_info ) . auth_user = NULL ;
SG ( request_info ) . auth_password = NULL ;
}
2001-07-28 11:36:37 +00:00
php_request_startup ( TSRMLS_C ) ;
2000-11-11 18:24:27 +00:00
}
2001-07-28 11:36:37 +00:00
static void php_apache_request_dtor ( ap_filter_t * f TSRMLS_DC )
2000-11-11 18:24:27 +00:00
{
php_request_shutdown ( NULL ) ;
2002-04-12 22:25:29 +00:00
if ( SG ( request_info ) . query_string ) {
free ( SG ( request_info ) . query_string ) ;
}
2002-11-02 04:35:25 +00:00
if ( SG ( request_info ) . request_uri ) {
2002-04-12 22:25:29 +00:00
free ( SG ( request_info ) . request_uri ) ;
}
2000-11-11 18:24:27 +00:00
}
2001-02-28 14:03:58 +00:00
static int php_output_filter ( ap_filter_t * f , apr_bucket_brigade * bb )
2000-10-26 17:55:05 +00:00
{
2000-10-29 14:52:15 +00:00
php_struct * ctx ;
2001-02-28 14:03:58 +00:00
apr_bucket * b ;
2000-10-29 14:52:15 +00:00
void * conf = ap_get_module_config ( f - > r - > per_dir_config , & php4_module ) ;
2002-10-22 12:20:12 +00:00
char * p = get_php_config ( conf , " engine " , sizeof ( " engine " ) ) ;
2001-07-28 11:36:37 +00:00
TSRMLS_FETCH ( ) ;
2000-10-26 17:55:05 +00:00
2001-08-19 20:28:36 +00:00
if ( f - > r - > proxyreq ) {
return ap_pass_brigade ( f - > next , bb ) ;
2002-10-22 12:20:12 +00:00
}
/* handle situations where user turns the engine off */
if ( * p = = ' 0 ' ) {
return ap_pass_brigade ( f - > next , bb ) ;
2001-08-19 20:28:36 +00:00
}
2001-11-13 21:40:01 +00:00
/* setup standard CGI variables */
ap_add_common_vars ( f - > r ) ;
ap_add_cgi_vars ( f - > r ) ;
PHP filters and Apache 2 aren't quite a perfect match yet, so we have
to do some trickery with the server_context to make sure it is always
valid within the current thread.
This patch makes sure the server_context is created in apache's
post_read_request hook phase, and then registeres a cleanup that
will NULL out the server context when the request goes out of scope.
Then, inside the output filters, if the server_context is null we
throw an error. Finally, instead of saving the output filter in
the server_context, now we store the entire request_rec pointer
in there.
POST bodies appear to be working now, although they are very inefficient.
The input filter is still just realloc()ing for whatever data comes
down the input pipe, and then sending this to PHP. This means that
we are doing some really nasty memory management on big POST bodies.
For now this it allows for unlimited input bodies, which means that
a big POST could potentially DoS a box by making it run out of memory.
We might want to put a limit on here just in case, at least until
we figure out how to consume input data more efficiently into php.
2002-04-11 19:25:08 +00:00
ctx = SG ( server_context ) ;
if ( ctx = = NULL ) {
ap_log_rerror ( APLOG_MARK , APLOG_ERR | APLOG_NOERRNO , 0 , f - > r ,
" php failed to get server context " ) ;
return HTTP_INTERNAL_SERVER_ERROR ;
2000-10-26 17:55:05 +00:00
}
2002-04-16 17:41:28 +00:00
ctx - > f = f ; /* save whatever filters are after us in the chain. */
2000-10-26 17:55:05 +00:00
2002-04-11 06:01:54 +00:00
if ( ctx - > request_processed ) {
return ap_pass_brigade ( f - > next , bb ) ;
}
2000-10-26 17:55:05 +00:00
2002-12-09 18:45:32 +00:00
for ( b = APR_BRIGADE_FIRST ( bb ) ; b ! = APR_BRIGADE_SENTINEL ( bb ) ; b = APR_BUCKET_NEXT ( b ) ) {
2000-10-26 17:55:05 +00:00
zend_file_handle zfd ;
2002-04-11 06:01:54 +00:00
if ( ! ctx - > request_processed & & APR_BUCKET_IS_FILE ( b ) ) {
const char * path ;
apr_bucket_brigade * prebb = bb ;
/* Split the brigade into two brigades before and after
* the file bucket . Leave the " after the FILE " brigade
* in the original bb , so it gets passed outside of this
* loop . */
bb = apr_brigade_split ( prebb , b ) ;
/* Pass the "before the FILE" brigade here
* ( if it ' s non - empty ) . */
if ( ! APR_BRIGADE_EMPTY ( prebb ) ) {
apr_status_t rv ;
rv = ap_pass_brigade ( f - > next , prebb ) ;
/* XXX: destroy the prebb, since we know we're
* done with it ? */
if ( rv ! = APR_SUCCESS ) {
php_handle_aborted_connection ( ) ;
}
}
2000-10-26 21:23:20 +00:00
2002-04-11 06:01:54 +00:00
apply_config ( conf ) ;
php_apache_request_ctor ( f , ctx TSRMLS_CC ) ;
2001-07-23 04:50:13 +00:00
2002-04-11 06:01:54 +00:00
apr_file_name_get ( & path , ( ( apr_bucket_file * ) b - > data ) - > fd ) ;
2002-10-04 21:15:59 +00:00
/* Determine if we need to parse the file or show the source */
2002-10-16 20:45:36 +00:00
if ( strncmp ( ctx - > r - > handler , " application/x-httpd-php-source " , sizeof ( " application/x-httpd-php-source " ) ) ) {
2002-10-04 21:15:59 +00:00
zfd . type = ZEND_HANDLE_FILENAME ;
zfd . filename = ( char * ) path ;
zfd . free_filename = 0 ;
zfd . opened_path = NULL ;
php_execute_script ( & zfd TSRMLS_CC ) ;
} else {
zend_syntax_highlighter_ini syntax_highlighter_ini ;
php_get_highlight_struct ( & syntax_highlighter_ini ) ;
highlight_file ( ( char * ) path , & syntax_highlighter_ini TSRMLS_CC ) ;
}
2002-04-11 06:01:54 +00:00
php_apache_request_dtor ( f TSRMLS_CC ) ;
2001-07-23 04:50:13 +00:00
2002-04-11 06:01:54 +00:00
ctx - > request_processed = 1 ;
2000-10-26 17:55:05 +00:00
2002-04-11 06:01:54 +00:00
/* Delete the FILE bucket from the brigade. */
apr_bucket_delete ( b ) ;
2000-10-26 17:55:05 +00:00
2002-04-11 06:01:54 +00:00
/* We won't handle any more buckets in this brigade, so
* it ' s ok to break out now . */
break ;
}
}
/* Pass whatever is left on the brigade. */
return ap_pass_brigade ( f - > next , bb ) ;
2000-10-26 17:55:05 +00:00
}
static apr_status_t
php_apache_server_shutdown ( void * tmp )
{
2001-01-02 22:49:31 +00:00
apache2_sapi_module . shutdown ( & apache2_sapi_module ) ;
2000-10-26 17:55:05 +00:00
sapi_shutdown ( ) ;
2002-06-24 14:51:01 +00:00
# ifdef ZTS
2000-10-26 17:55:05 +00:00
tsrm_shutdown ( ) ;
2002-06-24 14:51:01 +00:00
# endif
2000-10-26 17:55:05 +00:00
return APR_SUCCESS ;
}
2001-08-28 06:23:27 +00:00
static void php_apache_add_version ( apr_pool_t * p )
{
TSRMLS_FETCH ( ) ;
if ( PG ( expose_php ) ) {
ap_add_version_component ( p , " PHP/ " PHP_VERSION ) ;
}
}
2002-04-18 22:10:57 +00:00
static int php_pre_config ( apr_pool_t * pconf , apr_pool_t * plog , apr_pool_t * ptemp )
{
2002-06-24 16:04:20 +00:00
# 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
2002-04-18 22:10:57 +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 ;
}
2001-11-29 11:29:11 +00:00
static int
2001-08-28 06:19:58 +00:00
php_apache_server_startup ( apr_pool_t * pconf , apr_pool_t * plog ,
apr_pool_t * ptemp , server_rec * s )
2000-10-26 17:55:05 +00:00
{
2002-04-24 00:55:38 +00:00
void * data = NULL ;
const char * userdata_key = " apache2filter_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 ) {
2002-05-05 18:11:41 +00:00
/* 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 . */
apr_pool_userdata_set ( ( const void * ) 1 , userdata_key ,
apr_pool_cleanup_null , s - > process - > pool ) ;
2002-04-24 00:55:38 +00:00
return OK ;
}
2002-04-18 22:10:57 +00:00
/* Set up our overridden path. */
if ( apache2_php_ini_path_override ) {
apache2_sapi_module . php_ini_path_override = apache2_php_ini_path_override ;
}
2002-06-24 14:51:01 +00:00
# ifdef ZTS
2000-11-18 02:44:04 +00:00
tsrm_startup ( 1 , 1 , 0 , NULL ) ;
2002-06-24 14:51:01 +00:00
# endif
2001-01-08 23:18:47 +00:00
sapi_startup ( & apache2_sapi_module ) ;
2001-01-02 22:49:31 +00:00
apache2_sapi_module . startup ( & apache2_sapi_module ) ;
2001-08-28 06:19:58 +00:00
apr_pool_cleanup_register ( pconf , NULL , php_apache_server_shutdown , apr_pool_cleanup_null ) ;
2001-08-28 06:23:27 +00:00
php_apache_add_version ( pconf ) ;
2001-11-29 11:29:11 +00:00
return OK ;
2000-10-26 17:55:05 +00:00
}
2001-08-20 16:34:45 +00:00
static void php_add_filter ( request_rec * r , ap_filter_t * f )
{
int output = ( f = = r - > output_filters ) ;
/* for those who still have Set*Filter PHP configured */
while ( f ) {
if ( strcmp ( f - > frec - > name , " PHP " ) = = 0 ) {
ap_log_error ( APLOG_MARK , APLOG_WARNING | APLOG_NOERRNO ,
0 , r - > server ,
" \" Set%sFilter PHP \" already configured for %s " ,
output ? " Output " : " Input " , r - > uri ) ;
return ;
}
f = f - > next ;
}
if ( output ) {
ap_add_output_filter ( " PHP " , NULL , r , r - > connection ) ;
2002-04-14 12:38:33 +00:00
} else {
2001-08-20 16:34:45 +00:00
ap_add_input_filter ( " PHP " , NULL , r , r - > connection ) ;
}
}
static void php_insert_filter ( request_rec * r )
{
2002-10-04 21:15:59 +00:00
int content_type_len = strlen ( " application/x-httpd-php " ) ;
if ( r - > content_type & & ! strncmp ( r - > content_type , " application/x-httpd-php " , content_type_len - 1 ) ) {
2002-10-04 21:31:34 +00:00
if ( r - > content_type [ content_type_len ] = = ' \0 ' | | ! strncmp ( r - > content_type + content_type_len , " -source " , sizeof ( " -source " ) ) ) {
2002-10-04 21:15:59 +00:00
php_add_filter ( r , r - > output_filters ) ;
php_add_filter ( r , r - > input_filters ) ;
}
2001-08-20 16:34:45 +00:00
}
}
PHP filters and Apache 2 aren't quite a perfect match yet, so we have
to do some trickery with the server_context to make sure it is always
valid within the current thread.
This patch makes sure the server_context is created in apache's
post_read_request hook phase, and then registeres a cleanup that
will NULL out the server context when the request goes out of scope.
Then, inside the output filters, if the server_context is null we
throw an error. Finally, instead of saving the output filter in
the server_context, now we store the entire request_rec pointer
in there.
POST bodies appear to be working now, although they are very inefficient.
The input filter is still just realloc()ing for whatever data comes
down the input pipe, and then sending this to PHP. This means that
we are doing some really nasty memory management on big POST bodies.
For now this it allows for unlimited input bodies, which means that
a big POST could potentially DoS a box by making it run out of memory.
We might want to put a limit on here just in case, at least until
we figure out how to consume input data more efficiently into php.
2002-04-11 19:25:08 +00:00
static apr_status_t php_server_context_cleanup ( void * data_ )
{
void * * data = data_ ;
* data = NULL ;
return APR_SUCCESS ;
}
static int php_post_read_request ( request_rec * r )
{
php_struct * ctx ;
TSRMLS_FETCH ( ) ;
/* Initialize filter context */
SG ( server_context ) = ctx = 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 ) ;
/* Save the entire request, so we can get the input or output
* filters if we need them . */
ctx - > r = r ;
return OK ;
}
2001-02-28 14:03:58 +00:00
static void php_register_hook ( apr_pool_t * p )
2000-10-26 17:55:05 +00:00
{
2002-04-18 22:10:57 +00:00
ap_hook_pre_config ( php_pre_config , NULL , NULL , APR_HOOK_MIDDLE ) ;
2001-08-28 06:19:58 +00:00
ap_hook_post_config ( php_apache_server_startup , NULL , NULL , APR_HOOK_MIDDLE ) ;
2001-08-20 16:34:45 +00:00
ap_hook_insert_filter ( php_insert_filter , NULL , NULL , APR_HOOK_MIDDLE ) ;
2002-04-14 12:38:33 +00:00
ap_hook_post_read_request ( php_post_read_request , NULL , NULL , APR_HOOK_MIDDLE ) ;
2002-12-27 19:59:09 +00:00
ap_register_output_filter ( " PHP " , php_output_filter , php_apache_disable_caching , AP_FTYPE_RESOURCE ) ;
ap_register_input_filter ( " PHP " , php_input_filter , php_apache_disable_caching , AP_FTYPE_RESOURCE ) ;
2000-10-26 17:55:05 +00:00
}
2001-02-28 14:03:58 +00:00
AP_MODULE_DECLARE_DATA module php4_module = {
2002-04-14 12:38:33 +00:00
STANDARD20_MODULE_STUFF ,
create_php_config , /* create per-directory config structure */
merge_php_config , /* merge per-directory config structures */
NULL , /* create per-server config structure */
NULL , /* merge per-server config structures */
php_dir_cmds , /* command apr_table_t */
php_register_hook /* register hooks */
2000-10-26 17:55:05 +00:00
} ;
2001-08-22 04:45:51 +00:00
/*
* Local variables :
* tab - width : 4
* c - basic - offset : 4
* End :
2001-09-09 13:29:31 +00:00
* vim600 : sw = 4 ts = 4 fdm = marker
* vim < 600 : sw = 4 ts = 4
2001-08-22 04:45:51 +00:00
*/