added litespeed SAPI

This commit is contained in:
George Wang 2008-08-05 22:37:32 +00:00
parent 457f00b201
commit 52604d2832
8 changed files with 3905 additions and 0 deletions

2
sapi/litespeed/CREDITS Normal file
View File

@ -0,0 +1,2 @@
litespeed
George Wang

View File

@ -0,0 +1,3 @@
$(SAPI_LITESPEED_PATH): $(PHP_GLOBAL_OBJS) $(PHP_SAPI_OBJS)
$(BUILD_LITESPEED)

225
sapi/litespeed/README Normal file
View File

@ -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.

36
sapi/litespeed/config.m4 Normal file
View File

@ -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)

908
sapi/litespeed/lsapi_main.c Normal file
View File

@ -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
*/

196
sapi/litespeed/lsapidef.h Normal file
View File

@ -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 Normal file

File diff suppressed because it is too large Load Diff

358
sapi/litespeed/lsapilib.h Normal file
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