8 changed files with 3905 additions and 0 deletions
-
2sapi/litespeed/CREDITS
-
3sapi/litespeed/Makefile.frag
-
225sapi/litespeed/README
-
36sapi/litespeed/config.m4
-
908sapi/litespeed/lsapi_main.c
-
196sapi/litespeed/lsapidef.h
-
2177sapi/litespeed/lsapilib.c
-
358sapi/litespeed/lsapilib.h
@ -0,0 +1,2 @@ |
|||
litespeed |
|||
George Wang |
|||
@ -0,0 +1,3 @@ |
|||
$(SAPI_LITESPEED_PATH): $(PHP_GLOBAL_OBJS) $(PHP_SAPI_OBJS) |
|||
$(BUILD_LITESPEED) |
|||
|
|||
@ -0,0 +1,225 @@ |
|||
Introduction |
|||
============ |
|||
|
|||
LiteSpeed SAPI module is a dedicated interface for PHP integration with |
|||
LiteSpeed Web Server. LiteSpeed SAPI has similar architecture to the |
|||
FastCGI SAPI with there major enhancements: better performance, dynamic |
|||
spawning and PHP configuration modification through web server |
|||
configuration and .htaccess files. |
|||
|
|||
Our simple benchmark test ("hello world") shows that PHP with |
|||
LiteSpeed SAPI has 30% better performance over PHP with FastCGI SAPI, |
|||
which is nearly twice the performance that Apache mod_php can deliver. |
|||
|
|||
A major drawback of FastCGI PHP comparing to Apache mod_php is lacking |
|||
the flexibilities in PHP configurations. PHP configurations cannot be |
|||
changed at runtime via configuration files like .htaccess files or web |
|||
server's virtual host configuration. In shared hosting environment, |
|||
each hosting account will has its own "open_basedir" overridden in |
|||
server configuration to enhance server security when mod_php is used. |
|||
usually, FastCGI PHP is not an option in shared hosting environment |
|||
due to lacking of this flexibility. LiteSpeed SAPI is carefully designed |
|||
to address this issue. PHP configurations can be modified the same way |
|||
as that in mod_php with the the same configuration directives. |
|||
|
|||
PHP with LiteSpeed SAPI is highly recommended over FastCGI PHP for |
|||
PHP scripting with LiteSpeed web server. |
|||
|
|||
|
|||
Building PHP with LiteSpeed SAPI |
|||
================================ |
|||
|
|||
You need to add "--with-litespeed" to the configure command to build |
|||
PHP with LiteSpeed SAPI, all other SAPI related configure options |
|||
should be removed. |
|||
|
|||
For example: |
|||
./configure --with-litespeed |
|||
make |
|||
|
|||
You should find an executable called 'php' under sapi/litespeed/ |
|||
directory after the compilation succeeds. Copy it to |
|||
'lsws/fcgi-bin/lsphp' or wherever you prefer, if LiteSpeed web server |
|||
has been configured to run PHP with LiteSpeed SAPI already, you just |
|||
need to overwrite the old executable with this one and you are all |
|||
set. |
|||
|
|||
Start PHP from command line |
|||
=========================== |
|||
|
|||
Usually, lsphp is managed by LiteSpeed web server in a single server |
|||
installation. lsphp can be used in clustered environment with one |
|||
LiteSpeed web server at the front, load balancing lsphp processes |
|||
running on multiple backend servers. In such environment, lsphp can be |
|||
start manually from command with option "-b <socket_address>", socket |
|||
address can be IPv4, IPv6 or Unix Domain Socket address. |
|||
for example: |
|||
|
|||
./lsphp -b [::]:3000 |
|||
|
|||
have lsphp bind to port 3000 on all IPv4 and IPv6 address, |
|||
|
|||
./lsphp -b *:3000 |
|||
|
|||
have lsphp bind to port 300 on all IPv4 address. |
|||
|
|||
./lsphp -b 192.168.0.2:3000 |
|||
|
|||
have lsphp bind to address 192.168.0.2:3000. |
|||
|
|||
./lsphp -b /tmp/lsphp_manual.sock |
|||
|
|||
have lsphp accept request on Unix domain socket "/tmp/lsphp_manual.sock" |
|||
|
|||
|
|||
Using LiteSpeed PHP with LiteSpeed Web Server |
|||
============================================= |
|||
|
|||
Detailed information about how to configure LiteSpeed web server with |
|||
PHP support is available from our website, at: |
|||
|
|||
http://www.litespeedtech.com/docs/HowTo_QA.html |
|||
|
|||
Usually, PHP support has been configured out of box, you don't need to |
|||
change it unless you want to change PHP interface from FastCGI to |
|||
LiteSpeed SAPI or vice versa. |
|||
|
|||
Brief instructions are as follow: |
|||
|
|||
1) Login to web administration interface, go to 'Server'->'Ext App' tab, |
|||
add an external application of type "LSAPI app", "Command" should be |
|||
set to a shell command that executes the PHP binary you just built. |
|||
"Instances" should be set to "1". Add "LSAPI_CHILDREN" environment |
|||
variable to match the value of "Max Connections". More tunable |
|||
environment variable described below can be added. |
|||
|
|||
2) Go to 'Server'->'Script Handler' tab, add a script handler |
|||
configuration: set 'suffix' to 'php', 'Handler Type' to 'LiteSpeed |
|||
API', 'Handler Name' should be the name of external application |
|||
just defined. |
|||
|
|||
|
|||
3) Click 'Apply Changes' link on the top left of the page, then click |
|||
'graceful restart'. Now PHP is running with LiteSpeed SAPI. |
|||
|
|||
Tunings |
|||
------- |
|||
|
|||
There are a few environment variables that can be tweaked to control the |
|||
behavior of LSAPI application. |
|||
|
|||
* LSAPI_CHILDREN or PHP_LSAPI_CHILDREN (default: 0) |
|||
|
|||
There are two ways to let PHP handle multiple requests concurrently, |
|||
Server Managed Mode and Self Managed Mode. In Server Managed Mode, |
|||
LiteSpeed web server dynamically spawn/stop PHP processes, in this mode |
|||
"Instances" should match "Max Connections" configuration for PHP |
|||
external application. To start PHP in Self Managed Mode, "Instances" |
|||
should be set to "1", while "LSAPI_CHILDREN" environment variable should |
|||
be set to match the value of "Max Connections" and >1. Web Server will |
|||
start one PHP process, this process will start/stop children PHP processes |
|||
dynamically based on on demand. If "LSAPI_CHILDREN" <=1, PHP will be |
|||
started in server managed mode. |
|||
|
|||
Self Managed Mode is preferred because all PHP processes can share one |
|||
shared memory block for the opcode cache. |
|||
|
|||
Usually, there is no need to set value of LSAPI_CHILDREN over 100 in |
|||
most server environment. |
|||
|
|||
|
|||
* LSAPI_AVOID_FORK (default: 0) |
|||
|
|||
LSAPI_AVOID_FORK specifies the policy of the internal process manager in |
|||
"Self Managed Mode". When set to 0, the internal process manager will stop |
|||
and start children process on demand to save system resource. This is |
|||
preferred in a shared hosting environment. When set to 1, the internal |
|||
process manager will try to avoid freqently stopping and starting children |
|||
process. This might be preferred in a dedicate hosting environment. |
|||
|
|||
|
|||
* LSAPI_EXTRA_CHILDREN (default: 1/3 of LSAPI_CHILDREN or 0) |
|||
|
|||
LSAPI_EXTRA_CHILDREN controls the maximum number of extra children processes |
|||
can be started when some or all existing children processes are in |
|||
malfunctioning state. Total number of children processes will be reduced to |
|||
LSAPI_CHILDREN level as soon as service is back to normal. |
|||
When LSAPI_AVOID_FORK is set to 0, the default value is 1/3 of |
|||
LSAPI_CHIDLREN, When LSAPI_AVOID_FORK is set to 1, the default value is 0. |
|||
|
|||
|
|||
* LSAPI_MAX_REQS or PHP_LSAPI_MAX_REQUESTS (default value: 10000) |
|||
|
|||
This controls how many requests each child process will handle before |
|||
it exits automatically. Several PHP functions have been identified |
|||
having memory leaks. This parameter can help reducing memory usage |
|||
of leaky PHP functions. |
|||
|
|||
|
|||
* LSAPI_MAX_IDLE (default value: 300 seconds) |
|||
|
|||
In Self Managed Mode, LSAPI_MAX_IDLE controls how long a idle child |
|||
process will wait for a new request before it exits. This option help |
|||
releasing system resources taken by idle processes. |
|||
|
|||
|
|||
* LSAPI_MAX_IDLE_CHILDREN |
|||
(default value: 1/3 of LSAPI_CHILDREN or LSAPI_CHILDREN) |
|||
|
|||
In Self Managed Mode, LSAI_MAX_IDLE_CHILDREN controls how many idle |
|||
children processes are allowed. Excessive idle children processes |
|||
will be killed by the parent process immediately. |
|||
When LSAPI_AVOID_FORK is set to 0, the default value is 1/3 of |
|||
LSAPI_CHIDLREN, When LSAPI_AVOID_FORK is set to 1, the default value |
|||
is LSAPI_CHILDREN. |
|||
|
|||
|
|||
* LSAPI_MAX_PROCESS_TIME (default value: 300 seconds) |
|||
|
|||
In Self Managed Mode, LSAPI_MAX_PROCESS_TIME controls the maximum |
|||
processing time allowed when processing a request. If a child process |
|||
can not finish processing of a request in the given time period, it |
|||
will be killed by the parent process. This option can help getting rid |
|||
of dead or runaway child process. |
|||
|
|||
|
|||
* LSAPI_PGRP_MAX_IDLE (default value: FOREVER ) |
|||
|
|||
In Self Managed Mode, LSAPI_PGRP_MAX_IDLE controls how long the parent |
|||
process will wait before exiting when there is no child process. |
|||
This option help releasing system resources taken by an idle parent |
|||
process. |
|||
|
|||
|
|||
* LSAPI_PPID_NO_CHECK |
|||
|
|||
By default a LSAPI application check the existence of its parent process |
|||
and exits automatically if the parent process died. This is to reduce |
|||
orphan process when web server is restarted. However, it is desireable |
|||
to disable this feature, such as when a LSAPI process was started |
|||
manually from command line. LSAPI_PPID_NO_CHECK should be set when |
|||
you want to disable the checking of existence of parent process. |
|||
When PHP started by "-b" option, it is disabled automatically. |
|||
|
|||
|
|||
Compatibility with Apache mod_php |
|||
================================= |
|||
|
|||
LSAPI PHP supports PHP configuration overridden via web server configuration |
|||
as well as .htaccess. |
|||
Since 4.0 release "apache_response_headers" function is supported. |
|||
|
|||
|
|||
|
|||
Contact |
|||
======= |
|||
|
|||
For support questions, please post to our free support forum, at: |
|||
|
|||
http://www.litespeedtech.com/forum/ |
|||
|
|||
For bug report, please send bug report to bug [at] litespeedtech.com. |
|||
|
|||
|
|||
|
|||
|
|||
@ -0,0 +1,36 @@ |
|||
dnl |
|||
dnl $Id$ |
|||
dnl |
|||
|
|||
AC_MSG_CHECKING(for LiteSpeed support) |
|||
|
|||
AC_ARG_WITH(litespeed, |
|||
[ --with-litespeed Build PHP as litespeed module], |
|||
[ |
|||
PHP_SAPI_LITESPEED=$withval |
|||
],[ |
|||
PHP_SAPI_LITESPEED=no |
|||
]) |
|||
|
|||
if test "$PHP_SAPI_LITESPEED" != "no"; then |
|||
PHP_ADD_MAKEFILE_FRAGMENT($abs_srcdir/sapi/litespeed/Makefile.frag,$abs_srcdir/sapi/litespeed,sapi/litespeed) |
|||
SAPI_LITESPEED_PATH=sapi/litespeed/php |
|||
PHP_SUBST(SAPI_LITESPEED_PATH) |
|||
PHP_SELECT_SAPI(litespeed, program, lsapi_main.c lsapilib.c, "", '$(SAPI_LITESPEED_PATH)') |
|||
case $host_alias in |
|||
*darwin*) |
|||
BUILD_LITESPEED="\$(CC) \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(NATIVE_RPATHS) \$(PHP_GLOBAL_OBJS:.lo=.o) \$(PHP_SAPI_OBJS:.lo=.o) \$(PHP_FRAMEWORKS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_LITESPEED_PATH)" |
|||
;; |
|||
*cygwin*) |
|||
SAPI_LITESPEED_PATH=sapi/litespeed/php.exe |
|||
BUILD_LITESPEED="\$(LIBTOOL) --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS) \$(PHP_SAPI_OBJS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_LITESPEED_PATH)" |
|||
;; |
|||
*) |
|||
BUILD_LITESPEED="\$(LIBTOOL) --mode=link \$(CC) -export-dynamic \$(CFLAGS_CLEAN) \$(EXTRA_CFLAGS) \$(EXTRA_LDFLAGS_PROGRAM) \$(LDFLAGS) \$(PHP_RPATHS) \$(PHP_GLOBAL_OBJS) \$(PHP_SAPI_OBJS) \$(EXTRA_LIBS) \$(ZEND_EXTRA_LIBS) -o \$(SAPI_LITESPEED_PATH)" |
|||
;; |
|||
esac |
|||
|
|||
PHP_SUBST(BUILD_LITESPEED) |
|||
fi |
|||
|
|||
AC_MSG_RESULT($PHP_SAPI_LITESPEED) |
|||
@ -0,0 +1,908 @@ |
|||
/* |
|||
+----------------------------------------------------------------------+ |
|||
| PHP Version 5 | |
|||
+----------------------------------------------------------------------+ |
|||
| 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 at 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. | |
|||
+----------------------------------------------------------------------+ |
|||
| Author: George Wang <gwang@litespeedtech.com> | |
|||
+----------------------------------------------------------------------+ |
|||
*/ |
|||
|
|||
|
|||
#include "php.h" |
|||
#include "SAPI.h" |
|||
#include "php_main.h" |
|||
#include "php_ini.h" |
|||
#include "php_variables.h" |
|||
#include "zend_highlight.h" |
|||
#include "zend.h" |
|||
|
|||
#include "lsapilib.h" |
|||
|
|||
#include <stdio.h> |
|||
|
|||
#if HAVE_STDLIB_H |
|||
#include <stdlib.h> |
|||
#endif |
|||
|
|||
#if HAVE_UNISTD_H |
|||
#include <unistd.h> |
|||
#endif |
|||
|
|||
#ifdef PHP_WIN32 |
|||
|
|||
#include <io.h> |
|||
#include <fcntl.h> |
|||
#include "win32/php_registry.h" |
|||
|
|||
#else |
|||
|
|||
#include <sys/wait.h> |
|||
|
|||
#endif |
|||
|
|||
#include <sys/stat.h> |
|||
|
|||
#if HAVE_SYS_TYPES_H |
|||
|
|||
#include <sys/types.h> |
|||
|
|||
#endif |
|||
|
|||
#if HAVE_SIGNAL_H |
|||
|
|||
#include <signal.h> |
|||
|
|||
#endif |
|||
|
|||
#include <sys/socket.h> |
|||
#include <arpa/inet.h> |
|||
#include <netinet/in.h> |
|||
|
|||
|
|||
#define SAPI_LSAPI_MAX_HEADER_LENGTH 2048 |
|||
|
|||
static int lsapi_mode = 1; |
|||
static char *php_self = ""; |
|||
static char *script_filename = ""; |
|||
static int source_highlight = 0; |
|||
|
|||
#ifdef ZTS |
|||
zend_compiler_globals *compiler_globals; |
|||
zend_executor_globals *executor_globals; |
|||
php_core_globals *core_globals; |
|||
sapi_globals_struct *sapi_globals; |
|||
void ***tsrm_ls; |
|||
#endif |
|||
|
|||
zend_module_entry litespeed_module_entry; |
|||
|
|||
/* {{{ php_lsapi_startup |
|||
*/ |
|||
static int php_lsapi_startup(sapi_module_struct *sapi_module) |
|||
{ |
|||
if (php_module_startup(sapi_module, NULL, 0)==FAILURE) { |
|||
return FAILURE; |
|||
} |
|||
return SUCCESS; |
|||
} |
|||
/* }}} */ |
|||
|
|||
|
|||
|
|||
/* {{{ sapi_lsapi_ub_write |
|||
*/ |
|||
static int sapi_lsapi_ub_write(const char *str, uint str_length TSRMLS_DC) |
|||
{ |
|||
int ret; |
|||
int remain; |
|||
if ( lsapi_mode ) { |
|||
ret = LSAPI_Write( str, str_length ); |
|||
if ( ret < str_length ) { |
|||
php_handle_aborted_connection(); |
|||
return str_length - ret; |
|||
} |
|||
} else { |
|||
remain = str_length; |
|||
while( remain > 0 ) { |
|||
ret = write( 1, str, remain ); |
|||
if ( ret <= 0 ) { |
|||
php_handle_aborted_connection(); |
|||
return str_length - remain; |
|||
} |
|||
str += ret; |
|||
remain -= ret; |
|||
} |
|||
} |
|||
return str_length; |
|||
} |
|||
/* }}} */ |
|||
|
|||
|
|||
/* {{{ sapi_lsapi_flush |
|||
*/ |
|||
static void sapi_lsapi_flush( void * server_context ) |
|||
{ |
|||
if ( lsapi_mode ) { |
|||
if ( LSAPI_Flush() == -1) { |
|||
php_handle_aborted_connection(); |
|||
} |
|||
} |
|||
} |
|||
/* }}} */ |
|||
|
|||
|
|||
/* {{{ sapi_lsapi_deactivate |
|||
*/ |
|||
static int sapi_lsapi_deactivate(TSRMLS_D) |
|||
{ |
|||
LSAPI_Finish(); |
|||
return SUCCESS; |
|||
} |
|||
/* }}} */ |
|||
|
|||
|
|||
|
|||
|
|||
/* {{{ sapi_lsapi_getenv |
|||
*/ |
|||
static char *sapi_lsapi_getenv( char * name, size_t name_len TSRMLS_DC ) |
|||
{ |
|||
if ( lsapi_mode ) { |
|||
return LSAPI_GetEnv( name ); |
|||
} else { |
|||
return getenv( name ); |
|||
} |
|||
} |
|||
/* }}} */ |
|||
|
|||
|
|||
|
|||
static int add_variable( const char * pKey, int keyLen, const char * pValue, int valLen, |
|||
void * arg ) |
|||
{ |
|||
php_register_variable_safe((char *)pKey, (char *)pValue, valLen, (zval *)arg TSRMLS_CC); |
|||
return 1; |
|||
} |
|||
|
|||
|
|||
|
|||
/* {{{ sapi_lsapi_register_variables |
|||
*/ |
|||
static void sapi_lsapi_register_variables(zval *track_vars_array TSRMLS_DC) |
|||
{ |
|||
|
|||
if ( lsapi_mode ) { |
|||
LSAPI_ForeachHeader( add_variable, track_vars_array ); |
|||
LSAPI_ForeachEnv( add_variable, track_vars_array ); |
|||
php_import_environment_variables(track_vars_array TSRMLS_CC); |
|||
|
|||
php_register_variable("PHP_SELF", (SG(request_info).request_uri ? SG(request_info).request_uri:""), track_vars_array TSRMLS_CC); |
|||
} else { |
|||
php_import_environment_variables(track_vars_array TSRMLS_CC); |
|||
|
|||
php_register_variable("PHP_SELF", php_self, track_vars_array TSRMLS_CC); |
|||
php_register_variable("SCRIPT_NAME", php_self, track_vars_array TSRMLS_CC); |
|||
php_register_variable("SCRIPT_FILENAME", script_filename, track_vars_array TSRMLS_CC); |
|||
php_register_variable("PATH_TRANSLATED", script_filename, track_vars_array TSRMLS_CC); |
|||
php_register_variable("DOCUMENT_ROOT", "", track_vars_array TSRMLS_CC); |
|||
|
|||
} |
|||
} |
|||
/* }}} */ |
|||
|
|||
|
|||
/* {{{ sapi_lsapi_read_post |
|||
*/ |
|||
static int sapi_lsapi_read_post(char *buffer, uint count_bytes TSRMLS_DC) |
|||
{ |
|||
if ( lsapi_mode ) { |
|||
return LSAPI_ReadReqBody( buffer, count_bytes ); |
|||
} else { |
|||
return 0; |
|||
} |
|||
} |
|||
/* }}} */ |
|||
|
|||
|
|||
|
|||
|
|||
/* {{{ sapi_lsapi_read_cookies |
|||
*/ |
|||
static char *sapi_lsapi_read_cookies(TSRMLS_D) |
|||
{ |
|||
if ( lsapi_mode ) { |
|||
return LSAPI_GetHeader( H_COOKIE ); |
|||
} else { |
|||
return NULL; |
|||
} |
|||
} |
|||
/* }}} */ |
|||
|
|||
|
|||
/* {{{ sapi_lsapi_send_headers |
|||
*/ |
|||
static int sapi_lsapi_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC) |
|||
{ |
|||
sapi_header_struct *h; |
|||
zend_llist_position pos; |
|||
if ( lsapi_mode ) { |
|||
LSAPI_SetRespStatus( SG(sapi_headers).http_response_code ); |
|||
|
|||
h = zend_llist_get_first_ex(&sapi_headers->headers, &pos); |
|||
while (h) { |
|||
if ( h->header_len > 0 ) { |
|||
LSAPI_AppendRespHeader(h->header, h->header_len); |
|||
} |
|||
h = zend_llist_get_next_ex(&sapi_headers->headers, &pos); |
|||
} |
|||
if (SG(sapi_headers).send_default_content_type) { |
|||
char *hd; |
|||
int len; |
|||
char headerBuf[SAPI_LSAPI_MAX_HEADER_LENGTH]; |
|||
|
|||
hd = sapi_get_default_content_type(TSRMLS_C); |
|||
len = snprintf( headerBuf, SAPI_LSAPI_MAX_HEADER_LENGTH - 1, |
|||
"Content-type: %s", hd ); |
|||
efree(hd); |
|||
|
|||
LSAPI_AppendRespHeader( headerBuf, len ); |
|||
} |
|||
} |
|||
LSAPI_FinalizeRespHeaders(); |
|||
return SAPI_HEADER_SENT_SUCCESSFULLY; |
|||
|
|||
|
|||
} |
|||
/* }}} */ |
|||
|
|||
|
|||
/* {{{ sapi_lsapi_send_headers |
|||
*/ |
|||
static void sapi_lsapi_log_message(char *message) |
|||
{ |
|||
int len = strlen( message ); |
|||
LSAPI_Write_Stderr( message, len); |
|||
} |
|||
/* }}} */ |
|||
|
|||
|
|||
/* {{{ sapi_module_struct cgi_sapi_module |
|||
*/ |
|||
static sapi_module_struct lsapi_sapi_module = |
|||
{ |
|||
"litespeed", |
|||
"LiteSpeed", |
|||
|
|||
php_lsapi_startup, /* startup */ |
|||
php_module_shutdown_wrapper, /* shutdown */ |
|||
|
|||
NULL, /* activate */ |
|||
sapi_lsapi_deactivate, /* deactivate */ |
|||
|
|||
sapi_lsapi_ub_write, /* unbuffered write */ |
|||
sapi_lsapi_flush, /* flush */ |
|||
NULL, /* get uid */ |
|||
sapi_lsapi_getenv, /* getenv */ |
|||
|
|||
php_error, /* error handler */ |
|||
|
|||
NULL, /* header handler */ |
|||
sapi_lsapi_send_headers, /* send headers handler */ |
|||
NULL, /* send header handler */ |
|||
|
|||
sapi_lsapi_read_post, /* read POST data */ |
|||
sapi_lsapi_read_cookies, /* read Cookies */ |
|||
|
|||
sapi_lsapi_register_variables, /* register server variables */ |
|||
sapi_lsapi_log_message, /* Log message */ |
|||
|
|||
NULL, /* php.ini path override */ |
|||
NULL, /* block interruptions */ |
|||
NULL, /* unblock interruptions */ |
|||
NULL, /* default post reader */ |
|||
NULL, /* treat data */ |
|||
NULL, /* executable location */ |
|||
|
|||
0, /* php.ini ignore */ |
|||
|
|||
STANDARD_SAPI_MODULE_PROPERTIES |
|||
|
|||
}; |
|||
/* }}} */ |
|||
|
|||
static int init_request_info( TSRMLS_D ) |
|||
{ |
|||
char * pContentType = LSAPI_GetHeader( H_CONTENT_TYPE ); |
|||
char * pAuth; |
|||
|
|||
SG(request_info).content_type = pContentType ? pContentType : ""; |
|||
SG(request_info).request_method = LSAPI_GetRequestMethod(); |
|||
SG(request_info).query_string = LSAPI_GetQueryString(); |
|||
SG(request_info).request_uri = LSAPI_GetScriptName(); |
|||
SG(request_info).content_length = LSAPI_GetReqBodyLen(); |
|||
SG(request_info).path_translated = LSAPI_GetScriptFileName(); |
|||
|
|||
/* It is not reset by zend engine, set it to 0. */ |
|||
SG(sapi_headers).http_response_code = 0; |
|||
|
|||
pAuth = LSAPI_GetHeader( H_AUTHORIZATION ); |
|||
php_handle_auth_data(pAuth TSRMLS_CC); |
|||
} |
|||
|
|||
static int lsapi_module_main(int show_source TSRMLS_DC) |
|||
{ |
|||
zend_file_handle file_handle = {0}; |
|||
|
|||
if (php_request_startup(TSRMLS_C) == FAILURE ) { |
|||
return -1; |
|||
} |
|||
if (show_source) { |
|||
zend_syntax_highlighter_ini syntax_highlighter_ini; |
|||
|
|||
php_get_highlight_struct(&syntax_highlighter_ini); |
|||
highlight_file(SG(request_info).path_translated, &syntax_highlighter_ini TSRMLS_CC); |
|||
} else { |
|||
file_handle.type = ZEND_HANDLE_FILENAME; |
|||
file_handle.handle.fd = 0; |
|||
file_handle.filename = SG(request_info).path_translated; |
|||
file_handle.free_filename = 0; |
|||
file_handle.opened_path = NULL; |
|||
|
|||
php_execute_script(&file_handle TSRMLS_CC); |
|||
} |
|||
zend_try { |
|||
php_request_shutdown(NULL); |
|||
} zend_end_try(); |
|||
return 0; |
|||
} |
|||
|
|||
|
|||
static int alter_ini( const char * pKey, int keyLen, const char * pValue, int valLen, |
|||
void * arg ) |
|||
{ |
|||
int type = ZEND_INI_PERDIR; |
|||
if ( '\001' == *pKey ) { |
|||
++pKey; |
|||
if ( *pKey == 4 ) { |
|||
type = ZEND_INI_SYSTEM; |
|||
} |
|||
++pKey; |
|||
--keyLen; |
|||
zend_alter_ini_entry((char *)pKey, keyLen, |
|||
(char *)pValue, valLen, |
|||
type, PHP_INI_STAGE_ACTIVATE); |
|||
} |
|||
return 1; |
|||
} |
|||
|
|||
|
|||
static void override_ini() |
|||
{ |
|||
|
|||
LSAPI_ForeachSpecialEnv( alter_ini, NULL ); |
|||
|
|||
} |
|||
|
|||
static int processReq( TSRMLS_D ) |
|||
{ |
|||
int ret = 0; |
|||
zend_first_try { |
|||
/* avoid server_context==NULL checks */ |
|||
SG(server_context) = (void *) 1; |
|||
|
|||
init_request_info( TSRMLS_C ); |
|||
|
|||
override_ini(); |
|||
|
|||
if ( lsapi_module_main( source_highlight TSRMLS_CC ) == -1 ) { |
|||
ret = -1; |
|||
} |
|||
} zend_end_try(); |
|||
return ret; |
|||
} |
|||
|
|||
static void cli_usage( TSRMLS_D ) |
|||
{ |
|||
static const char * usage = |
|||
"Usage: php\n" |
|||
" php -[b|c|h|i|q|s|v|?] [<file>] [args...]\n" |
|||
" Run in LSAPI mode, only '-b', '-s' and '-c' are effective\n" |
|||
" Run in Command Line Interpreter mode when parameters are specified\n" |
|||
"\n" |
|||
" -b <address:port>|<port> Bind Path for external LSAPI Server mode\n" |
|||
" -c <path>|<file> Look for php.ini file in this directory\n" |
|||
" -h This help\n" |
|||
" -i PHP information\n" |
|||
" -q Quiet-mode. Suppress HTTP Header output.\n" |
|||
" -s Display colour syntax highlighted source.\n" |
|||
" -v Version number\n" |
|||
" -? This help\n" |
|||
"\n" |
|||
" args... Arguments passed to script.\n"; |
|||
php_output_startup(); |
|||
php_output_activate(TSRMLS_C); |
|||
php_printf( usage ); |
|||
#ifdef PHP_OUTPUT_NEWAPI |
|||
php_output_end_all(TSRMLS_C); |
|||
#else |
|||
php_end_ob_buffers(1 TSRMLS_CC); |
|||
#endif |
|||
} |
|||
|
|||
static int parse_opt( int argc, char * argv[], int *climode, |
|||
char **php_ini_path, char ** php_bind ) |
|||
{ |
|||
char ** p = &argv[1]; |
|||
char ** argend= &argv[argc]; |
|||
int c; |
|||
while (( p < argend )&&(**p == '-' )) { |
|||
c = *((*p)+1); |
|||
++p; |
|||
switch( c ) { |
|||
case 'b': |
|||
if ( p >= argend ) { |
|||
fprintf( stderr, "TCP or socket address must be specified following '-b' option.\n"); |
|||
return -1; |
|||
} |
|||
*php_bind = *p++; |
|||
break; |
|||
|
|||
case 'c': |
|||
if ( p >= argend ) { |
|||
fprintf( stderr, "<path> or <file> must be specified following '-c' option.\n"); |
|||
|
|||
return -1; |
|||
} |
|||
*php_ini_path = *p++; |
|||
break; |
|||
case 's': |
|||
source_highlight = 1; |
|||
break; |
|||
case 'h': |
|||
case 'i': |
|||
case 'q': |
|||
case 'v': |
|||
case '?': |
|||
default: |
|||
*climode = 1; |
|||
break; |
|||
} |
|||
} |
|||
if ( p - argv < argc ) { |
|||
*climode = 1; |
|||
} |
|||
return 0; |
|||
} |
|||
|
|||
static int cli_main( int argc, char * argv[] ) |
|||
{ |
|||
|
|||
static const char * ini_defaults[] = { |
|||
"report_zend_debug", "0", |
|||
"display_errors", "1", |
|||
"register_argc_argv", "1", |
|||
"html_errors", "0", |
|||
"implicit_flush", "1", |
|||
"output_buffering", "0", |
|||
"max_execution_time", "0", |
|||
NULL |
|||
}; |
|||
|
|||
const char ** ini; |
|||
char ** p = &argv[1]; |
|||
char ** argend= &argv[argc]; |
|||
int ret = 0; |
|||
int c; |
|||
lsapi_mode = 0; /* enter CLI mode */ |
|||
|
|||
#ifdef PHP_WIN32 |
|||
_fmode = _O_BINARY; /*sets default for file streams to binary */ |
|||
setmode(_fileno(stdin), O_BINARY); /* make the stdio mode be binary */ |
|||
setmode(_fileno(stdout), O_BINARY); /* make the stdio mode be binary */ |
|||
setmode(_fileno(stderr), O_BINARY); /* make the stdio mode be binary */ |
|||
#endif |
|||
|
|||
zend_first_try { |
|||
SG(server_context) = (void *) 1; |
|||
|
|||
zend_uv.html_errors = 0; /* tell the engine we're in non-html mode */ |
|||
CG(in_compilation) = 0; /* not initialized but needed for several options */ |
|||
EG(uninitialized_zval_ptr) = NULL; |
|||
|
|||
for( ini = ini_defaults; *ini; ini+=2 ) { |
|||
zend_alter_ini_entry( (char *)*ini, strlen( *ini )+1, |
|||
(char *)*(ini+1), strlen( *(ini+1) ), |
|||
PHP_INI_SYSTEM, PHP_INI_STAGE_ACTIVATE); |
|||
} |
|||
|
|||
while (( p < argend )&&(**p == '-' )) { |
|||
c = *((*p)+1); |
|||
++p; |
|||
switch( c ) { |
|||
case 'q': |
|||
break; |
|||
case 'i': |
|||
if (php_request_startup(TSRMLS_C) != FAILURE) { |
|||
php_print_info(0xFFFFFFFF TSRMLS_CC); |
|||
#ifdef PHP_OUTPUT_NEWAPI |
|||
php_output_end_all(TSRMLS_C); |
|||
#else |
|||
php_end_ob_buffers(1 TSRMLS_CC); |
|||
#endif |
|||
php_request_shutdown( NULL ); |
|||
} |
|||
ret = 1; |
|||
break; |
|||
case 'v': |
|||
if (php_request_startup(TSRMLS_C) != FAILURE) { |
|||
#if ZEND_DEBUG |
|||
php_printf("PHP %s (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2004 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version()); |
|||
#else |
|||
php_printf("PHP %s (%s) (built: %s %s)\nCopyright (c) 1997-2004 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version()); |
|||
#endif |
|||
#ifdef PHP_OUTPUT_NEWAPI |
|||
php_output_end_all(TSRMLS_C); |
|||
#else |
|||
php_end_ob_buffers(1 TSRMLS_CC); |
|||
#endif |
|||
php_request_shutdown( NULL ); |
|||
} |
|||
ret = 1; |
|||
break; |
|||
case 'c': |
|||
++p; |
|||
/* fall through */ |
|||
case 's': |
|||
break; |
|||
|
|||
case 'h': |
|||
case '?': |
|||
default: |
|||
cli_usage(TSRMLS_C); |
|||
ret = 1; |
|||
break; |
|||
|
|||
} |
|||
} |
|||
if ( !ret ) { |
|||
if ( *p ) { |
|||
zend_file_handle file_handle = {0}; |
|||
|
|||
file_handle.type = ZEND_HANDLE_FP; |
|||
file_handle.handle.fp = VCWD_FOPEN(*p, "rb"); |
|||
|
|||
if ( file_handle.handle.fp ) { |
|||
script_filename = *p; |
|||
php_self = *p; |
|||
|
|||
SG(request_info).path_translated = *p; |
|||
SG(request_info).argc = argc - (p - argv); |
|||
SG(request_info).argv = p; |
|||
|
|||
if (php_request_startup(TSRMLS_C) == FAILURE ) { |
|||
fclose( file_handle.handle.fp ); |
|||
ret = 2; |
|||
} else { |
|||
if (source_highlight) { |
|||
zend_syntax_highlighter_ini syntax_highlighter_ini; |
|||
|
|||
php_get_highlight_struct(&syntax_highlighter_ini); |
|||
highlight_file(SG(request_info).path_translated, &syntax_highlighter_ini TSRMLS_CC); |
|||
} else { |
|||
file_handle.filename = *p; |
|||
file_handle.free_filename = 0; |
|||
file_handle.opened_path = NULL; |
|||
|
|||
php_execute_script(&file_handle TSRMLS_CC); |
|||
} |
|||
|
|||
php_request_shutdown( NULL ); |
|||
} |
|||
} else { |
|||
php_printf("Could not open input file: %s.\n", *p); |
|||
} |
|||
} else { |
|||
cli_usage(TSRMLS_C); |
|||
} |
|||
} |
|||
|
|||
}zend_end_try(); |
|||
|
|||
php_module_shutdown(TSRMLS_C); |
|||
|
|||
#ifdef ZTS |
|||
tsrm_shutdown(); |
|||
#endif |
|||
return ret; |
|||
} |
|||
|
|||
static int s_stop; |
|||
void litespeed_cleanup(int signal) |
|||
{ |
|||
s_stop = signal; |
|||
} |
|||
|
|||
|
|||
void start_children( int children ) |
|||
{ |
|||
struct sigaction act, old_term, old_quit, old_int, old_usr1; |
|||
int running = 0; |
|||
int status; |
|||
pid_t pid; |
|||
|
|||
/* Create a process group */ |
|||
setsid(); |
|||
|
|||
/* Set up handler to kill children upon exit */ |
|||
act.sa_flags = 0; |
|||
act.sa_handler = litespeed_cleanup; |
|||
if( sigaction( SIGTERM, &act, &old_term ) || |
|||
sigaction( SIGINT, &act, &old_int ) || |
|||
sigaction( SIGUSR1, &act, &old_usr1 ) || |
|||
sigaction( SIGQUIT, &act, &old_quit )) { |
|||
perror( "Can't set signals" ); |
|||
exit( 1 ); |
|||
} |
|||
s_stop = 0; |
|||
while( 1 ) { |
|||
while((!s_stop )&&( running < children )) { |
|||
pid = fork(); |
|||
switch( pid ) { |
|||
case 0: /* children process */ |
|||
|
|||
/* don't catch our signals */ |
|||
sigaction( SIGTERM, &old_term, 0 ); |
|||
sigaction( SIGQUIT, &old_quit, 0 ); |
|||
sigaction( SIGINT, &old_int, 0 ); |
|||
sigaction( SIGUSR1, &old_usr1, 0 ); |
|||
return ; |
|||
case -1: |
|||
perror( "php (pre-forking)" ); |
|||
exit( 1 ); |
|||
break; |
|||
default: /* parent process */ |
|||
running++; |
|||
break; |
|||
} |
|||
} |
|||
if ( s_stop ) { |
|||
break; |
|||
} |
|||
pid = wait( &status ); |
|||
running--; |
|||
} |
|||
kill( -getpgrp(), SIGUSR1 ); |
|||
exit( 0 ); |
|||
} |
|||
|
|||
|
|||
|
|||
#include <fcntl.h> |
|||
int main( int argc, char * argv[] ) |
|||
{ |
|||
int ret; |
|||
int bindFd; |
|||
|
|||
char * php_ini_path = NULL; |
|||
char * php_bind = NULL; |
|||
char * p; |
|||
int n; |
|||
int climode = 0; |
|||
|
|||
#ifdef HAVE_SIGNAL_H |
|||
#if defined(SIGPIPE) && defined(SIG_IGN) |
|||
signal(SIGPIPE, SIG_IGN); |
|||
#endif |
|||
#endif |
|||
|
|||
#ifdef ZTS |
|||
tsrm_startup(1, 1, 0, NULL); |
|||
#endif |
|||
|
|||
if (argc > 1 ) { |
|||
if ( parse_opt( argc, argv, &climode, |
|||
&php_ini_path, &php_bind ) == -1 ) { |
|||
return 1; |
|||
} |
|||
} |
|||
if ( climode ) { |
|||
lsapi_sapi_module.phpinfo_as_text = 1; |
|||
} |
|||
sapi_startup(&lsapi_sapi_module); |
|||
|
|||
#ifdef ZTS |
|||
compiler_globals = ts_resource(compiler_globals_id); |
|||
executor_globals = ts_resource(executor_globals_id); |
|||
core_globals = ts_resource(core_globals_id); |
|||
sapi_globals = ts_resource(sapi_globals_id); |
|||
tsrm_ls = ts_resource(0); |
|||
|
|||
SG(request_info).path_translated = NULL; |
|||
#endif |
|||
|
|||
lsapi_sapi_module.executable_location = argv[0]; |
|||
|
|||
if ( php_ini_path ) { |
|||
lsapi_sapi_module.php_ini_path_override = php_ini_path; |
|||
} |
|||
|
|||
if (php_module_startup(&lsapi_sapi_module, &litespeed_module_entry, 1) == FAILURE) { |
|||
#ifdef ZTS |
|||
tsrm_shutdown(); |
|||
#endif |
|||
return FAILURE; |
|||
} |
|||
|
|||
if ( climode ) { |
|||
return cli_main(argc, argv); |
|||
} |
|||
|
|||
|
|||
if ( php_bind ) { |
|||
bindFd = LSAPI_CreateListenSock( php_bind, 10 ); |
|||
if ( bindFd == -1 ) { |
|||
fprintf( stderr, |
|||
"Failed to bind socket [%s]: %s\n", php_bind, strerror( errno ) ); |
|||
exit( 2 ); |
|||
} |
|||
if ( bindFd != 0 ) { |
|||
dup2( bindFd, 0 ); |
|||
close( bindFd ); |
|||
} |
|||
} |
|||
|
|||
LSAPI_Init(); |
|||
|
|||
LSAPI_Init_Env_Parameters( NULL ); |
|||
|
|||
if ( php_bind ) { |
|||
LSAPI_No_Check_ppid(); |
|||
} |
|||
|
|||
while( LSAPI_Prefork_Accept_r( &g_req ) >= 0 ) { |
|||
ret = processReq(TSRMLS_C); |
|||
LSAPI_Finish(); |
|||
if ( ret ) { |
|||
break; |
|||
} |
|||
} |
|||
php_module_shutdown(TSRMLS_C); |
|||
|
|||
#ifdef ZTS |
|||
tsrm_shutdown(); |
|||
#endif |
|||
return ret; |
|||
} |
|||
|
|||
|
|||
/* LiteSpeed PHP module starts here */ |
|||
|
|||
|
|||
|
|||
PHP_FUNCTION(litespeed_request_headers); |
|||
PHP_FUNCTION(litespeed_response_headers); |
|||
|
|||
PHP_MINFO_FUNCTION(litespeed); |
|||
|
|||
zend_function_entry litespeed_functions[] = { |
|||
PHP_FE(litespeed_request_headers, NULL) |
|||
PHP_FE(litespeed_response_headers, NULL) |
|||
PHP_FALIAS(getallheaders, litespeed_request_headers, NULL) |
|||
PHP_FALIAS(apache_request_headers, litespeed_request_headers, NULL) |
|||
PHP_FALIAS(apache_response_headers, litespeed_response_headers, NULL) |
|||
{NULL, NULL, NULL} |
|||
}; |
|||
|
|||
static PHP_MINIT_FUNCTION(litespeed) |
|||
{ |
|||
//REGISTER_INI_ENTRIES(); |
|||
return SUCCESS; |
|||
} |
|||
|
|||
|
|||
static PHP_MSHUTDOWN_FUNCTION(litespeed) |
|||
{ |
|||
//UNREGISTER_INI_ENTRIES(); |
|||
return SUCCESS; |
|||
} |
|||
|
|||
zend_module_entry litespeed_module_entry = { |
|||
STANDARD_MODULE_HEADER, |
|||
"litespeed", |
|||
litespeed_functions, |
|||
PHP_MINIT(litespeed), |
|||
PHP_MSHUTDOWN(litespeed), |
|||
NULL, |
|||
NULL, |
|||
NULL, |
|||
NO_VERSION_YET, |
|||
STANDARD_MODULE_PROPERTIES |
|||
}; |
|||
|
|||
static int add_associate_array( const char * pKey, int keyLen, const char * pValue, int valLen, |
|||
void * arg ) |
|||
{ |
|||
add_assoc_string_ex( (zval *)arg, (char *)pKey, keyLen+1, (char *)pValue, 1 ); |
|||
return 1; |
|||
} |
|||
|
|||
|
|||
/* {{{ proto array litespeed_request_headers(void) |
|||
Fetch all HTTP request headers */ |
|||
PHP_FUNCTION(litespeed_request_headers) |
|||
{ |
|||
//TODO: |
|||
if (ZEND_NUM_ARGS() > 0) { |
|||
WRONG_PARAM_COUNT; |
|||
} |
|||
array_init(return_value); |
|||
|
|||
LSAPI_ForeachOrgHeader( add_associate_array, return_value ); |
|||
|
|||
} |
|||
/* }}} */ |
|||
|
|||
|
|||
|
|||
/* {{{ proto array litespeed_response_headers(void) |
|||
Fetch all HTTP response headers */ |
|||
PHP_FUNCTION(litespeed_response_headers) |
|||
{ |
|||
sapi_header_struct *h; |
|||
zend_llist_position pos; |
|||
char * p; |
|||
int len; |
|||
char headerBuf[SAPI_LSAPI_MAX_HEADER_LENGTH]; |
|||
|
|||
if (ZEND_NUM_ARGS() > 0) { |
|||
WRONG_PARAM_COUNT; |
|||
} |
|||
|
|||
if (!&SG(sapi_headers).headers) { |
|||
RETURN_FALSE; |
|||
} |
|||
array_init(return_value); |
|||
|
|||
h = zend_llist_get_first_ex(&SG(sapi_headers).headers, &pos); |
|||
while (h) { |
|||
if ( h->header_len > 0 ) { |
|||
p = strchr( h->header, ':' ); |
|||
len = p - h->header; |
|||
if (( p )&&( len > 0 )) { |
|||
memmove( headerBuf, h->header, len ); |
|||
while( len > 0 && (isspace( headerBuf[len-1])) ) { |
|||
--len; |
|||
} |
|||
headerBuf[len] = 0; |
|||
if ( len ) { |
|||
while( isspace(*++p)); |
|||
add_assoc_string_ex(return_value, headerBuf, len+1, p, 1 ); |
|||
} |
|||
} |
|||
} |
|||
h = zend_llist_get_next_ex(&SG(sapi_headers).headers, &pos); |
|||
} |
|||
} |
|||
|
|||
/* }}} */ |
|||
|
|||
|
|||
/* |
|||
* Local variables: |
|||
* tab-width: 4 |
|||
* c-basic-offset: 4 |
|||
* End: |
|||
* vim600: sw=4 ts=4 fdm=marker |
|||
* vim<600: sw=4 ts=4 |
|||
*/ |
|||
|
|||
|
|||
@ -0,0 +1,196 @@ |
|||
|
|||
/* |
|||
+----------------------------------------------------------------------+ |
|||
| PHP Version 5 | |
|||
+----------------------------------------------------------------------+ |
|||
| 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 at 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. | |
|||
+----------------------------------------------------------------------+ |
|||
| Author: George Wang <gwang@litespeedtech.com> | |
|||
+----------------------------------------------------------------------+ |
|||
*/ |
|||
|
|||
|
|||
/* |
|||
Copyright (c) 2007, Lite Speed Technologies Inc. |
|||
All rights reserved. |
|||
|
|||
Redistribution and use in source and binary forms, with or without |
|||
modification, are permitted provided that the following conditions are |
|||
met: |
|||
|
|||
* Redistributions of source code must retain the above copyright |
|||
notice, this list of conditions and the following disclaimer. |
|||
* Redistributions in binary form must reproduce the above |
|||
copyright notice, this list of conditions and the following |
|||
disclaimer in the documentation and/or other materials provided |
|||
with the distribution. |
|||
* Neither the name of the Lite Speed Technologies Inc nor the |
|||
names of its contributors may be used to endorse or promote |
|||
products derived from this software without specific prior |
|||
written permission. |
|||
|
|||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
|||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
|||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
|||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
|||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
|||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
|||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
|||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
|||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|||
*/ |
|||
|
|||
|
|||
#ifndef _LSAPIDEF_H_ |
|||
#define _LSAPIDEF_H_ |
|||
|
|||
#include <inttypes.h> |
|||
|
|||
#if defined (c_plusplus) || defined (__cplusplus) |
|||
extern "C" { |
|||
#endif |
|||
|
|||
enum |
|||
{ |
|||
H_ACCEPT = 0, |
|||
H_ACC_CHARSET, |
|||
H_ACC_ENCODING, |
|||
H_ACC_LANG, |
|||
H_AUTHORIZATION, |
|||
H_CONNECTION, |
|||
H_CONTENT_TYPE, |
|||
H_CONTENT_LENGTH, |
|||
H_COOKIE, |
|||
H_COOKIE2, |
|||
H_HOST, |
|||
H_PRAGMA, |
|||
H_REFERER, |
|||
H_USERAGENT, |
|||
H_CACHE_CTRL, |
|||
H_IF_MODIFIED_SINCE, |
|||
H_IF_MATCH, |
|||
H_IF_NO_MATCH, |
|||
H_IF_RANGE, |
|||
H_IF_UNMOD_SINCE, |
|||
H_KEEP_ALIVE, |
|||
H_RANGE, |
|||
H_X_FORWARDED_FOR, |
|||
H_VIA, |
|||
H_TRANSFER_ENCODING |
|||
|
|||
}; |
|||
#define LSAPI_SOCK_FILENO 0 |
|||
|
|||
#define LSAPI_VERSION_B0 'L' |
|||
#define LSAPI_VERSION_B1 'S' |
|||
|
|||
/* Values for m_flag in lsapi_packet_header */ |
|||
#define LSAPI_ENDIAN_LITTLE 0 |
|||
#define LSAPI_ENDIAN_BIG 1 |
|||
#define LSAPI_ENDIAN_BIT 1 |
|||
|
|||
#if defined(__i386__)||defined( __x86_64 )||defined( __x86_64__ ) |
|||
#define LSAPI_ENDIAN LSAPI_ENDIAN_LITTLE |
|||
#else |
|||
#define LSAPI_ENDIAN LSAPI_ENDIAN_BIG |
|||
#endif |
|||
|
|||
/* Values for m_type in lsapi_packet_header */ |
|||
#define LSAPI_BEGIN_REQUEST 1 |
|||
#define LSAPI_ABORT_REQUEST 2 |
|||
#define LSAPI_RESP_HEADER 3 |
|||
#define LSAPI_RESP_STREAM 4 |
|||
#define LSAPI_RESP_END 5 |
|||
#define LSAPI_STDERR_STREAM 6 |
|||
#define LSAPI_REQ_RECEIVED 7 |
|||
|
|||
|
|||
#define LSAPI_MAX_HEADER_LEN 65535 |
|||
#define LSAPI_MAX_DATA_PACKET_LEN 16384 |
|||
|
|||
#define LSAPI_RESP_HTTP_HEADER_MAX 4096 |
|||
#define LSAPI_PACKET_HEADER_LEN 8 |
|||
|
|||
|
|||
struct lsapi_packet_header |
|||
{ |
|||
char m_versionB0; /* LSAPI protocol version */ |
|||
char m_versionB1; |
|||
char m_type; |
|||
char m_flag; |
|||
union |
|||
{ |
|||
int32_t m_iLen; /* include this header */ |
|||
char m_bytes[4]; |
|||
}m_packetLen; |
|||
}; |
|||
|
|||
/* |
|||
LSAPI request header packet |
|||
|
|||
1. struct lsapi_req_header |
|||
2. struct lsapi_http_header_index |
|||
3. lsapi_header_offset * unknownHeaders |
|||
4. org http request header |
|||
5. request body if available |
|||
*/ |
|||
|
|||
struct lsapi_req_header |
|||
{ |
|||
struct lsapi_packet_header m_pktHeader; |
|||
|
|||
int32_t m_httpHeaderLen; |
|||
int32_t m_reqBodyLen; |
|||
int32_t m_scriptFileOff; /* path to the script file. */ |
|||
int32_t m_scriptNameOff; /* decrypted URI, without pathinfo, */ |
|||
int32_t m_queryStringOff; /* Query string inside env */ |
|||
int32_t m_requestMethodOff; |
|||
int32_t m_cntUnknownHeaders; |
|||
int32_t m_cntEnv; |
|||
int32_t m_cntSpecialEnv; |
|||
} ; |
|||
|
|||
|
|||
struct lsapi_http_header_index |
|||
{ |
|||
int16_t m_headerLen[H_TRANSFER_ENCODING+1]; |
|||
int32_t m_headerOff[H_TRANSFER_ENCODING+1]; |
|||
} ; |
|||
|
|||
struct lsapi_header_offset |
|||
{ |
|||
int32_t nameOff; |
|||
int32_t nameLen; |
|||
int32_t valueOff; |
|||
int32_t valueLen; |
|||
} ; |
|||
|
|||
struct lsapi_resp_info |
|||
{ |
|||
int32_t m_cntHeaders; |
|||
int32_t m_status; |
|||
}; |
|||
|
|||
struct lsapi_resp_header |
|||
{ |
|||
struct lsapi_packet_header m_pktHeader; |
|||
struct lsapi_resp_info m_respInfo; |
|||
}; |
|||
|
|||
#if defined (c_plusplus) || defined (__cplusplus) |
|||
} |
|||
#endif |
|||
|
|||
|
|||
#endif |
|||
|
|||
2177
sapi/litespeed/lsapilib.c
File diff suppressed because it is too large
View File
File diff suppressed because it is too large
View File
@ -0,0 +1,358 @@ |
|||
|
|||
/* |
|||
+----------------------------------------------------------------------+ |
|||
| PHP Version 5 | |
|||
+----------------------------------------------------------------------+ |
|||
| 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 at 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. | |
|||
+----------------------------------------------------------------------+ |
|||
| Author: George Wang <gwang@litespeedtech.com> | |
|||
+----------------------------------------------------------------------+ |
|||
*/ |
|||
|
|||
/* |
|||
Copyright (c) 2007, Lite Speed Technologies Inc. |
|||
All rights reserved. |
|||
|
|||
Redistribution and use in source and binary forms, with or without |
|||
modification, are permitted provided that the following conditions are |
|||
met: |
|||
|
|||
* Redistributions of source code must retain the above copyright |
|||
notice, this list of conditions and the following disclaimer. |
|||
* Redistributions in binary form must reproduce the above |
|||
copyright notice, this list of conditions and the following |
|||
disclaimer in the documentation and/or other materials provided |
|||
with the distribution. |
|||
* Neither the name of the Lite Speed Technologies Inc nor the |
|||
names of its contributors may be used to endorse or promote |
|||
products derived from this software without specific prior |
|||
written permission. |
|||
|
|||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS |
|||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT |
|||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
|||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT |
|||
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
|||
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
|||
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
|||
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
|||
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
|||
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
|||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|||
*/ |
|||
|
|||
|
|||
|
|||
#ifndef _LSAPILIB_H_ |
|||
#define _LSAPILIB_H_ |
|||
|
|||
#if defined (c_plusplus) || defined (__cplusplus) |
|||
extern "C" { |
|||
#endif |
|||
|
|||
#include <stddef.h> |
|||
#include <lsapidef.h> |
|||
|
|||
#include <sys/time.h> |
|||
#include <sys/types.h> |
|||
|
|||
struct LSAPI_key_value_pair |
|||
{ |
|||
char * pKey; |
|||
char * pValue; |
|||
int keyLen; |
|||
int valLen; |
|||
}; |
|||
|
|||
|
|||
#define LSAPI_MAX_RESP_HEADERS 100 |
|||
|
|||
typedef struct lsapi_request |
|||
{ |
|||
int m_fdListen; |
|||
int m_fd; |
|||
|
|||
long m_lLastActive; |
|||
long m_lReqBegin; |
|||
|
|||
char * m_pReqBuf; |
|||
int m_reqBufSize; |
|||
|
|||
char * m_pRespBuf; |
|||
char * m_pRespBufEnd; |
|||
char * m_pRespBufPos; |
|||
|
|||
char * m_pRespHeaderBuf; |
|||
char * m_pRespHeaderBufEnd; |
|||
char * m_pRespHeaderBufPos; |
|||
|
|||
|
|||
struct iovec * m_pIovec; |
|||
struct iovec * m_pIovecEnd; |
|||
struct iovec * m_pIovecCur; |
|||
struct iovec * m_pIovecToWrite; |
|||
|
|||
struct lsapi_packet_header * m_respPktHeaderEnd; |
|||
|
|||
struct lsapi_req_header * m_pHeader; |
|||
struct LSAPI_key_value_pair * m_pEnvList; |
|||
struct LSAPI_key_value_pair * m_pSpecialEnvList; |
|||
int m_envListSize; |
|||
int m_specialEnvListSize; |
|||
|
|||
struct lsapi_http_header_index * m_pHeaderIndex; |
|||
struct lsapi_header_offset * m_pUnknownHeader; |
|||
|
|||
char * m_pScriptFile; |
|||
char * m_pScriptName; |
|||
char * m_pQueryString; |
|||
char * m_pHttpHeader; |
|||
char * m_pRequestMethod; |
|||
int m_totalLen; |
|||
int m_reqState; |
|||
int m_reqBodyRead; |
|||
int m_bufProcessed; |
|||
int m_bufRead; |
|||
|
|||
struct lsapi_packet_header m_respPktHeader[5]; |
|||
|
|||
struct lsapi_resp_header m_respHeader; |
|||
short m_respHeaderLen[LSAPI_MAX_RESP_HEADERS]; |
|||
|
|||
}LSAPI_Request; |
|||
|
|||
extern LSAPI_Request g_req; |
|||
|
|||
|
|||
/* return: >0 continue, ==0 stop, -1 failed */ |
|||
typedef int (*LSAPI_CB_EnvHandler )( const char * pKey, int keyLen, |
|||
const char * pValue, int valLen, void * arg ); |
|||
|
|||
|
|||
int LSAPI_Init(void); |
|||
|
|||
void LSAPI_Stop(void); |
|||
|
|||
int LSAPI_Is_Listen_r( LSAPI_Request * pReq); |
|||
|
|||
int LSAPI_InitRequest( LSAPI_Request * pReq, int fd ); |
|||
|
|||
int LSAPI_Accept_r( LSAPI_Request * pReq ); |
|||
|
|||
void LSAPI_Reset_r( LSAPI_Request * pReq ); |
|||
|
|||
int LSAPI_Finish_r( LSAPI_Request * pReq ); |
|||
|
|||
int LSAPI_Release_r( LSAPI_Request * pReq ); |
|||
|
|||
char * LSAPI_GetHeader_r( LSAPI_Request * pReq, int headerIndex ); |
|||
|
|||
int LSAPI_ForeachHeader_r( LSAPI_Request * pReq, |
|||
LSAPI_CB_EnvHandler fn, void * arg ); |
|||
|
|||
int LSAPI_ForeachOrgHeader_r( LSAPI_Request * pReq, |
|||
LSAPI_CB_EnvHandler fn, void * arg ); |
|||
|
|||
int LSAPI_ForeachEnv_r( LSAPI_Request * pReq, |
|||
LSAPI_CB_EnvHandler fn, void * arg ); |
|||
|
|||
int LSAPI_ForeachSpecialEnv_r( LSAPI_Request * pReq, |
|||
LSAPI_CB_EnvHandler fn, void * arg ); |
|||
|
|||
char * LSAPI_GetEnv_r( LSAPI_Request * pReq, const char * name ); |
|||
|
|||
|
|||
int LSAPI_ReadReqBody_r( LSAPI_Request * pReq, char * pBuf, int len ); |
|||
|
|||
int LSAPI_ReqBodyGetChar_r( LSAPI_Request * pReq ); |
|||
|
|||
int LSAPI_ReqBodyGetLine_r( LSAPI_Request * pReq, char * pBuf, int bufLen, int *getLF ); |
|||
|
|||
|
|||
int LSAPI_FinalizeRespHeaders_r( LSAPI_Request * pReq ); |
|||
|
|||
int LSAPI_Write_r( LSAPI_Request * pReq, const char * pBuf, int len ); |
|||
|
|||
int LSAPI_Write_Stderr_r( LSAPI_Request * pReq, const char * pBuf, int len ); |
|||
|
|||
int LSAPI_Flush_r( LSAPI_Request * pReq ); |
|||
|
|||
int LSAPI_AppendRespHeader_r( LSAPI_Request * pHeader, char * pBuf, int len ); |
|||
|
|||
static inline int LSAPI_SetRespStatus_r( LSAPI_Request * pReq, int code ) |
|||
{ |
|||
if ( !pReq ) |
|||
return -1; |
|||
pReq->m_respHeader.m_respInfo.m_status = code; |
|||
return 0; |
|||
} |
|||
|
|||
static inline char * LSAPI_GetQueryString_r( LSAPI_Request * pReq ) |
|||
{ |
|||
if ( pReq ) |
|||
return pReq->m_pQueryString; |
|||
return NULL; |
|||
} |
|||
|
|||
|
|||
static inline char * LSAPI_GetScriptFileName_r( LSAPI_Request * pReq ) |
|||
{ |
|||
if ( pReq ) |
|||
return pReq->m_pScriptFile; |
|||
return NULL; |
|||
} |
|||
|
|||
|
|||
static inline char * LSAPI_GetScriptName_r( LSAPI_Request * pReq ) |
|||
{ |
|||
if ( pReq ) |
|||
return pReq->m_pScriptName; |
|||
return NULL; |
|||
} |
|||
|
|||
|
|||
static inline char * LSAPI_GetRequestMethod_r( LSAPI_Request * pReq) |
|||
{ |
|||
if ( pReq ) |
|||
return pReq->m_pRequestMethod; |
|||
return NULL; |
|||
} |
|||
|
|||
|
|||
|
|||
static inline int LSAPI_GetReqBodyLen_r( LSAPI_Request * pReq ) |
|||
{ |
|||
if ( pReq ) |
|||
return pReq->m_pHeader->m_reqBodyLen; |
|||
return -1; |
|||
} |
|||
|
|||
static inline int LSAPI_GetReqBodyRemain_r( LSAPI_Request * pReq ) |
|||
{ |
|||
if ( pReq ) |
|||
return pReq->m_pHeader->m_reqBodyLen - pReq->m_reqBodyRead; |
|||
return -1; |
|||
} |
|||
|
|||
|
|||
int LSAPI_Is_Listen(void); |
|||
|
|||
static inline int LSAPI_Accept( void ) |
|||
{ return LSAPI_Accept_r( &g_req ); } |
|||
|
|||
static inline int LSAPI_Finish(void) |
|||
{ return LSAPI_Finish_r( &g_req ); } |
|||
|
|||
static inline char * LSAPI_GetHeader( int headerIndex ) |
|||
{ return LSAPI_GetHeader_r( &g_req, headerIndex ); } |
|||
|
|||
static inline int LSAPI_ForeachHeader( LSAPI_CB_EnvHandler fn, void * arg ) |
|||
{ return LSAPI_ForeachHeader_r( &g_req, fn, arg ); } |
|||
|
|||
static inline int LSAPI_ForeachOrgHeader( |
|||
LSAPI_CB_EnvHandler fn, void * arg ) |
|||
{ return LSAPI_ForeachOrgHeader_r( &g_req, fn, arg ); } |
|||
|
|||
static inline int LSAPI_ForeachEnv( LSAPI_CB_EnvHandler fn, void * arg ) |
|||
{ return LSAPI_ForeachEnv_r( &g_req, fn, arg ); } |
|||
|
|||
static inline int LSAPI_ForeachSpecialEnv( LSAPI_CB_EnvHandler fn, void * arg ) |
|||
{ return LSAPI_ForeachSpecialEnv_r( &g_req, fn, arg ); } |
|||
|
|||
static inline char * LSAPI_GetEnv( const char * name ) |
|||
{ return LSAPI_GetEnv_r( &g_req, name ); } |
|||
|
|||
static inline char * LSAPI_GetQueryString() |
|||
{ return LSAPI_GetQueryString_r( &g_req ); } |
|||
|
|||
static inline char * LSAPI_GetScriptFileName() |
|||
{ return LSAPI_GetScriptFileName_r( &g_req ); } |
|||
|
|||
static inline char * LSAPI_GetScriptName() |
|||
{ return LSAPI_GetScriptName_r( &g_req ); } |
|||
|
|||
static inline char * LSAPI_GetRequestMethod() |
|||
{ return LSAPI_GetRequestMethod_r( &g_req ); } |
|||
|
|||
static inline int LSAPI_GetReqBodyLen() |
|||
{ return LSAPI_GetReqBodyLen_r( &g_req ); } |
|||
|
|||
static inline int LSAPI_GetReqBodyRemain() |
|||
{ return LSAPI_GetReqBodyRemain_r( &g_req ); } |
|||
|
|||
static inline int LSAPI_ReadReqBody( char * pBuf, int len ) |
|||
{ return LSAPI_ReadReqBody_r( &g_req, pBuf, len ); } |
|||
|
|||
static inline int LSAPI_ReqBodyGetChar() |
|||
{ return LSAPI_ReqBodyGetChar_r( &g_req ); } |
|||
|
|||
static inline int LSAPI_ReqBodyGetLine( char * pBuf, int len, int *getLF ) |
|||
{ return LSAPI_ReqBodyGetLine_r( &g_req, pBuf, len, getLF ); } |
|||
|
|||
|
|||
|
|||
static inline int LSAPI_FinalizeRespHeaders(void) |
|||
{ return LSAPI_FinalizeRespHeaders_r( &g_req ); } |
|||
|
|||
static inline int LSAPI_Write( const char * pBuf, int len ) |
|||
{ return LSAPI_Write_r( &g_req, pBuf, len ); } |
|||
|
|||
static inline int LSAPI_Write_Stderr( const char * pBuf, int len ) |
|||
{ return LSAPI_Write_Stderr_r( &g_req, pBuf, len ); } |
|||
|
|||
static inline int LSAPI_Flush() |
|||
{ return LSAPI_Flush_r( &g_req ); } |
|||
|
|||
static inline int LSAPI_AppendRespHeader( char * pBuf, int len ) |
|||
{ return LSAPI_AppendRespHeader_r( &g_req, pBuf, len ); } |
|||
|
|||
static inline int LSAPI_SetRespStatus( int code ) |
|||
{ return LSAPI_SetRespStatus_r( &g_req, code ); } |
|||
|
|||
int LSAPI_IsRunning(void); |
|||
|
|||
int LSAPI_CreateListenSock( const char * pBind, int backlog ); |
|||
|
|||
typedef int (*fn_select_t)( int, fd_set *, fd_set *, fd_set *, struct timeval * ); |
|||
|
|||
int LSAPI_Init_Prefork_Server( int max_children, fn_select_t fp, int avoidFork ); |
|||
|
|||
void LSAPI_Set_Server_fd( int fd ); |
|||
|
|||
int LSAPI_Prefork_Accept_r( LSAPI_Request * pReq ); |
|||
|
|||
void LSAPI_Set_Max_Reqs( int reqs ); |
|||
|
|||
void LSAPI_Set_Max_Idle( int secs ); |
|||
|
|||
void LSAPI_Set_Max_Children( int maxChildren ); |
|||
|
|||
void LSAPI_Set_Max_Idle_Children( int maxIdleChld ); |
|||
|
|||
void LSAPI_Set_Server_Max_Idle_Secs( int serverMaxIdle ); |
|||
|
|||
void LSAPI_Set_Max_Process_Time( int secs ); |
|||
|
|||
void LSAPI_Init_Env_Parameters( fn_select_t fp ); |
|||
|
|||
#if defined (c_plusplus) || defined (__cplusplus) |
|||
} |
|||
#endif |
|||
|
|||
|
|||
#endif |
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
|
|||
Write
Preview
Loading…
Cancel
Save
Reference in new issue