2001-11-05 20:07:49 +08:00
/*
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2004-01-08 16:18:22 +08:00
| PHP Version 5 |
2001-11-05 20:07:49 +08:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2007-01-01 17:29:37 +08:00
| Copyright ( c ) 1997 - 2007 The PHP Group |
2001-11-05 20:07:49 +08:00
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
2006-01-01 21:10:10 +08:00
| This source file is subject to version 3.01 of the PHP license , |
2001-11-05 20:07:49 +08:00
| that is bundled with this package in the file LICENSE , and is |
2003-06-11 04:04:29 +08:00
| available through the world - wide - web at the following url : |
2006-01-01 21:10:10 +08:00
| http : //www.php.net/license/3_01.txt |
2001-11-05 20:07:49 +08: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 . |
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
| Author : Alex Waugh < alex @ alexwaugh . com > |
+ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - +
*/
# include "php.h"
# include "SAPI.h"
# include "php_main.h"
# include "php_variables.h"
# define WEBJAMES_PHP_ONLY
# include "php_webjames.h"
# include <unixlib/local.h>
2006-11-27 03:50:30 +08:00
# define WEBJAMES_SAPI_VERSION "1.0.2"
2001-11-05 20:07:49 +08:00
typedef struct {
struct connection * conn ; /*structure holding all the details of the current request*/
int bodyread ; /*amount of POST body read*/
closefn oldclose ; /*function to call to close the connection*/
} php_webjames_globals ;
static php_webjames_globals webjames_globals ;
# define WG(v) (webjames_globals.v)
2002-02-17 20:55:52 +08:00
static int sapi_webjames_ub_write ( const char * str , uint str_length TSRMLS_DC )
2001-11-05 20:07:49 +08:00
/*unbuffered write - send data straight out to socket*/
{
2006-11-27 03:50:30 +08:00
int totalbytes = 0 ;
do {
int bytes ;
bytes = webjames_writebuffer ( WG ( conn ) , str , str_length ) ;
if ( bytes < 0 ) {
PG ( connection_status ) = PHP_CONNECTION_ABORTED ;
if ( ! PG ( ignore_user_abort ) ) {
zend_bailout ( ) ;
}
return bytes ;
2001-11-05 20:07:49 +08:00
}
2006-11-27 03:50:30 +08:00
str + = bytes ;
str_length - = bytes ;
totalbytes + = bytes ;
} while ( str_length ) ;
return totalbytes ;
2001-11-05 20:07:49 +08:00
}
2002-02-17 20:55:52 +08:00
static void sapi_webjames_send_header ( sapi_header_struct * sapi_header , void * server_context TSRMLS_DC )
2001-11-05 20:07:49 +08:00
/*send an HTTP header*/
{
2006-11-27 03:50:30 +08:00
char * header = sapi_header - > header ;
int len = sapi_header - > header_len ;
2001-11-05 20:07:49 +08:00
if ( WG ( conn ) - > flags . outputheaders ) {
2006-11-27 03:50:30 +08:00
while ( sapi_header & & len > 0 ) {
int bytes ;
bytes = webjames_writebuffer ( WG ( conn ) , header , len ) ;
if ( bytes < 0 ) {
PG ( connection_status ) = PHP_CONNECTION_ABORTED ;
if ( ! PG ( ignore_user_abort ) ) {
zend_bailout ( ) ;
}
return ;
}
header + = bytes ;
len - = bytes ;
}
2001-11-05 20:07:49 +08:00
webjames_writestring ( WG ( conn ) , " \r \n " ) ;
}
}
2002-02-17 20:55:52 +08:00
static int sapi_webjames_read_post ( char * buffer , uint count_bytes TSRMLS_DC )
2001-11-05 20:07:49 +08:00
/*read some of the post data*/
{
if ( WG ( conn ) - > body = = NULL ) return 0 ;
if ( count_bytes + WG ( bodyread ) > WG ( conn ) - > bodysize ) count_bytes = WG ( conn ) - > bodysize - WG ( bodyread ) ;
memcpy ( buffer , WG ( conn ) - > body + WG ( bodyread ) , count_bytes ) ;
WG ( bodyread ) + = count_bytes ;
return count_bytes ;
}
2002-02-17 20:55:52 +08:00
static char * sapi_webjames_read_cookies ( TSRMLS_D )
2001-11-05 20:07:49 +08:00
{
return WG ( conn ) - > cookie ;
}
# define BUF_SIZE 512
# define ADD_STRING(name,string)\
2002-02-17 20:55:52 +08:00
php_register_variable ( name , string , track_vars_array TSRMLS_CC )
2001-11-05 20:07:49 +08:00
# define ADD_NUM(name,field) {\
snprintf ( buf , BUF_SIZE , " %d " , WG ( conn ) - > field ) ; \
2002-02-17 20:55:52 +08:00
php_register_variable ( name , buf , track_vars_array TSRMLS_CC ) ; \
2001-11-05 20:07:49 +08:00
}
2002-02-17 20:55:52 +08:00
# define ADD_FIELD(name, field) \
if ( WG ( conn ) - > field ) { \
php_register_variable ( name , WG ( conn ) - > field , track_vars_array TSRMLS_CC ) ; \
2001-11-05 20:07:49 +08:00
}
2002-02-17 20:55:52 +08:00
static void sapi_webjames_register_variables ( zval * track_vars_array TSRMLS_DC )
2001-11-05 20:07:49 +08:00
{
char buf [ BUF_SIZE + 1 ] ;
2006-03-08 06:34:37 +08:00
char * docroot ;
2001-11-05 20:07:49 +08:00
buf [ BUF_SIZE ] = ' \0 ' ;
ADD_STRING ( " SERVER_SOFTWARE " , configuration . server ) ;
ADD_STRING ( " SERVER_NAME " , configuration . serverip ) ;
ADD_FIELD ( " SERVER_PROTOCOL " , protocol ) ;
ADD_NUM ( " SERVER_PORT " , port ) ;
ADD_STRING ( " SERVER_ADMIN " , configuration . webmaster ) ;
ADD_STRING ( " GATEWAY_INTERFACE " , " CGI/1.1 " ) ;
2006-03-08 06:34:37 +08:00
docroot = __unixify ( WG ( conn ) - > homedir , 0 , NULL , 1024 , 0 ) ;
if ( docroot ) ADD_STRING ( " DOCUMENT_ROOT " , docroot ) ;
2001-11-05 20:07:49 +08:00
ADD_FIELD ( " REQUEST_METHOD " , methodstr ) ;
ADD_FIELD ( " REQUEST_URI " , requesturi ) ;
ADD_STRING ( " PATH_TRANSLATED " , SG ( request_info ) . path_translated ) ;
ADD_FIELD ( " SCRIPT_NAME " , uri ) ;
ADD_FIELD ( " PHP_SELF " , uri ) ;
ADD_FIELD ( " QUERY_STRING " , args ) ;
snprintf ( buf , BUF_SIZE , " %d.%d.%d.%d " , WG ( conn ) - > ipaddr [ 0 ] , WG ( conn ) - > ipaddr [ 1 ] , WG ( conn ) - > ipaddr [ 2 ] , WG ( conn ) - > ipaddr [ 3 ] ) ;
ADD_STRING ( " REMOTE_ADDR " , buf ) ;
if ( WG ( conn ) - > dnsstatus = = DNS_OK ) ADD_FIELD ( " REMOTE_HOST " , host ) ;
if ( ( WG ( conn ) - > method = = METHOD_POST ) | | ( WG ( conn ) - > method = = METHOD_PUT ) ) {
ADD_NUM ( " CONTENT_LENGTH " , bodysize ) ;
ADD_FIELD ( " CONTENT_TYPE " , type ) ;
}
if ( ( WG ( conn ) - > method = = METHOD_PUT ) | | ( WG ( conn ) - > method = = METHOD_DELETE ) ) ADD_FIELD ( " ENTITY_PATH " , requesturi ) ;
if ( WG ( conn ) - > pwd ) {
ADD_STRING ( " AUTH_TYPE " , " basic " ) ;
ADD_FIELD ( " REMOTE_USER " , authorization ) ;
}
ADD_FIELD ( " HTTP_COOKIE " , cookie ) ;
ADD_FIELD ( " HTTP_USER_AGENT " , useragent ) ;
ADD_FIELD ( " HTTP_REFERER " , referer ) ;
ADD_FIELD ( " HTTP_ACCEPT " , accept ) ;
ADD_FIELD ( " HTTP_ACCEPT_LANGUAGE " , acceptlanguage ) ;
ADD_FIELD ( " HTTP_ACCEPT_CHARSET " , acceptcharset ) ;
ADD_FIELD ( " HTTP_ACCEPT_ENCODING " , acceptencoding ) ;
}
2002-02-17 20:55:52 +08:00
static void webjames_module_main ( TSRMLS_D )
2001-11-05 20:07:49 +08:00
{
zend_file_handle file_handle ;
FILE * fp = NULL ;
char * path ;
/* Convert filename to Unix format*/
2006-03-08 06:34:37 +08:00
__riscosify_control | = __RISCOSIFY_STRICT_UNIX_SPECS ;
2001-11-05 20:07:49 +08:00
path = __unixify ( WG ( conn ) - > filename , 0 , NULL , 1024 , 0 ) ;
if ( path ) SG ( request_info ) . path_translated = estrdup ( path ) ;
SG ( request_info ) . query_string = WG ( conn ) - > args ;
SG ( request_info ) . request_uri = WG ( conn ) - > requesturi ;
SG ( request_info ) . request_method = WG ( conn ) - > methodstr ;
if ( WG ( conn ) - > method = = METHOD_HEAD ) {
SG ( request_info ) . headers_only = 1 ;
} else {
SG ( request_info ) . headers_only = 0 ;
}
SG ( sapi_headers ) . http_response_code = 200 ;
SG ( request_info ) . content_type = WG ( conn ) - > type ;
SG ( request_info ) . content_length = WG ( conn ) - > bodysize ;
SG ( request_info ) . auth_user = NULL ;
SG ( request_info ) . auth_password = NULL ;
if ( WG ( conn ) - > authorization ) {
char * colon = strchr ( WG ( conn ) - > authorization , ' : ' ) ;
if ( colon ) {
SG ( request_info ) . auth_user = emalloc ( colon - WG ( conn ) - > authorization + 1 ) ;
if ( SG ( request_info ) . auth_user ) {
memcpy ( SG ( request_info ) . auth_user , WG ( conn ) - > authorization , colon - WG ( conn ) - > authorization ) ;
SG ( request_info ) . auth_user [ colon - WG ( conn ) - > authorization ] = ' \0 ' ;
SG ( request_info ) . auth_password = estrdup ( colon + 1 ) ;
}
}
}
2002-02-17 20:55:52 +08:00
/*ensure that syslog calls get logged separately from WebJames' main log */
2001-11-05 20:07:49 +08:00
openlog ( " PHP " , 0 , 0 ) ;
file_handle . type = ZEND_HANDLE_FILENAME ;
file_handle . filename = SG ( request_info ) . path_translated ;
file_handle . free_filename = 0 ;
file_handle . opened_path = NULL ;
2002-02-17 20:55:52 +08:00
if ( php_request_startup ( TSRMLS_C ) = = FAILURE ) {
2001-11-05 20:07:49 +08:00
return ;
}
2002-02-17 20:55:52 +08:00
php_execute_script ( & file_handle TSRMLS_CC ) ;
2001-11-05 20:07:49 +08:00
php_request_shutdown ( NULL ) ;
}
static void webjames_php_close ( struct connection * conn , int force )
/*called by webjames if it wants to close the connection*/
{
2002-02-17 20:55:52 +08:00
TSRMLS_FETCH ( ) ;
2001-11-05 20:07:49 +08:00
php_request_shutdown ( NULL ) ;
WG ( oldclose ) ( conn , force ) ;
}
void webjames_php_request ( struct connection * conn )
/*called by WebJames to start handler*/
{
2002-02-17 20:55:52 +08:00
TSRMLS_FETCH ( ) ;
2001-11-05 20:07:49 +08:00
WG ( conn ) = conn ;
WG ( bodyread ) = 0 ;
WG ( oldclose ) = conn - > close ;
conn - > close = webjames_php_close ;
2002-02-17 20:55:52 +08:00
webjames_module_main ( TSRMLS_C ) ;
2001-11-05 20:07:49 +08:00
WG ( oldclose ) ( WG ( conn ) , 0 ) ;
}
static void php_info_webjames ( ZEND_MODULE_INFO_FUNC_ARGS )
{
php_info_print_table_start ( ) ;
php_info_print_table_row ( 2 , " SAPI module version " , WEBJAMES_SAPI_VERSION ) ;
php_info_print_table_row ( 2 , " WebJames version " , WEBJAMES_VERSION " ( " WEBJAMES_DATE " ) " ) ;
php_info_print_table_end ( ) ;
}
static zend_module_entry php_webjames_module = {
# if ZEND_MODULE_API_NO >= 20010901
STANDARD_MODULE_HEADER ,
# endif
" WebJames " ,
NULL ,
NULL ,
NULL ,
NULL ,
NULL ,
php_info_webjames ,
# if ZEND_MODULE_API_NO >= 20010901
WEBJAMES_SAPI_VERSION ,
# endif
STANDARD_MODULE_PROPERTIES
} ;
2002-09-19 05:57:42 +08:00
2001-11-05 20:07:49 +08:00
static int php_webjames_startup ( sapi_module_struct * sapi_module )
{
2002-09-19 05:57:42 +08:00
if ( php_module_startup ( sapi_module , & php_webjames_module , 1 ) = = FAILURE ) {
2001-11-05 20:07:49 +08:00
return FAILURE ;
} else {
return SUCCESS ;
}
}
static sapi_module_struct sapi_module = {
" webjames " , /* name */
" WebJames " , /* pretty name */
php_webjames_startup , /* startup */
php_module_shutdown_wrapper , /* shutdown */
NULL , /* activate */
NULL , /* deactivate */
sapi_webjames_ub_write , /* unbuffered write */
NULL , /* flush */
NULL , /* get uid */
NULL , /* getenv */
php_error , /* error handler */
NULL , /* header handler */
2002-07-03 18:42:31 +08:00
NULL , /* send headers handler */
2001-11-05 20:07:49 +08:00
sapi_webjames_send_header , /* send header handler */
sapi_webjames_read_post , /* read POST data */
sapi_webjames_read_cookies , /* read Cookies */
sapi_webjames_register_variables , /* register server variables */
NULL , /* Log message */
2004-12-21 03:33:41 +08:00
NULL , /* Get request time */
2001-11-05 20:07:49 +08:00
STANDARD_SAPI_MODULE_PROPERTIES
} ;
int webjames_php_init ( void )
/*called when WebJames initialises*/
{
2002-02-17 20:55:52 +08:00
TSRMLS_FETCH ( ) ;
2001-11-05 20:07:49 +08:00
if ( strcmp ( configuration . webjames_h_revision , WEBJAMES_H_REVISION ) ! = 0 ) {
/*This file was compiled against a different revision of
webjames . h than webjames was , which could be bad news */
webjames_writelog ( 0 , " PHP module is compiled for WebJames (%s) and was linked with a different version (%s) " , WEBJAMES_H_REVISION , configuration . webjames_h_revision ) ;
return 0 ; /*failed to initialise*/
}
sapi_startup ( & sapi_module ) ;
sapi_module . startup ( & sapi_module ) ;
SG ( server_context ) = ( void * ) 1 ;
return 1 ; /*initialised correctly*/
}
void webjames_php_shutdown ( void )
/*called when WebJames is about to quit*/
{
sapi_module . shutdown ( & sapi_module ) ;
sapi_shutdown ( ) ;
}