summaryrefslogtreecommitdiff
path: root/sapi/cgi
diff options
context:
space:
mode:
authorSean Finney <seanius@debian.org>2010-02-07 22:19:53 +0100
committerSean Finney <seanius@debian.org>2010-02-07 22:27:07 +0100
commitc852c28a88fccf6e34a2cb091fdfa72bce2b59c7 (patch)
tree91f01b0d06916c78262404096bfd466b8e95e5b5 /sapi/cgi
parent176cbd0bc99e20bb21f92f0b72df728eafc1e2ce (diff)
parent0fab6db7cac8d2be99579dd049f812a8ff98e74f (diff)
downloadphp-c852c28a88fccf6e34a2cb091fdfa72bce2b59c7.tar.gz
Merge branch 'upstream-experimental' into upstream-sid
Diffstat (limited to 'sapi/cgi')
-rwxr-xr-xsapi/cgi/CHANGES34
-rw-r--r--sapi/cgi/cgi_main.c1331
-rw-r--r--sapi/cgi/config.w3222
-rw-r--r--sapi/cgi/config9.m490
-rw-r--r--sapi/cgi/fastcgi.c162
-rw-r--r--sapi/cgi/fastcgi.h9
-rw-r--r--sapi/cgi/getopt.c164
-rw-r--r--sapi/cgi/php_getopt.h39
-rw-r--r--sapi/cgi/tests/002.phpt18
-rw-r--r--sapi/cgi/tests/003.phpt6
-rw-r--r--sapi/cgi/tests/007.phpt4
-rw-r--r--sapi/cgi/tests/008.phpt4
-rw-r--r--sapi/cgi/tests/009.phpt2
-rw-r--r--sapi/cgi/tests/011.phpt165
14 files changed, 1042 insertions, 1008 deletions
diff --git a/sapi/cgi/CHANGES b/sapi/cgi/CHANGES
new file mode 100755
index 000000000..de029474e
--- /dev/null
+++ b/sapi/cgi/CHANGES
@@ -0,0 +1,34 @@
+In PHP5.3 all additional configure options (except --enable-cgi) are removed:
+
+ --enable-fastcgi CGI: If this is enabled, the cgi module will
+ be built with support for fastcgi also
+
+ Now fastcgi is always enabled
+
+ --disable-path-info-check CGI: If this is disabled, paths such as
+ /info.php/test?a=b will fail to work
+
+ Now it is enabled by default, but can be disabled
+ with ini directive "cgi.fix_pathinfo=0"
+
+ --enable-force-cgi-redirect
+ CGI: Enable the security check for internal server
+ redirects. You should use this if you are
+ running the CGI version with Apache
+
+ Now it is enabled by default, but can be disabled
+ with ini directive "cgi.force_redirect=0"
+
+ --enable-discard-path CGI: If this is enabled, the PHP CGI binary
+ can safely be placed outside of the
+ web tree and people will not be able
+ to circumvent .htaccess security
+
+ This option had effect only with
+ --disable-path-info-check or "cgi.fix_pathinfo=0".
+ Seems it needs only for CGI configuration that
+ require each script start from "#! /usr/bin/php".
+
+ Now it is disabled by default, but can be enabled
+ with ini directive "cgi.discard_path=1".
+
diff --git a/sapi/cgi/cgi_main.c b/sapi/cgi/cgi_main.c
index e7481a95e..c01dce1dd 100644
--- a/sapi/cgi/cgi_main.c
+++ b/sapi/cgi/cgi_main.c
@@ -21,7 +21,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: cgi_main.c 291497 2009-11-30 14:43:22Z dmitry $ */
+/* $Id: cgi_main.c 289795 2009-10-20 12:57:44Z tony2001 $ */
#include "php.h"
#include "php_globals.h"
@@ -32,29 +32,37 @@
#include <stdio.h>
#include "php.h"
+
#ifdef PHP_WIN32
-#include "win32/time.h"
-#include "win32/signal.h"
-#include <process.h>
+# include "win32/time.h"
+# include "win32/signal.h"
+# include <process.h>
#endif
+
#if HAVE_SYS_TIME_H
-#include <sys/time.h>
+# include <sys/time.h>
#endif
+
#if HAVE_UNISTD_H
-#include <unistd.h>
+# include <unistd.h>
#endif
+
#if HAVE_SIGNAL_H
-#include <signal.h>
+# include <signal.h>
#endif
+
#if HAVE_SETLOCALE
-#include <locale.h>
+# include <locale.h>
#endif
+
#if HAVE_SYS_TYPES_H
-#include <sys/types.h>
+# include <sys/types.h>
#endif
+
#if HAVE_SYS_WAIT_H
-#include <sys/wait.h>
+# include <sys/wait.h>
#endif
+
#include "zend.h"
#include "zend_extensions.h"
#include "php_ini.h"
@@ -62,14 +70,15 @@
#include "php_main.h"
#include "fopen_wrappers.h"
#include "ext/standard/php_standard.h"
+
#ifdef PHP_WIN32
-#include <io.h>
-#include <fcntl.h>
-#include "win32/php_registry.h"
+# include <io.h>
+# include <fcntl.h>
+# include "win32/php_registry.h"
#endif
#ifdef __riscos__
-#include <unixlib/local.h>
+# include <unixlib/local.h>
int __riscosify_control = __RISCOSIFY_STRICT_UNIX_SPECS;
#endif
@@ -80,12 +89,10 @@ int __riscosify_control = __RISCOSIFY_STRICT_UNIX_SPECS;
#include "php_getopt.h"
-#if PHP_FASTCGI
#include "fastcgi.h"
#ifndef PHP_WIN32
-/* XXX this will need to change later when threaded fastcgi is
- implemented. shane */
+/* XXX this will need to change later when threaded fastcgi is implemented. shane */
struct sigaction act, old_term, old_quit, old_int;
#endif
@@ -115,8 +122,6 @@ static int parent_waiting = 0;
static pid_t pgroup;
#endif
-#endif
-
#define PHP_MODE_STANDARD 1
#define PHP_MODE_HIGHLIGHT 2
#define PHP_MODE_INDENT 3
@@ -147,9 +152,7 @@ static const opt_struct OPTIONS[] = {
{'?', 0, "usage"},/* help alias (both '?' and 'usage') */
{'v', 0, "version"},
{'z', 1, "zend-extension"},
-#if PHP_FASTCGI
{'T', 1, "timing"},
-#endif
{'-', 0, NULL} /* end of args */
};
@@ -157,21 +160,38 @@ typedef struct _php_cgi_globals_struct {
zend_bool rfc2616_headers;
zend_bool nph;
zend_bool check_shebang_line;
-#if ENABLE_PATHINFO_CHECK
zend_bool fix_pathinfo;
-#endif
-#if FORCE_CGI_REDIRECT
zend_bool force_redirect;
- char *redirect_status_env;
-#endif
-#if PHP_FASTCGI
+ zend_bool discard_path;
zend_bool fcgi_logging;
-# ifdef PHP_WIN32
+ char *redirect_status_env;
+#ifdef PHP_WIN32
zend_bool impersonate;
-# endif
#endif
+ HashTable user_config_cache;
} php_cgi_globals_struct;
+/* {{{ user_config_cache
+ *
+ * Key for each cache entry is dirname(PATH_TRANSLATED).
+ *
+ * NOTE: Each cache entry config_hash contains the combination from all user ini files found in
+ * the path starting from doc_root throught to dirname(PATH_TRANSLATED). There is no point
+ * storing per-file entries as it would not be possible to detect added / deleted entries
+ * between separate files.
+ */
+typedef struct _user_config_cache_entry {
+ time_t expires;
+ HashTable *user_config;
+} user_config_cache_entry;
+
+static void user_config_cache_entry_dtor(user_config_cache_entry *entry)
+{
+ zend_hash_destroy(entry->user_config);
+ free(entry->user_config);
+}
+/* }}} */
+
#ifdef ZTS
static int php_cgi_globals_id;
#define CGIG(v) TSRMG(php_cgi_globals_id, php_cgi_globals_struct *, v)
@@ -204,8 +224,8 @@ static int module_name_cmp(const void *a, const void *b TSRMLS_DC)
Bucket *f = *((Bucket **) a);
Bucket *s = *((Bucket **) b);
- return strcasecmp(((zend_module_entry *)f->pData)->name,
- ((zend_module_entry *)s->pData)->name);
+ return strcasecmp( ((zend_module_entry *)f->pData)->name,
+ ((zend_module_entry *)s->pData)->name);
}
static void print_modules(TSRMLS_D)
@@ -226,11 +246,10 @@ static int print_extension_info(zend_extension *ext, void *arg TSRMLS_DC)
return 0;
}
-static int extension_name_cmp(const zend_llist_element **f,
- const zend_llist_element **s TSRMLS_DC)
+static int extension_name_cmp(const zend_llist_element **f, const zend_llist_element **s TSRMLS_DC)
{
- return strcmp(((zend_extension *)(*f)->data)->name,
- ((zend_extension *)(*s)->data)->name);
+ return strcmp( ((zend_extension *)(*f)->data)->name,
+ ((zend_extension *)(*s)->data)->name);
}
static void print_extensions(TSRMLS_D)
@@ -256,7 +275,6 @@ static inline size_t sapi_cgibin_single_write(const char *str, uint str_length T
size_t ret;
#endif
-#if PHP_FASTCGI
if (fcgi_is_fastcgi()) {
fcgi_request *request = (fcgi_request*) SG(server_context);
long ret = fcgi_write(request, FCGI_STDOUT, str, str_length);
@@ -265,7 +283,7 @@ static inline size_t sapi_cgibin_single_write(const char *str, uint str_length T
}
return ret;
}
-#endif
+
#ifdef PHP_WRITE_STDOUT
ret = write(STDOUT_FILENO, str, str_length);
if (ret <= 0) return 0;
@@ -298,19 +316,17 @@ static int sapi_cgibin_ub_write(const char *str, uint str_length TSRMLS_DC)
static void sapi_cgibin_flush(void *server_context)
{
-#if PHP_FASTCGI
if (fcgi_is_fastcgi()) {
fcgi_request *request = (fcgi_request*) server_context;
if (
#ifndef PHP_WIN32
- !parent &&
+ !parent &&
#endif
request && !fcgi_flush(request, 0)) {
php_handle_aborted_connection();
}
return;
}
-#endif
if (fflush(stdout) == EOF) {
php_handle_aborted_connection();
}
@@ -396,16 +412,18 @@ static int sapi_cgi_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC)
char *s;
if (SG(sapi_headers).http_status_line &&
- (s = strchr(SG(sapi_headers).http_status_line, ' ')) != 0 &&
- (s - SG(sapi_headers).http_status_line) >= 5 &&
- strncasecmp(SG(sapi_headers).http_status_line, "HTTP/", 5) == 0) {
+ (s = strchr(SG(sapi_headers).http_status_line, ' ')) != 0 &&
+ (s - SG(sapi_headers).http_status_line) >= 5 &&
+ strncasecmp(SG(sapi_headers).http_status_line, "HTTP/", 5) == 0
+ ) {
len = slprintf(buf, sizeof(buf), "Status:%s\r\n", s);
response_status = atoi((s + 1));
} else {
h = (sapi_header_struct*)zend_llist_get_first_ex(&sapi_headers->headers, &pos);
while (h) {
if (h->header_len > sizeof("Status:")-1 &&
- strncasecmp(h->header, "Status:", sizeof("Status:")-1) == 0) {
+ strncasecmp(h->header, "Status:", sizeof("Status:")-1) == 0
+ ) {
has_status = 1;
break;
}
@@ -415,7 +433,7 @@ static int sapi_cgi_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC)
http_error *err = (http_error*)http_error_codes;
while (err->code != 0) {
- if (err->code == SG(sapi_headers).http_response_code) {
+ if (err->code == SG(sapi_headers).http_response_code) {
break;
}
err++;
@@ -428,6 +446,7 @@ static int sapi_cgi_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC)
}
}
}
+
if (!has_status) {
PHPWRITE_H(buf, len);
ignore_status = 1;
@@ -438,15 +457,17 @@ static int sapi_cgi_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC)
while (h) {
/* prevent CRLFCRLF */
if (h->header_len) {
- if (h->header_len > sizeof("Status:")-1 &&
- strncasecmp(h->header, "Status:", sizeof("Status:")-1) == 0) {
- if (!ignore_status) {
- ignore_status = 1;
+ if (h->header_len > sizeof("Status:")-1 &&
+ strncasecmp(h->header, "Status:", sizeof("Status:")-1) == 0
+ ) {
+ if (!ignore_status) {
+ ignore_status = 1;
PHPWRITE_H(h->header, h->header_len);
PHPWRITE_H("\r\n", 2);
}
- } else if (response_status == 304 && h->header_len > sizeof("Content-Type:")-1 &&
- strncasecmp(h->header, "Content-Type:", sizeof("Content-Type:")-1) == 0) {
+ } else if (response_status == 304 && h->header_len > sizeof("Content-Type:")-1 &&
+ strncasecmp(h->header, "Content-Type:", sizeof("Content-Type:")-1) == 0
+ ) {
h = (sapi_header_struct*)zend_llist_get_next_ex(&sapi_headers->headers, &pos);
continue;
} else {
@@ -467,21 +488,17 @@ static int sapi_cgi_send_headers(sapi_headers_struct *sapi_headers TSRMLS_DC)
static int sapi_cgi_read_post(char *buffer, uint count_bytes TSRMLS_DC)
{
- int read_bytes=0, tmp_read_bytes;
+ uint read_bytes = 0;
+ int tmp_read_bytes;
count_bytes = MIN(count_bytes, (uint) SG(request_info).content_length - SG(read_post_bytes));
while (read_bytes < count_bytes) {
-#if PHP_FASTCGI
if (fcgi_is_fastcgi()) {
fcgi_request *request = (fcgi_request*) SG(server_context);
tmp_read_bytes = fcgi_read(request, buffer + read_bytes, count_bytes - read_bytes);
} else {
tmp_read_bytes = read(STDIN_FILENO, buffer + read_bytes, count_bytes - read_bytes);
}
-#else
- tmp_read_bytes = read(STDIN_FILENO, buffer + read_bytes, count_bytes - read_bytes);
-#endif
-
if (tmp_read_bytes <= 0) {
break;
}
@@ -492,16 +509,14 @@ static int sapi_cgi_read_post(char *buffer, uint count_bytes TSRMLS_DC)
static char *sapi_cgibin_getenv(char *name, size_t name_len TSRMLS_DC)
{
-#if PHP_FASTCGI
/* when php is started by mod_fastcgi, no regular environment
- is provided to PHP. It is always sent to PHP at the start
- of a request. So we have to do our own lookup to get env
- vars. This could probably be faster somehow. */
+ * is provided to PHP. It is always sent to PHP at the start
+ * of a request. So we have to do our own lookup to get env
+ * vars. This could probably be faster somehow. */
if (fcgi_is_fastcgi()) {
fcgi_request *request = (fcgi_request*) SG(server_context);
return fcgi_getenv(request, name, name_len);
}
-#endif
/* if cgi, or fastcgi and not found in fcgi env
check the regular environment */
return getenv(name);
@@ -520,16 +535,15 @@ static char *_sapi_cgibin_putenv(char *name, char *value TSRMLS_DC)
}
name_len = strlen(name);
-#if PHP_FASTCGI
/* when php is started by mod_fastcgi, no regular environment
- is provided to PHP. It is always sent to PHP at the start
- of a request. So we have to do our own lookup to get env
- vars. This could probably be faster somehow. */
+ * is provided to PHP. It is always sent to PHP at the start
+ * of a request. So we have to do our own lookup to get env
+ * vars. This could probably be faster somehow. */
if (fcgi_is_fastcgi()) {
fcgi_request *request = (fcgi_request*) SG(server_context);
return fcgi_putenv(request, name, name_len, value);
}
-#endif
+
#if HAVE_SETENV
if (value) {
setenv(name, value, 1);
@@ -543,7 +557,7 @@ static char *_sapi_cgibin_putenv(char *name, char *value TSRMLS_DC)
#if !HAVE_SETENV || !HAVE_UNSETENV
/* if cgi, or fastcgi and not found in fcgi env
- check the regular environment
+ check the regular environment
this leaks, but it's only cgi anyway, we'll fix
it for 5.0
*/
@@ -573,29 +587,30 @@ static char *sapi_cgi_read_cookies(TSRMLS_D)
return sapi_cgibin_getenv((char *) "HTTP_COOKIE", sizeof("HTTP_COOKIE")-1 TSRMLS_CC);
}
-#if PHP_FASTCGI
void cgi_php_import_environment_variables(zval *array_ptr TSRMLS_DC)
{
if (PG(http_globals)[TRACK_VARS_ENV] &&
- array_ptr != PG(http_globals)[TRACK_VARS_ENV] &&
- Z_TYPE_P(PG(http_globals)[TRACK_VARS_ENV]) == IS_ARRAY &&
- zend_hash_num_elements(Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_ENV])) > 0) {
- zval_dtor(array_ptr);
- *array_ptr = *PG(http_globals)[TRACK_VARS_ENV];
- INIT_PZVAL(array_ptr);
- zval_copy_ctor(array_ptr);
- return;
+ array_ptr != PG(http_globals)[TRACK_VARS_ENV] &&
+ Z_TYPE_P(PG(http_globals)[TRACK_VARS_ENV]) == IS_ARRAY &&
+ zend_hash_num_elements(Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_ENV])) > 0
+ ) {
+ zval_dtor(array_ptr);
+ *array_ptr = *PG(http_globals)[TRACK_VARS_ENV];
+ INIT_PZVAL(array_ptr);
+ zval_copy_ctor(array_ptr);
+ return;
} else if (PG(http_globals)[TRACK_VARS_SERVER] &&
array_ptr != PG(http_globals)[TRACK_VARS_SERVER] &&
- Z_TYPE_P(PG(http_globals)[TRACK_VARS_SERVER]) == IS_ARRAY &&
- zend_hash_num_elements(Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_SERVER])) > 0) {
- zval_dtor(array_ptr);
- *array_ptr = *PG(http_globals)[TRACK_VARS_SERVER];
- INIT_PZVAL(array_ptr);
- zval_copy_ctor(array_ptr);
- return;
+ Z_TYPE_P(PG(http_globals)[TRACK_VARS_SERVER]) == IS_ARRAY &&
+ zend_hash_num_elements(Z_ARRVAL_P(PG(http_globals)[TRACK_VARS_SERVER])) > 0
+ ) {
+ zval_dtor(array_ptr);
+ *array_ptr = *PG(http_globals)[TRACK_VARS_SERVER];
+ INIT_PZVAL(array_ptr);
+ zval_copy_ctor(array_ptr);
+ return;
}
-
+
/* call php's original import as a catch-all */
php_php_import_environment_variables(array_ptr TSRMLS_CC);
@@ -610,11 +625,13 @@ void cgi_php_import_environment_variables(zval *array_ptr TSRMLS_DC)
/* turn off magic_quotes while importing environment variables */
PG(magic_quotes_gpc) = 0;
- for (zend_hash_internal_pointer_reset_ex(&request->env, &pos);
- zend_hash_get_current_key_ex(&request->env, &var, &var_len, &idx, 0, &pos) == HASH_KEY_IS_STRING &&
- zend_hash_get_current_data_ex(&request->env, (void **) &val, &pos) == SUCCESS;
- zend_hash_move_forward_ex(&request->env, &pos)) {
+ for (zend_hash_internal_pointer_reset_ex(request->env, &pos);
+ zend_hash_get_current_key_ex(request->env, &var, &var_len, &idx, 0, &pos) == HASH_KEY_IS_STRING &&
+ zend_hash_get_current_data_ex(request->env, (void **) &val, &pos) == SUCCESS;
+ zend_hash_move_forward_ex(request->env, &pos)
+ ) {
unsigned int new_val_len;
+
if (sapi_module.input_filter(filter_arg, var, val, strlen(*val), &new_val_len TSRMLS_CC)) {
php_register_variable_safe(var, *val, new_val_len, array_ptr TSRMLS_CC);
}
@@ -622,7 +639,6 @@ void cgi_php_import_environment_variables(zval *array_ptr TSRMLS_DC)
PG(magic_quotes_gpc) = magic_quotes_gpc;
}
}
-#endif
static void sapi_cgi_register_variables(zval *track_vars_array TSRMLS_DC)
{
@@ -634,15 +650,15 @@ static void sapi_cgi_register_variables(zval *track_vars_array TSRMLS_DC)
*/
php_import_environment_variables(track_vars_array TSRMLS_CC);
-#if ENABLE_PATHINFO_CHECK
if (CGIG(fix_pathinfo)) {
- char *script_name = SG(request_info).request_uri;
+ char *script_name = SG(request_info).request_uri;
unsigned int script_name_len = script_name ? strlen(script_name) : 0;
- char *path_info = sapi_cgibin_getenv("PATH_INFO", sizeof("PATH_INFO")-1 TSRMLS_CC);
+ char *path_info = sapi_cgibin_getenv("PATH_INFO", sizeof("PATH_INFO")-1 TSRMLS_CC);
unsigned int path_info_len = path_info ? strlen(path_info) : 0;
php_self_len = script_name_len + path_info_len;
php_self = emalloc(php_self_len + 1);
+
if (script_name) {
memcpy(php_self, script_name, script_name_len + 1);
}
@@ -655,27 +671,24 @@ static void sapi_cgi_register_variables(zval *track_vars_array TSRMLS_DC)
php_register_variable_safe("PHP_SELF", php_self, php_self_len, track_vars_array TSRMLS_CC);
}
efree(php_self);
- return;
- }
-#endif
-
- php_self = SG(request_info).request_uri ? SG(request_info).request_uri : "";
- php_self_len = strlen(php_self);
- if (sapi_module.input_filter(PARSE_SERVER, "PHP_SELF", &php_self, php_self_len, &php_self_len TSRMLS_CC)) {
- php_register_variable_safe("PHP_SELF", php_self, php_self_len, track_vars_array TSRMLS_CC);
+ } else {
+ php_self = SG(request_info).request_uri ? SG(request_info).request_uri : "";
+ php_self_len = strlen(php_self);
+ if (sapi_module.input_filter(PARSE_SERVER, "PHP_SELF", &php_self, php_self_len, &php_self_len TSRMLS_CC)) {
+ php_register_variable_safe("PHP_SELF", php_self, php_self_len, track_vars_array TSRMLS_CC);
+ }
}
}
static void sapi_cgi_log_message(char *message)
{
-#if PHP_FASTCGI
TSRMLS_FETCH();
if (fcgi_is_fastcgi() && CGIG(fcgi_logging)) {
fcgi_request *request;
-
+
request = (fcgi_request*) SG(server_context);
- if (request) {
+ if (request) {
int len = strlen(message);
char *buf = malloc(len+2);
@@ -687,20 +700,173 @@ static void sapi_cgi_log_message(char *message)
fprintf(stderr, "%s\n", message);
}
/* ignore return code */
- } else
-#endif /* PHP_FASTCGI */
- fprintf(stderr, "%s\n", message);
+ } else {
+ fprintf(stderr, "%s\n", message);
+ }
+}
+
+/* {{{ php_cgi_ini_activate_user_config
+ */
+static void php_cgi_ini_activate_user_config(char *path, int path_len, const char *doc_root, int doc_root_len, int start TSRMLS_DC)
+{
+ char *ptr;
+ user_config_cache_entry *new_entry, *entry;
+ time_t request_time = sapi_get_request_time(TSRMLS_C);
+
+ /* Find cached config entry: If not found, create one */
+ if (zend_hash_find(&CGIG(user_config_cache), path, path_len + 1, (void **) &entry) == FAILURE) {
+ new_entry = pemalloc(sizeof(user_config_cache_entry), 1);
+ new_entry->expires = 0;
+ new_entry->user_config = (HashTable *) pemalloc(sizeof(HashTable), 1);
+ zend_hash_init(new_entry->user_config, 0, NULL, (dtor_func_t) config_zval_dtor, 1);
+ zend_hash_update(&CGIG(user_config_cache), path, path_len + 1, new_entry, sizeof(user_config_cache_entry), (void **) &entry);
+ free(new_entry);
+ }
+
+ /* Check whether cache entry has expired and rescan if it is */
+ if (request_time > entry->expires) {
+ char * real_path;
+ int real_path_len;
+ char *s1, *s2;
+ int s_len;
+
+ /* Clear the expired config */
+ zend_hash_clean(entry->user_config);
+
+ if (!IS_ABSOLUTE_PATH(path, path_len)) {
+ real_path = tsrm_realpath(path, NULL TSRMLS_CC);
+ real_path_len = strlen(real_path);
+ path = real_path;
+ path_len = real_path_len;
+ }
+
+ if (path_len > doc_root_len) {
+ s1 = (char *) doc_root;
+ s2 = path;
+ s_len = doc_root_len;
+ } else {
+ s1 = path;
+ s2 = (char *) doc_root;
+ s_len = path_len;
+ }
+
+ /* we have to test if path is part of DOCUMENT_ROOT.
+ if it is inside the docroot, we scan the tree up to the docroot
+ to find more user.ini, if not we only scan the current path.
+ */
+#ifdef PHP_WIN32
+ if (strnicmp(s1, s2, s_len) == 0) {
+#else
+ if (strncmp(s1, s2, s_len) == 0) {
+#endif
+ ptr = s2 + start; /* start is the point where doc_root ends! */
+ while ((ptr = strchr(ptr, DEFAULT_SLASH)) != NULL) {
+ *ptr = 0;
+ php_parse_user_ini_file(path, PG(user_ini_filename), entry->user_config TSRMLS_CC);
+ *ptr = '/';
+ ptr++;
+ }
+ } else {
+ php_parse_user_ini_file(path, PG(user_ini_filename), entry->user_config TSRMLS_CC);
+ }
+
+ entry->expires = request_time + PG(user_ini_cache_ttl);
+ }
+
+ /* Activate ini entries with values from the user config hash */
+ php_ini_activate_config(entry->user_config, PHP_INI_PERDIR, PHP_INI_STAGE_HTACCESS TSRMLS_CC);
+}
+/* }}} */
+
+static int sapi_cgi_activate(TSRMLS_D)
+{
+ char *path, *doc_root, *server_name;
+ uint path_len, doc_root_len, server_name_len;
+
+ /* PATH_TRANSLATED should be defined at this stage but better safe than sorry :) */
+ if (!SG(request_info).path_translated) {
+ return FAILURE;
+ }
+
+ if (php_ini_has_per_host_config()) {
+ /* Activate per-host-system-configuration defined in php.ini and stored into configuration_hash during startup */
+ server_name = sapi_cgibin_getenv("SERVER_NAME", sizeof("SERVER_NAME") - 1 TSRMLS_CC);
+ /* SERVER_NAME should also be defined at this stage..but better check it anyway */
+ if (server_name) {
+ server_name_len = strlen(server_name);
+ server_name = estrndup(server_name, server_name_len);
+ zend_str_tolower(server_name, server_name_len);
+ php_ini_activate_per_host_config(server_name, server_name_len + 1 TSRMLS_CC);
+ efree(server_name);
+ }
+ }
+
+ if (php_ini_has_per_dir_config() ||
+ (PG(user_ini_filename) && *PG(user_ini_filename))
+ ) {
+ /* Prepare search path */
+ path_len = strlen(SG(request_info).path_translated);
+
+ /* Make sure we have trailing slash! */
+ if (!IS_SLASH(SG(request_info).path_translated[path_len])) {
+ path = emalloc(path_len + 2);
+ memcpy(path, SG(request_info).path_translated, path_len + 1);
+ path_len = zend_dirname(path, path_len);
+ path[path_len++] = DEFAULT_SLASH;
+ } else {
+ path = estrndup(SG(request_info).path_translated, path_len);
+ path_len = zend_dirname(path, path_len);
+ }
+ path[path_len] = 0;
+
+ /* Activate per-dir-system-configuration defined in php.ini and stored into configuration_hash during startup */
+ php_ini_activate_per_dir_config(path, path_len TSRMLS_CC); /* Note: for global settings sake we check from root to path */
+
+ /* Load and activate user ini files in path starting from DOCUMENT_ROOT */
+ if (PG(user_ini_filename) && *PG(user_ini_filename)) {
+ doc_root = sapi_cgibin_getenv("DOCUMENT_ROOT", sizeof("DOCUMENT_ROOT") - 1 TSRMLS_CC);
+ /* DOCUMENT_ROOT should also be defined at this stage..but better check it anyway */
+ if (doc_root) {
+ doc_root_len = strlen(doc_root);
+ if (doc_root_len > 0 && IS_SLASH(doc_root[doc_root_len - 1])) {
+ --doc_root_len;
+ }
+#ifdef PHP_WIN32
+ /* paths on windows should be case-insensitive */
+ doc_root = estrndup(doc_root, doc_root_len);
+ zend_str_tolower(doc_root, doc_root_len);
+#endif
+ php_cgi_ini_activate_user_config(path, path_len, doc_root, doc_root_len, doc_root_len - 1 TSRMLS_CC);
+ }
+ }
+
+#ifdef PHP_WIN32
+ efree(doc_root);
+#endif
+ efree(path);
+ }
+
+ return SUCCESS;
}
static int sapi_cgi_deactivate(TSRMLS_D)
{
/* flush only when SAPI was started. The reasons are:
1. SAPI Deactivate is called from two places: module init and request shutdown
- 2. When the first call occurs and the request is not set up, flush fails on
- FastCGI.
+ 2. When the first call occurs and the request is not set up, flush fails on FastCGI.
*/
if (SG(sapi_started)) {
- sapi_cgibin_flush(SG(server_context));
+ if (fcgi_is_fastcgi()) {
+ if (
+#ifndef PHP_WIN32
+ !parent &&
+#endif
+ !fcgi_finish_request((fcgi_request*)SG(server_context), 0)) {
+ php_handle_aborted_connection();
+ }
+ } else {
+ sapi_cgibin_flush(SG(server_context));
+ }
}
return SUCCESS;
}
@@ -713,22 +879,16 @@ static int php_cgi_startup(sapi_module_struct *sapi_module)
return SUCCESS;
}
-
/* {{{ sapi_module_struct cgi_sapi_module
*/
static sapi_module_struct cgi_sapi_module = {
-#if PHP_FASTCGI
"cgi-fcgi", /* name */
"CGI/FastCGI", /* pretty name */
-#else
- "cgi", /* name */
- "CGI", /* pretty name */
-#endif
php_cgi_startup, /* startup */
php_module_shutdown_wrapper, /* shutdown */
- NULL, /* activate */
+ sapi_cgi_activate, /* activate */
sapi_cgi_deactivate, /* deactivate */
sapi_cgibin_ub_write, /* unbuffered write */
@@ -748,11 +908,23 @@ static sapi_module_struct cgi_sapi_module = {
sapi_cgi_register_variables, /* register server variables */
sapi_cgi_log_message, /* Log message */
NULL, /* Get request time */
+ NULL, /* Child terminate */
STANDARD_SAPI_MODULE_PROPERTIES
};
/* }}} */
+/* {{{ arginfo ext/standard/dl.c */
+ZEND_BEGIN_ARG_INFO(arginfo_dl, 0)
+ ZEND_ARG_INFO(0, extension_filename)
+ZEND_END_ARG_INFO()
+/* }}} */
+
+static const zend_function_entry additional_functions[] = {
+ ZEND_FE(dl, arginfo_dl)
+ {NULL, NULL, NULL}
+};
+
/* {{{ php_cgi_usage
*/
static void php_cgi_usage(char *argv0)
@@ -766,32 +938,27 @@ static void php_cgi_usage(char *argv0)
prog = "php";
}
- php_printf("Usage: %s [-q] [-h] [-s] [-v] [-i] [-f <file>]\n"
- " %s <file> [args...]\n"
- " -a Run interactively\n"
-#if PHP_FASTCGI
- " -b <address:port>|<port> Bind Path for external FASTCGI Server mode\n"
-#endif
- " -C Do not chdir to the script's directory\n"
- " -c <path>|<file> Look for php.ini file in this directory\n"
- " -n No php.ini file will be used\n"
- " -d foo[=bar] Define INI entry foo with value 'bar'\n"
- " -e Generate extended information for debugger/profiler\n"
- " -f <file> Parse <file>. Implies `-q'\n"
- " -h This help\n"
- " -i PHP information\n"
- " -l Syntax check only (lint)\n"
- " -m Show compiled in modules\n"
- " -q Quiet-mode. Suppress HTTP Header output.\n"
- " -s Display colour syntax highlighted source.\n"
- " -v Version number\n"
- " -w Display source with stripped comments and whitespace.\n"
- " -z <file> Load Zend extension <file>.\n"
-#if PHP_FASTCGI
- " -T <count> Measure execution time of script repeated <count> times.\n"
-#endif
- ,
- prog, prog);
+ php_printf( "Usage: %s [-q] [-h] [-s] [-v] [-i] [-f <file>]\n"
+ " %s <file> [args...]\n"
+ " -a Run interactively\n"
+ " -b <address:port>|<port> Bind Path for external FASTCGI Server mode\n"
+ " -C Do not chdir to the script's directory\n"
+ " -c <path>|<file> Look for php.ini file in this directory\n"
+ " -n No php.ini file will be used\n"
+ " -d foo[=bar] Define INI entry foo with value 'bar'\n"
+ " -e Generate extended information for debugger/profiler\n"
+ " -f <file> Parse <file>. Implies `-q'\n"
+ " -h This help\n"
+ " -i PHP information\n"
+ " -l Syntax check only (lint)\n"
+ " -m Show compiled in modules\n"
+ " -q Quiet-mode. Suppress HTTP Header output.\n"
+ " -s Display colour syntax highlighted source.\n"
+ " -v Version number\n"
+ " -w Display source with stripped comments and whitespace.\n"
+ " -z <file> Load Zend extension <file>.\n"
+ " -T <count> Measure execution time of script repeated <count> times.\n",
+ prog, prog);
}
/* }}} */
@@ -810,7 +977,8 @@ static int is_valid_path(const char *path)
p = strstr(path, "..");
if (p) {
if ((p == path || IS_SLASH(*(p-1))) &&
- (*(p+2) == 0 || IS_SLASH(*(p+2)))) {
+ (*(p+2) == 0 || IS_SLASH(*(p+2)))
+ ) {
return 0;
}
while (1) {
@@ -819,7 +987,8 @@ static int is_valid_path(const char *path)
break;
}
if (IS_SLASH(*(p-1)) &&
- (*(p+2) == 0 || IS_SLASH(*(p+2)))) {
+ (*(p+2) == 0 || IS_SLASH(*(p+2)))
+ ) {
return 0;
}
}
@@ -836,14 +1005,14 @@ static int is_valid_path(const char *path)
for:
PATH_INFO
- derived from the portion of the URI path following
+ derived from the portion of the URI path following
the script name but preceding any query data
may be empty
PATH_TRANSLATED
- derived by taking any path-info component of the
- request URI and performing any virtual-to-physical
- translation appropriate to map it onto the server's
+ derived by taking any path-info component of the
+ request URI and performing any virtual-to-physical
+ translation appropriate to map it onto the server's
document repository structure
empty if PATH_INFO is empty
@@ -854,13 +1023,13 @@ static int is_valid_path(const char *path)
SCRIPT_NAME
set to a URL path that could identify the CGI script
- rather than the interpreter. PHP_SELF is set to this.
+ rather than the interpreter. PHP_SELF is set to this
REQUEST_URI
uri section following the domain:port part of a URI
SCRIPT_FILENAME
- The virtual-to-physical translation of SCRIPT_NAME (as per
+ The virtual-to-physical translation of SCRIPT_NAME (as per
PATH_TRANSLATED)
These settings are documented at
@@ -868,29 +1037,29 @@ static int is_valid_path(const char *path)
Based on the following URL request:
-
- http://localhost/info.php/test?a=b
-
+
+ http://localhost/info.php/test?a=b
+
should produce, which btw is the same as if
we were running under mod_cgi on apache (ie. not
using ScriptAlias directives):
-
+
PATH_INFO=/test
PATH_TRANSLATED=/docroot/test
SCRIPT_NAME=/info.php
REQUEST_URI=/info.php/test?a=b
SCRIPT_FILENAME=/docroot/info.php
QUERY_STRING=a=b
-
+
but what we get is (cgi/mod_fastcgi under apache):
-
+
PATH_INFO=/info.php/test
PATH_TRANSLATED=/docroot/info.php/test
SCRIPT_NAME=/php/php-cgi (from the Action setting I suppose)
REQUEST_URI=/info.php/test?a=b
SCRIPT_FILENAME=/path/to/php/bin/php-cgi (Action setting translated)
QUERY_STRING=a=b
-
+
Comments in the code below refer to using the above URL in a request
*/
@@ -900,14 +1069,12 @@ static void init_request_info(TSRMLS_D)
char *env_path_translated = sapi_cgibin_getenv("PATH_TRANSLATED", sizeof("PATH_TRANSLATED")-1 TSRMLS_CC);
char *script_path_translated = env_script_filename;
-#if !DISCARD_PATH
/* some broken servers do not have script_filename or argv0
- an example, IIS configured in some ways. then they do more
- broken stuff and set path_translated to the cgi script location */
+ * an example, IIS configured in some ways. then they do more
+ * broken stuff and set path_translated to the cgi script location */
if (!script_path_translated && env_path_translated) {
script_path_translated = env_path_translated;
}
-#endif
/* initialize the defaults */
SG(request_info).path_translated = NULL;
@@ -920,57 +1087,57 @@ static void init_request_info(TSRMLS_D)
SG(sapi_headers).http_response_code = 200;
/* script_path_translated being set is a good indication that
- we are running in a cgi environment, since it is always
- null otherwise. otherwise, the filename
- of the script will be retreived later via argc/argv */
+ * we are running in a cgi environment, since it is always
+ * null otherwise. otherwise, the filename
+ * of the script will be retreived later via argc/argv */
if (script_path_translated) {
const char *auth;
char *content_length = sapi_cgibin_getenv("CONTENT_LENGTH", sizeof("CONTENT_LENGTH")-1 TSRMLS_CC);
char *content_type = sapi_cgibin_getenv("CONTENT_TYPE", sizeof("CONTENT_TYPE")-1 TSRMLS_CC);
char *env_path_info = sapi_cgibin_getenv("PATH_INFO", sizeof("PATH_INFO")-1 TSRMLS_CC);
char *env_script_name = sapi_cgibin_getenv("SCRIPT_NAME", sizeof("SCRIPT_NAME")-1 TSRMLS_CC);
-#if ENABLE_PATHINFO_CHECK
- struct stat st;
- char *env_redirect_url = sapi_cgibin_getenv("REDIRECT_URL", sizeof("REDIRECT_URL")-1 TSRMLS_CC);
- char *env_document_root = sapi_cgibin_getenv("DOCUMENT_ROOT", sizeof("DOCUMENT_ROOT")-1 TSRMLS_CC);
- int script_path_translated_len;
/* Hack for buggy IIS that sets incorrect PATH_INFO */
char *env_server_software = sapi_cgibin_getenv("SERVER_SOFTWARE", sizeof("SERVER_SOFTWARE")-1 TSRMLS_CC);
if (env_server_software &&
- env_script_name &&
- env_path_info &&
- strncmp(env_server_software, "Microsoft-IIS", sizeof("Microsoft-IIS")-1) == 0 &&
- strncmp(env_path_info, env_script_name, strlen(env_script_name)) == 0) {
+ env_script_name &&
+ env_path_info &&
+ strncmp(env_server_software, "Microsoft-IIS", sizeof("Microsoft-IIS")-1) == 0 &&
+ strncmp(env_path_info, env_script_name, strlen(env_script_name)) == 0
+ ) {
env_path_info = _sapi_cgibin_putenv("ORIG_PATH_INFO", env_path_info TSRMLS_CC);
- env_path_info += strlen(env_script_name);
- if (*env_path_info == 0) {
- env_path_info = NULL;
- }
+ env_path_info += strlen(env_script_name);
+ if (*env_path_info == 0) {
+ env_path_info = NULL;
+ }
env_path_info = _sapi_cgibin_putenv("PATH_INFO", env_path_info TSRMLS_CC);
}
if (CGIG(fix_pathinfo)) {
+ struct stat st;
char *real_path = NULL;
+ char *env_redirect_url = sapi_cgibin_getenv("REDIRECT_URL", sizeof("REDIRECT_URL")-1 TSRMLS_CC);
+ char *env_document_root = sapi_cgibin_getenv("DOCUMENT_ROOT", sizeof("DOCUMENT_ROOT")-1 TSRMLS_CC);
char *orig_path_translated = env_path_translated;
char *orig_path_info = env_path_info;
char *orig_script_name = env_script_name;
char *orig_script_filename = env_script_filename;
+ int script_path_translated_len;
if (!env_document_root && PG(doc_root)) {
env_document_root = _sapi_cgibin_putenv("DOCUMENT_ROOT", PG(doc_root) TSRMLS_CC);
/* fix docroot */
TRANSLATE_SLASHES(env_document_root);
- }
-
- if (env_path_translated != NULL && env_redirect_url != NULL &&
- env_path_translated != script_path_translated &&
- strcmp(env_path_translated, script_path_translated) != 0) {
- /*
- pretty much apache specific. If we have a redirect_url
- then our script_filename and script_name point to the
- php executable
- */
+ }
+
+ if (env_path_translated != NULL && env_redirect_url != NULL &&
+ env_path_translated != script_path_translated &&
+ strcmp(env_path_translated, script_path_translated) != 0) {
+ /*
+ * pretty much apache specific. If we have a redirect_url
+ * then our script_filename and script_name point to the
+ * php executable
+ */
script_path_translated = env_path_translated;
/* we correct SCRIPT_NAME now in case we don't have PATH_INFO */
env_script_name = env_redirect_url;
@@ -981,7 +1148,7 @@ static void init_request_info(TSRMLS_D)
__riscosify_control |= __RISCOSIFY_DONT_CHECK_DIR;
script_path_translated = __unixify(script_path_translated, 0, NULL, 1, 0);
#endif
-
+
/*
* if the file doesn't exist, try to extract PATH_INFO out
* of it by stat'ing back through the '/'
@@ -991,9 +1158,10 @@ static void init_request_info(TSRMLS_D)
(script_path_translated_len = strlen(script_path_translated)) > 0 &&
(script_path_translated[script_path_translated_len-1] == '/' ||
#ifdef PHP_WIN32
- script_path_translated[script_path_translated_len-1] == '\\' ||
+ script_path_translated[script_path_translated_len-1] == '\\' ||
#endif
- (real_path = tsrm_realpath(script_path_translated, NULL TSRMLS_CC)) == NULL)) {
+ (real_path = tsrm_realpath(script_path_translated, NULL TSRMLS_CC)) == NULL)
+ ) {
char *pt = estrndup(script_path_translated, script_path_translated_len);
int len = script_path_translated_len;
char *ptr;
@@ -1050,14 +1218,13 @@ static void init_request_info(TSRMLS_D)
TRANSLATE_SLASHES(pt);
/* figure out docroot
- SCRIPT_FILENAME minus SCRIPT_NAME
- */
-
+ * SCRIPT_FILENAME minus SCRIPT_NAME
+ */
if (env_document_root) {
int l = strlen(env_document_root);
int path_translated_len = 0;
char *path_translated = NULL;
-
+
if (l && env_document_root[l - 1] == '/') {
--l;
}
@@ -1077,11 +1244,11 @@ static void init_request_info(TSRMLS_D)
path_translated[path_translated_len] = '\0';
if (orig_path_translated) {
_sapi_cgibin_putenv("ORIG_PATH_TRANSLATED", orig_path_translated TSRMLS_CC);
- }
+ }
env_path_translated = _sapi_cgibin_putenv("PATH_TRANSLATED", path_translated TSRMLS_CC);
efree(path_translated);
- } else if (env_script_name &&
- strstr(pt, env_script_name)
+ } else if ( env_script_name &&
+ strstr(pt, env_script_name)
) {
/* PATH_TRANSLATED = PATH_TRANSLATED - SCRIPT_NAME + PATH_INFO */
int ptlen = strlen(pt) - strlen(env_script_name);
@@ -1096,7 +1263,7 @@ static void init_request_info(TSRMLS_D)
path_translated[path_translated_len] = '\0';
if (orig_path_translated) {
_sapi_cgibin_putenv("ORIG_PATH_TRANSLATED", orig_path_translated TSRMLS_CC);
- }
+ }
env_path_translated = _sapi_cgibin_putenv("PATH_TRANSLATED", path_translated TSRMLS_CC);
efree(path_translated);
}
@@ -1125,13 +1292,10 @@ static void init_request_info(TSRMLS_D)
} else {
SG(request_info).request_uri = orig_script_name;
}
- }
+ }
if (pt) {
efree(pt);
}
- if (is_valid_path(script_path_translated)) {
- SG(request_info).path_translated = estrdup(script_path_translated);
- }
} else {
/* make sure path_info/translated are empty */
if (!orig_script_filename ||
@@ -1143,12 +1307,12 @@ static void init_request_info(TSRMLS_D)
script_path_translated = _sapi_cgibin_putenv("SCRIPT_FILENAME", script_path_translated TSRMLS_CC);
}
if (env_redirect_url) {
- if (orig_path_info) {
+ if (orig_path_info) {
_sapi_cgibin_putenv("ORIG_PATH_INFO", orig_path_info TSRMLS_CC);
_sapi_cgibin_putenv("PATH_INFO", NULL TSRMLS_CC);
}
if (orig_path_translated) {
- _sapi_cgibin_putenv("ORIG_PATH_TRANSLATED", orig_path_translated TSRMLS_CC);
+ _sapi_cgibin_putenv("ORIG_PATH_TRANSLATED", orig_path_translated TSRMLS_CC);
_sapi_cgibin_putenv("PATH_TRANSLATED", NULL TSRMLS_CC);
}
}
@@ -1160,36 +1324,30 @@ static void init_request_info(TSRMLS_D)
} else {
SG(request_info).request_uri = env_script_name;
}
- if (is_valid_path(script_path_translated)) {
- SG(request_info).path_translated = estrdup(script_path_translated);
- }
free(real_path);
}
} else {
-#endif
/* pre 4.3 behaviour, shouldn't be used but provides BC */
if (env_path_info) {
SG(request_info).request_uri = env_path_info;
} else {
SG(request_info).request_uri = env_script_name;
}
-#if !DISCARD_PATH
- if (env_path_translated) {
+ if (!CGIG(discard_path) && env_path_translated) {
script_path_translated = env_path_translated;
}
-#endif
- if (is_valid_path(script_path_translated)) {
- SG(request_info).path_translated = estrdup(script_path_translated);
- }
-#if ENABLE_PATHINFO_CHECK
}
-#endif
+
+ if (is_valid_path(script_path_translated)) {
+ SG(request_info).path_translated = estrdup(script_path_translated);
+ }
+
SG(request_info).request_method = sapi_cgibin_getenv("REQUEST_METHOD", sizeof("REQUEST_METHOD")-1 TSRMLS_CC);
/* FIXME - Work out proto_num here */
SG(request_info).query_string = sapi_cgibin_getenv("QUERY_STRING", sizeof("QUERY_STRING")-1 TSRMLS_CC);
SG(request_info).content_type = (content_type ? content_type : "" );
SG(request_info).content_length = (content_length ? atoi(content_length) : 0);
-
+
/* The CGI RFC allows servers to pass on unvalidated Authorization data */
auth = sapi_cgibin_getenv("HTTP_AUTHORIZATION", sizeof("HTTP_AUTHORIZATION")-1 TSRMLS_CC);
php_handle_auth_data(auth TSRMLS_CC);
@@ -1197,7 +1355,7 @@ static void init_request_info(TSRMLS_D)
}
/* }}} */
-#if PHP_FASTCGI && !defined(PHP_WIN32)
+#ifndef PHP_WIN32
/**
* Clean up child processes upon exit
*/
@@ -1224,18 +1382,13 @@ PHP_INI_BEGIN()
STD_PHP_INI_ENTRY("cgi.rfc2616_headers", "0", PHP_INI_ALL, OnUpdateBool, rfc2616_headers, php_cgi_globals_struct, php_cgi_globals)
STD_PHP_INI_ENTRY("cgi.nph", "0", PHP_INI_ALL, OnUpdateBool, nph, php_cgi_globals_struct, php_cgi_globals)
STD_PHP_INI_ENTRY("cgi.check_shebang_line", "1", PHP_INI_SYSTEM, OnUpdateBool, check_shebang_line, php_cgi_globals_struct, php_cgi_globals)
-#if FORCE_CGI_REDIRECT
STD_PHP_INI_ENTRY("cgi.force_redirect", "1", PHP_INI_SYSTEM, OnUpdateBool, force_redirect, php_cgi_globals_struct, php_cgi_globals)
STD_PHP_INI_ENTRY("cgi.redirect_status_env", NULL, PHP_INI_SYSTEM, OnUpdateString, redirect_status_env, php_cgi_globals_struct, php_cgi_globals)
-#endif
-#if ENABLE_PATHINFO_CHECK
STD_PHP_INI_ENTRY("cgi.fix_pathinfo", "1", PHP_INI_SYSTEM, OnUpdateBool, fix_pathinfo, php_cgi_globals_struct, php_cgi_globals)
-#endif
-#if PHP_FASTCGI
+ STD_PHP_INI_ENTRY("cgi.discard_path", "0", PHP_INI_SYSTEM, OnUpdateBool, discard_path, php_cgi_globals_struct, php_cgi_globals)
STD_PHP_INI_ENTRY("fastcgi.logging", "1", PHP_INI_SYSTEM, OnUpdateBool, fcgi_logging, php_cgi_globals_struct, php_cgi_globals)
-# ifdef PHP_WIN32
+#ifdef PHP_WIN32
STD_PHP_INI_ENTRY("fastcgi.impersonate", "0", PHP_INI_SYSTEM, OnUpdateBool, impersonate, php_cgi_globals_struct, php_cgi_globals)
-# endif
#endif
PHP_INI_END()
@@ -1246,19 +1399,15 @@ static void php_cgi_globals_ctor(php_cgi_globals_struct *php_cgi_globals TSRMLS_
php_cgi_globals->rfc2616_headers = 0;
php_cgi_globals->nph = 0;
php_cgi_globals->check_shebang_line = 1;
-#if FORCE_CGI_REDIRECT
php_cgi_globals->force_redirect = 1;
php_cgi_globals->redirect_status_env = NULL;
-#endif
-#if ENABLE_PATHINFO_CHECK
php_cgi_globals->fix_pathinfo = 1;
-#endif
-#if PHP_FASTCGI
+ php_cgi_globals->discard_path = 0;
php_cgi_globals->fcgi_logging = 1;
-# ifdef PHP_WIN32
+#ifdef PHP_WIN32
php_cgi_globals->impersonate = 0;
-# endif
#endif
+ zend_hash_init(&php_cgi_globals->user_config_cache, 0, NULL, (dtor_func_t) user_config_cache_entry_dtor, 1);
}
/* }}} */
@@ -1280,6 +1429,8 @@ static PHP_MINIT_FUNCTION(cgi)
*/
static PHP_MSHUTDOWN_FUNCTION(cgi)
{
+ zend_hash_destroy(&CGIG(user_config_cache));
+
UNREGISTER_INI_ENTRIES();
return SUCCESS;
}
@@ -1295,17 +1446,13 @@ static PHP_MINFO_FUNCTION(cgi)
static zend_module_entry cgi_module_entry = {
STANDARD_MODULE_HEADER,
-#if PHP_FASTCGI
"cgi-fcgi",
-#else
- "cgi",
-#endif
- NULL,
- PHP_MINIT(cgi),
- PHP_MSHUTDOWN(cgi),
- NULL,
- NULL,
- PHP_MINFO(cgi),
+ NULL,
+ PHP_MINIT(cgi),
+ PHP_MSHUTDOWN(cgi),
+ NULL,
+ NULL,
+ PHP_MINFO(cgi),
NO_VERSION_YET,
STANDARD_MODULE_PROPERTIES
};
@@ -1318,22 +1465,21 @@ int main(int argc, char *argv[])
int exit_status = SUCCESS;
int cgi = 0, c, i, len;
zend_file_handle file_handle;
- int retval = FAILURE;
char *s;
-/* temporary locals */
+
+ /* temporary locals */
int behavior = PHP_MODE_STANDARD;
int no_headers = 0;
int orig_optind = php_optind;
char *orig_optarg = php_optarg;
char *script_file = NULL;
int ini_entries_len = 0;
+ /* end of temporary locals */
-/* end of temporary locals */
#ifdef ZTS
void ***tsrm_ls;
#endif
-#if PHP_FASTCGI
int max_requests = 500;
int requests = 0;
int fastcgi = fcgi_is_fastcgi();
@@ -1350,15 +1496,13 @@ int main(int argc, char *argv[])
#ifndef PHP_WIN32
int status = 0;
#endif
-#endif /* PHP_FASTCGI */
#if 0 && defined(PHP_DEBUG)
/* IIS is always making things more difficult. This allows
- us to stop PHP and attach a debugger before much gets started */
+ * us to stop PHP and attach a debugger before much gets started */
{
char szMessage [256];
- wsprintf (szMessage, "Please attach a debugger to the process 0x%X [%d] (%s) and click OK",
- GetCurrentProcessId(), GetCurrentProcessId(), argv[0]);
+ wsprintf (szMessage, "Please attach a debugger to the process 0x%X [%d] (%s) and click OK", GetCurrentProcessId(), GetCurrentProcessId(), argv[0]);
MessageBox(NULL, szMessage, "CGI Debug Time!", MB_OK|MB_SERVICE_NOTIFICATION);
}
#endif
@@ -1389,23 +1533,19 @@ int main(int argc, char *argv[])
setmode(_fileno(stderr), O_BINARY); /* make the stdio mode be binary */
#endif
-#if PHP_FASTCGI
if (!fastcgi) {
-#endif
- /* Make sure we detect we are a cgi - a bit redundancy here,
- but the default case is that we have to check only the first one. */
- if (getenv("SERVER_SOFTWARE") ||
- getenv("SERVER_NAME") ||
- getenv("GATEWAY_INTERFACE") ||
- getenv("REQUEST_METHOD")
- ) {
- cgi = 1;
- }
-#if PHP_FASTCGI
+ /* Make sure we detect we are a cgi - a bit redundancy here,
+ * but the default case is that we have to check only the first one. */
+ if (getenv("SERVER_SOFTWARE") ||
+ getenv("SERVER_NAME") ||
+ getenv("GATEWAY_INTERFACE") ||
+ getenv("REQUEST_METHOD")
+ ) {
+ cgi = 1;
+ }
}
-#endif
- while ((c = php_getopt(argc, argv, OPTIONS, &php_optarg, &php_optind, 0)) != -1) {
+ while ((c = php_getopt(argc, argv, OPTIONS, &php_optarg, &php_optind, 0, 2)) != -1) {
switch (c) {
case 'c':
if (cgi_sapi_module.php_ini_path_override) {
@@ -1416,7 +1556,7 @@ int main(int argc, char *argv[])
case 'n':
cgi_sapi_module.php_ini_ignore = 1;
break;
- case 'd': {
+ case 'd': {
/* define ini entries on command line */
int len = strlen(php_optarg);
char *val;
@@ -1447,22 +1587,18 @@ int main(int argc, char *argv[])
}
break;
}
-#if PHP_FASTCGI
/* if we're started on command line, check to see if
- we are being started as an 'external' fastcgi
- server by accepting a bindpath parameter. */
+ * we are being started as an 'external' fastcgi
+ * server by accepting a bindpath parameter. */
case 'b':
if (!fastcgi) {
bindpath = strdup(php_optarg);
}
break;
-#endif
case 's': /* generate highlighted HTML from source */
behavior = PHP_MODE_HIGHLIGHT;
break;
-
}
-
}
php_optind = orig_optind;
php_optarg = orig_optarg;
@@ -1472,6 +1608,9 @@ int main(int argc, char *argv[])
#endif
cgi_sapi_module.executable_location = argv[0];
+ if (!cgi && !fastcgi && !bindpath) {
+ cgi_sapi_module.additional_functions = additional_functions;
+ }
/* startup after we get the above ini override se we get things right */
if (cgi_sapi_module.startup(&cgi_sapi_module) == FAILURE) {
@@ -1481,7 +1620,6 @@ int main(int argc, char *argv[])
return FAILURE;
}
-#if FORCE_CGI_REDIRECT
/* check force_cgi after startup, so we have proper output */
if (cgi && CGIG(force_redirect)) {
/* Apache will generate REDIRECT_STATUS,
@@ -1490,15 +1628,14 @@ int main(int argc, char *argv[])
* http://www.koehntopp.de/php.
* -- kk@netuse.de
*/
- if (!getenv("REDIRECT_STATUS")
- && !getenv ("HTTP_REDIRECT_STATUS")
+ if (!getenv("REDIRECT_STATUS") &&
+ !getenv ("HTTP_REDIRECT_STATUS") &&
/* this is to allow a different env var to be configured
- in case some server does something different than above */
- && (!CGIG(redirect_status_env) || !getenv(CGIG(redirect_status_env)))
- ) {
- zend_try {
- SG(sapi_headers).http_response_code = 400;
- PUTS("<b>Security Alert!</b> The PHP CGI cannot be accessed directly.\n\n\
+ * in case some server does something different than above */
+ (!CGIG(redirect_status_env) || !getenv(CGIG(redirect_status_env)))
+ ) {
+ SG(sapi_headers).http_response_code = 400;
+ PUTS("<b>Security Alert!</b> The PHP CGI cannot be accessed directly.\n\n\
<p>This PHP CGI binary was compiled with force-cgi-redirect enabled. This\n\
means that a page will only be served up if the REDIRECT_STATUS CGI variable is\n\
set, e.g. via an Apache Action directive.</p>\n\
@@ -1507,23 +1644,20 @@ manual page for CGI security</a>.</p>\n\
<p>For more information about changing this behaviour or re-enabling this webserver,\n\
consult the installation file that came with this distribution, or visit \n\
<a href=\"http://php.net/install.windows\">the manual page</a>.</p>\n");
- } zend_catch {
- } zend_end_try();
+
#if defined(ZTS) && !defined(PHP_DEBUG)
/* XXX we're crashing here in msvc6 debug builds at
- php_message_handler_for_zend:839 because
- SG(request_info).path_translated is an invalid pointer.
- It still happens even though I set it to null, so something
- weird is going on.
- */
+ * php_message_handler_for_zend:839 because
+ * SG(request_info).path_translated is an invalid pointer.
+ * It still happens even though I set it to null, so something
+ * weird is going on.
+ */
tsrm_shutdown();
#endif
return FAILURE;
}
}
-#endif /* FORCE_CGI_REDIRECT */
-#if PHP_FASTCGI
if (bindpath) {
fcgi_fd = fcgi_listen(bindpath, 128);
if (fcgi_fd < 0) {
@@ -1535,7 +1669,6 @@ consult the installation file that came with this distribution, or visit \n\
}
fastcgi = fcgi_is_fastcgi();
}
-
if (fastcgi) {
/* How many times to run PHP scripts before dying */
if (getenv("PHP_FCGI_MAX_REQUESTS")) {
@@ -1585,8 +1718,9 @@ consult the installation file that came with this distribution, or visit \n\
act.sa_flags = 0;
act.sa_handler = fastcgi_cleanup;
if (sigaction(SIGTERM, &act, &old_term) ||
- sigaction(SIGINT, &act, &old_int) ||
- sigaction(SIGQUIT, &act, &old_quit)) {
+ sigaction(SIGINT, &act, &old_int) ||
+ sigaction(SIGQUIT, &act, &old_quit)
+ ) {
perror("Can't set signals");
exit(1);
}
@@ -1636,7 +1770,7 @@ consult the installation file that came with this distribution, or visit \n\
break;
} else if (exit_signal) {
break;
- }
+ }
}
if (exit_signal) {
#if 0
@@ -1656,14 +1790,12 @@ consult the installation file that came with this distribution, or visit \n\
#endif /* WIN32 */
}
-#endif /* FASTCGI */
zend_first_try {
- while ((c = php_getopt(argc, argv, OPTIONS, &php_optarg, &php_optind, 1)) != -1) {
+ while ((c = php_getopt(argc, argv, OPTIONS, &php_optarg, &php_optind, 1, 2)) != -1) {
switch (c) {
-#if PHP_FASTCGI
case 'T':
- benchmark = 1;
+ benchmark = 1;
repeats = atoi(php_optarg);
#ifdef HAVE_GETTIMEOFDAY
gettimeofday(&start, NULL);
@@ -1671,12 +1803,9 @@ consult the installation file that came with this distribution, or visit \n\
time(&start);
#endif
break;
-#endif
case 'h':
case '?':
-#if PHP_FASTCGI
fcgi_shutdown();
-#endif
no_headers = 1;
php_output_startup();
php_output_activate(TSRMLS_C);
@@ -1690,392 +1819,343 @@ consult the installation file that came with this distribution, or visit \n\
php_optind = orig_optind;
php_optarg = orig_optarg;
-#if PHP_FASTCGI
/* start of FAST CGI loop */
/* Initialise FastCGI request structure */
#ifdef PHP_WIN32
/* attempt to set security impersonation for fastcgi
- will only happen on NT based OS, others will ignore it. */
+ * will only happen on NT based OS, others will ignore it. */
if (fastcgi && CGIG(impersonate)) {
fcgi_impersonate();
}
#endif
while (!fastcgi || fcgi_accept_request(&request) >= 0) {
-#endif
+ SG(server_context) = (void *) &request;
+ init_request_info(TSRMLS_C);
+ CG(interactive) = 0;
-#if PHP_FASTCGI
- SG(server_context) = (void *) &request;
-#else
- SG(server_context) = (void *) 1; /* avoid server_context==NULL checks */
-#endif
- init_request_info(TSRMLS_C);
- CG(interactive) = 0;
+ if (!cgi && !fastcgi) {
+ while ((c = php_getopt(argc, argv, OPTIONS, &php_optarg, &php_optind, 0, 2)) != -1) {
+ switch (c) {
- if (!cgi
-#if PHP_FASTCGI
- && !fastcgi
-#endif
- ) {
- while ((c = php_getopt(argc, argv, OPTIONS, &php_optarg, &php_optind, 0)) != -1) {
- switch (c) {
+ case 'a': /* interactive mode */
+ printf("Interactive mode enabled\n\n");
+ CG(interactive) = 1;
+ break;
- case 'a': /* interactive mode */
- printf("Interactive mode enabled\n\n");
- CG(interactive) = 1;
- break;
+ case 'C': /* don't chdir to the script directory */
+ SG(options) |= SAPI_OPTION_NO_CHDIR;
+ break;
- case 'C': /* don't chdir to the script directory */
- SG(options) |= SAPI_OPTION_NO_CHDIR;
- break;
+ case 'e': /* enable extended info output */
+ CG(compiler_options) |= ZEND_COMPILE_EXTENDED_INFO;
+ break;
- case 'e': /* enable extended info output */
- CG(extended_info) = 1;
- break;
+ case 'f': /* parse file */
+ if (script_file) {
+ efree(script_file);
+ }
+ script_file = estrdup(php_optarg);
+ no_headers = 1;
+ break;
- case 'f': /* parse file */
- if (script_file) {
- efree(script_file);
- }
- script_file = estrdup(php_optarg);
- no_headers = 1;
- break;
+ case 'i': /* php info & quit */
+ if (script_file) {
+ efree(script_file);
+ }
+ if (php_request_startup(TSRMLS_C) == FAILURE) {
+ SG(server_context) = NULL;
+ php_module_shutdown(TSRMLS_C);
+ return FAILURE;
+ }
+ if (no_headers) {
+ SG(headers_sent) = 1;
+ SG(request_info).no_headers = 1;
+ }
+ php_print_info(0xFFFFFFFF TSRMLS_CC);
+ php_request_shutdown((void *) 0);
+ exit_status = 0;
+ goto out;
+
+ case 'l': /* syntax check mode */
+ no_headers = 1;
+ behavior = PHP_MODE_LINT;
+ break;
- case 'i': /* php info & quit */
- if (script_file) {
- efree(script_file);
- }
- if (php_request_startup(TSRMLS_C) == FAILURE) {
- SG(server_context) = NULL;
- php_module_shutdown(TSRMLS_C);
- return FAILURE;
- }
- if (no_headers) {
+ case 'm': /* list compiled in modules */
+ if (script_file) {
+ efree(script_file);
+ }
+ php_output_startup();
+ php_output_activate(TSRMLS_C);
SG(headers_sent) = 1;
- SG(request_info).no_headers = 1;
- }
- php_print_info(0xFFFFFFFF TSRMLS_CC);
- php_request_shutdown((void *) 0);
- exit_status = 0;
- goto out;
-
- case 'l': /* syntax check mode */
- no_headers = 1;
- behavior = PHP_MODE_LINT;
- break;
-
- case 'm': /* list compiled in modules */
- if (script_file) {
- efree(script_file);
- }
- php_output_startup();
- php_output_activate(TSRMLS_C);
- SG(headers_sent) = 1;
- php_printf("[PHP Modules]\n");
- print_modules(TSRMLS_C);
- php_printf("\n[Zend Modules]\n");
- print_extensions(TSRMLS_C);
- php_printf("\n");
- php_end_ob_buffers(1 TSRMLS_CC);
- exit_status = 0;
- goto out;
+ php_printf("[PHP Modules]\n");
+ print_modules(TSRMLS_C);
+ php_printf("\n[Zend Modules]\n");
+ print_extensions(TSRMLS_C);
+ php_printf("\n");
+ php_end_ob_buffers(1 TSRMLS_CC);
+ exit_status = 0;
+ goto out;
#if 0 /* not yet operational, see also below ... */
- case '': /* generate indented source mode*/
- behavior=PHP_MODE_INDENT;
- break;
+ case '': /* generate indented source mode*/
+ behavior=PHP_MODE_INDENT;
+ break;
#endif
- case 'q': /* do not generate HTTP headers */
- no_headers = 1;
- break;
+ case 'q': /* do not generate HTTP headers */
+ no_headers = 1;
+ break;
- case 'v': /* show php version & quit */
- if (script_file) {
- efree(script_file);
- }
- no_headers = 1;
- if (php_request_startup(TSRMLS_C) == FAILURE) {
- SG(server_context) = NULL;
- php_module_shutdown(TSRMLS_C);
- return FAILURE;
- }
- if (no_headers) {
- SG(headers_sent) = 1;
- SG(request_info).no_headers = 1;
- }
+ case 'v': /* show php version & quit */
+ if (script_file) {
+ efree(script_file);
+ }
+ no_headers = 1;
+ if (php_request_startup(TSRMLS_C) == FAILURE) {
+ SG(server_context) = NULL;
+ php_module_shutdown(TSRMLS_C);
+ return FAILURE;
+ }
+ if (no_headers) {
+ SG(headers_sent) = 1;
+ SG(request_info).no_headers = 1;
+ }
#if ZEND_DEBUG
- php_printf("PHP %s (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2009 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
+ php_printf("PHP %s (%s) (built: %s %s) (DEBUG)\nCopyright (c) 1997-2009 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-2009 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
+ php_printf("PHP %s (%s) (built: %s %s)\nCopyright (c) 1997-2009 The PHP Group\n%s", PHP_VERSION, sapi_module.name, __DATE__, __TIME__, get_zend_version());
#endif
- php_request_shutdown((void *) 0);
- exit_status = 0;
- goto out;
+ php_request_shutdown((void *) 0);
+ exit_status = 0;
+ goto out;
- case 'w':
- behavior = PHP_MODE_STRIP;
- break;
+ case 'w':
+ behavior = PHP_MODE_STRIP;
+ break;
- case 'z': /* load extension file */
- zend_load_extension(php_optarg);
- break;
+ case 'z': /* load extension file */
+ zend_load_extension(php_optarg);
+ break;
- default:
- break;
+ default:
+ break;
+ }
}
- }
- if (script_file) {
- /* override path_translated if -f on command line */
- STR_FREE(SG(request_info).path_translated);
- SG(request_info).path_translated = script_file;
- /* before registering argv to module exchange the *new* argv[0] */
- /* we can achieve this without allocating more memory */
- SG(request_info).argc = argc - (php_optind - 1);
- SG(request_info).argv = &argv[php_optind - 1];
- SG(request_info).argv[0] = script_file;
- } else if (argc > php_optind) {
- /* file is on command line, but not in -f opt */
- STR_FREE(SG(request_info).path_translated);
- SG(request_info).path_translated = estrdup(argv[php_optind]);
- /* arguments after the file are considered script args */
- SG(request_info).argc = argc - php_optind;
- SG(request_info).argv = &argv[php_optind];
- }
-
- if (no_headers) {
- SG(headers_sent) = 1;
- SG(request_info).no_headers = 1;
- }
+ if (script_file) {
+ /* override path_translated if -f on command line */
+ STR_FREE(SG(request_info).path_translated);
+ SG(request_info).path_translated = script_file;
+ /* before registering argv to module exchange the *new* argv[0] */
+ /* we can achieve this without allocating more memory */
+ SG(request_info).argc = argc - (php_optind - 1);
+ SG(request_info).argv = &argv[php_optind - 1];
+ SG(request_info).argv[0] = script_file;
+ } else if (argc > php_optind) {
+ /* file is on command line, but not in -f opt */
+ STR_FREE(SG(request_info).path_translated);
+ SG(request_info).path_translated = estrdup(argv[php_optind]);
+ /* arguments after the file are considered script args */
+ SG(request_info).argc = argc - php_optind;
+ SG(request_info).argv = &argv[php_optind];
+ }
- /* all remaining arguments are part of the query string
- this section of code concatenates all remaining arguments
- into a single string, seperating args with a &
- this allows command lines like:
+ if (no_headers) {
+ SG(headers_sent) = 1;
+ SG(request_info).no_headers = 1;
+ }
- test.php v1=test v2=hello+world!
- test.php "v1=test&v2=hello world!"
- test.php v1=test "v2=hello world!"
- */
- if (!SG(request_info).query_string && argc > php_optind) {
- int slen = strlen(PG(arg_separator).input);
- len = 0;
- for (i = php_optind; i < argc; i++) {
- if (i < (argc - 1)) {
- len += strlen(argv[i]) + slen;
- } else {
- len += strlen(argv[i]);
+ /* all remaining arguments are part of the query string
+ * this section of code concatenates all remaining arguments
+ * into a single string, seperating args with a &
+ * this allows command lines like:
+ *
+ * test.php v1=test v2=hello+world!
+ * test.php "v1=test&v2=hello world!"
+ * test.php v1=test "v2=hello world!"
+ */
+ if (!SG(request_info).query_string && argc > php_optind) {
+ int slen = strlen(PG(arg_separator).input);
+ len = 0;
+ for (i = php_optind; i < argc; i++) {
+ if (i < (argc - 1)) {
+ len += strlen(argv[i]) + slen;
+ } else {
+ len += strlen(argv[i]);
+ }
}
- }
- len += 2;
- s = malloc(len);
- *s = '\0'; /* we are pretending it came from the environment */
- for (i = php_optind; i < argc; i++) {
- strlcat(s, argv[i], len);
- if (i < (argc - 1)) {
- strlcat(s, PG(arg_separator).input, len);
+ len += 2;
+ s = malloc(len);
+ *s = '\0'; /* we are pretending it came from the environment */
+ for (i = php_optind; i < argc; i++) {
+ strlcat(s, argv[i], len);
+ if (i < (argc - 1)) {
+ strlcat(s, PG(arg_separator).input, len);
+ }
}
+ SG(request_info).query_string = s;
+ free_query_string = 1;
}
- SG(request_info).query_string = s;
- free_query_string = 1;
- }
- } /* end !cgi && !fastcgi */
-
- /*
- we never take stdin if we're (f)cgi, always
- rely on the web server giving us the info
- we need in the environment.
- */
- if (SG(request_info).path_translated || cgi
-#if PHP_FASTCGI
- || fastcgi
-#endif
- )
- {
- file_handle.type = ZEND_HANDLE_FILENAME;
- file_handle.filename = SG(request_info).path_translated;
- file_handle.handle.fp = NULL;
- } else {
- file_handle.filename = "-";
- file_handle.type = ZEND_HANDLE_FP;
- file_handle.handle.fp = stdin;
- }
+ } /* end !cgi && !fastcgi */
- file_handle.opened_path = NULL;
- file_handle.free_filename = 0;
-
- /* request startup only after we've done all we can to
- get path_translated */
- if (php_request_startup(TSRMLS_C) == FAILURE) {
-#if PHP_FASTCGI
- if (fastcgi) {
- fcgi_finish_request(&request);
+ /*
+ we never take stdin if we're (f)cgi, always
+ rely on the web server giving us the info
+ we need in the environment.
+ */
+ if (SG(request_info).path_translated || cgi || fastcgi) {
+ file_handle.type = ZEND_HANDLE_FILENAME;
+ file_handle.filename = SG(request_info).path_translated;
+ file_handle.handle.fp = NULL;
+ } else {
+ file_handle.filename = "-";
+ file_handle.type = ZEND_HANDLE_FP;
+ file_handle.handle.fp = stdin;
}
-#endif
- SG(server_context) = NULL;
- php_module_shutdown(TSRMLS_C);
- return FAILURE;
- }
- if (no_headers) {
- SG(headers_sent) = 1;
- SG(request_info).no_headers = 1;
- }
- /*
- at this point path_translated will be set if:
- 1. we are running from shell and got filename was there
- 2. we are running as cgi or fastcgi
- */
- retval = FAILURE;
- if (cgi || SG(request_info).path_translated) {
- if (!php_check_open_basedir(SG(request_info).path_translated TSRMLS_CC)) {
- retval = php_fopen_primary_script(&file_handle TSRMLS_CC);
- }
- }
- /*
- if we are unable to open path_translated and we are not
- running from shell (so fp == NULL), then fail.
- */
- if (retval == FAILURE && file_handle.handle.fp == NULL) {
- zend_try {
- if (errno == EACCES) {
- SG(sapi_headers).http_response_code = 403;
- PUTS("Access denied.\n");
- } else {
- SG(sapi_headers).http_response_code = 404;
- PUTS("No input file specified.\n");
+ file_handle.opened_path = NULL;
+ file_handle.free_filename = 0;
+
+ /* request startup only after we've done all we can to
+ * get path_translated */
+ if (php_request_startup(TSRMLS_C) == FAILURE) {
+ if (fastcgi) {
+ fcgi_finish_request(&request, 1);
}
- } zend_catch {
- } zend_end_try();
-#if PHP_FASTCGI
- /* we want to serve more requests if this is fastcgi
- so cleanup and continue, request shutdown is
- handled later */
- if (fastcgi) {
- goto fastcgi_request_done;
+ SG(server_context) = NULL;
+ php_module_shutdown(TSRMLS_C);
+ return FAILURE;
+ }
+ if (no_headers) {
+ SG(headers_sent) = 1;
+ SG(request_info).no_headers = 1;
}
-#endif
- STR_FREE(SG(request_info).path_translated);
+ /*
+ at this point path_translated will be set if:
+ 1. we are running from shell and got filename was there
+ 2. we are running as cgi or fastcgi
+ */
+ if (cgi || fastcgi || SG(request_info).path_translated) {
+ if (php_fopen_primary_script(&file_handle TSRMLS_CC) == FAILURE) {
+ if (errno == EACCES) {
+ SG(sapi_headers).http_response_code = 403;
+ PUTS("Access denied.\n");
+ } else {
+ SG(sapi_headers).http_response_code = 404;
+ PUTS("No input file specified.\n");
+ }
+ /* we want to serve more requests if this is fastcgi
+ * so cleanup and continue, request shutdown is
+ * handled later */
+ if (fastcgi) {
+ goto fastcgi_request_done;
+ }
- if (free_query_string && SG(request_info).query_string) {
- free(SG(request_info).query_string);
- SG(request_info).query_string = NULL;
- }
+ STR_FREE(SG(request_info).path_translated);
- php_request_shutdown((void *) 0);
- SG(server_context) = NULL;
- php_module_shutdown(TSRMLS_C);
- sapi_shutdown();
+ if (free_query_string && SG(request_info).query_string) {
+ free(SG(request_info).query_string);
+ SG(request_info).query_string = NULL;
+ }
+
+ php_request_shutdown((void *) 0);
+ SG(server_context) = NULL;
+ php_module_shutdown(TSRMLS_C);
+ sapi_shutdown();
#ifdef ZTS
- tsrm_shutdown();
+ tsrm_shutdown();
#endif
- return FAILURE;
- }
-
- if (CGIG(check_shebang_line) && file_handle.handle.fp && (file_handle.handle.fp != stdin)) {
- /* #!php support */
- c = fgetc(file_handle.handle.fp);
- if (c == '#') {
- while (c != '\n' && c != '\r' && c != EOF) {
- c = fgetc(file_handle.handle.fp); /* skip to end of line */
- }
- /* handle situations where line is terminated by \r\n */
- if (c == '\r') {
- if (fgetc(file_handle.handle.fp) != '\n') {
- long pos = ftell(file_handle.handle.fp);
- fseek(file_handle.handle.fp, pos - 1, SEEK_SET);
- }
+ return FAILURE;
}
- CG(start_lineno) = 2;
- } else {
- rewind(file_handle.handle.fp);
}
- }
- switch (behavior) {
- case PHP_MODE_STANDARD:
- php_execute_script(&file_handle TSRMLS_CC);
- break;
- case PHP_MODE_LINT:
- PG(during_request_startup) = 0;
- exit_status = php_lint_script(&file_handle TSRMLS_CC);
- if (exit_status == SUCCESS) {
- zend_printf("No syntax errors detected in %s\n", file_handle.filename);
+ if (CGIG(check_shebang_line) && file_handle.handle.fp && (file_handle.handle.fp != stdin)) {
+ /* #!php support */
+ c = fgetc(file_handle.handle.fp);
+ if (c == '#') {
+ while (c != '\n' && c != '\r' && c != EOF) {
+ c = fgetc(file_handle.handle.fp); /* skip to end of line */
+ }
+ /* handle situations where line is terminated by \r\n */
+ if (c == '\r') {
+ if (fgetc(file_handle.handle.fp) != '\n') {
+ long pos = ftell(file_handle.handle.fp);
+ fseek(file_handle.handle.fp, pos - 1, SEEK_SET);
+ }
+ }
+ CG(start_lineno) = 2;
} else {
- zend_printf("Errors parsing %s\n", file_handle.filename);
- }
- break;
- case PHP_MODE_STRIP:
- if (open_file_for_scanning(&file_handle TSRMLS_CC) == SUCCESS) {
- zend_strip(TSRMLS_C);
- fclose(file_handle.handle.fp);
- php_end_ob_buffers(1 TSRMLS_CC);
+ rewind(file_handle.handle.fp);
}
- return SUCCESS;
- break;
- case PHP_MODE_HIGHLIGHT:
- {
- zend_syntax_highlighter_ini syntax_highlighter_ini;
+ }
+ switch (behavior) {
+ case PHP_MODE_STANDARD:
+ php_execute_script(&file_handle TSRMLS_CC);
+ break;
+ case PHP_MODE_LINT:
+ PG(during_request_startup) = 0;
+ exit_status = php_lint_script(&file_handle TSRMLS_CC);
+ if (exit_status == SUCCESS) {
+ zend_printf("No syntax errors detected in %s\n", file_handle.filename);
+ } else {
+ zend_printf("Errors parsing %s\n", file_handle.filename);
+ }
+ break;
+ case PHP_MODE_STRIP:
if (open_file_for_scanning(&file_handle TSRMLS_CC) == SUCCESS) {
- php_get_highlight_struct(&syntax_highlighter_ini);
- zend_highlight(&syntax_highlighter_ini TSRMLS_CC);
-#if PHP_FASTCGI
- if (fastcgi) {
- goto fastcgi_request_done;
- }
-#endif
- fclose(file_handle.handle.fp);
+ zend_strip(TSRMLS_C);
+ zend_file_handle_dtor(&file_handle TSRMLS_CC);
php_end_ob_buffers(1 TSRMLS_CC);
}
return SUCCESS;
- }
- break;
+ break;
+ case PHP_MODE_HIGHLIGHT:
+ {
+ zend_syntax_highlighter_ini syntax_highlighter_ini;
+
+ if (open_file_for_scanning(&file_handle TSRMLS_CC) == SUCCESS) {
+ php_get_highlight_struct(&syntax_highlighter_ini);
+ zend_highlight(&syntax_highlighter_ini TSRMLS_CC);
+ if (fastcgi) {
+ goto fastcgi_request_done;
+ }
+ zend_file_handle_dtor(&file_handle TSRMLS_CC);
+ php_end_ob_buffers(1 TSRMLS_CC);
+ }
+ return SUCCESS;
+ }
+ break;
#if 0
- /* Zeev might want to do something with this one day */
- case PHP_MODE_INDENT:
- open_file_for_scanning(&file_handle TSRMLS_CC);
- zend_indent();
- fclose(file_handle.handle.fp);
- return SUCCESS;
- break;
+ /* Zeev might want to do something with this one day */
+ case PHP_MODE_INDENT:
+ open_file_for_scanning(&file_handle TSRMLS_CC);
+ zend_indent();
+ zend_file_handle_dtor(&file_handle TSRMLS_CC);
+ return SUCCESS;
+ break;
#endif
- }
+ }
-#if PHP_FASTCGI
fastcgi_request_done:
-#endif
- {
- char *path_translated;
-
- /* Go through this trouble so that the memory manager doesn't warn
- * about SG(request_info).path_translated leaking
- */
- if (SG(request_info).path_translated) {
- path_translated = strdup(SG(request_info).path_translated);
+ {
STR_FREE(SG(request_info).path_translated);
- SG(request_info).path_translated = path_translated;
- }
- php_request_shutdown((void *) 0);
- if (exit_status == 0) {
- exit_status = EG(exit_status);
- }
+ php_request_shutdown((void *) 0);
- if (SG(request_info).path_translated) {
- free(SG(request_info).path_translated);
- SG(request_info).path_translated = NULL;
- }
- if (free_query_string && SG(request_info).query_string) {
- free(SG(request_info).query_string);
- SG(request_info).query_string = NULL;
- }
+ if (exit_status == 0) {
+ exit_status = EG(exit_status);
+ }
- }
+ if (free_query_string && SG(request_info).query_string) {
+ free(SG(request_info).query_string);
+ SG(request_info).query_string = NULL;
+ }
+ }
-#if PHP_FASTCGI
if (!fastcgi) {
if (benchmark) {
repeats--;
@@ -2092,7 +2172,7 @@ fastcgi_request_done:
/* only fastcgi will get here */
requests++;
if (max_requests && (requests == max_requests)) {
- fcgi_finish_request(&request);
+ fcgi_finish_request(&request, 1);
if (bindpath) {
free(bindpath);
}
@@ -2105,7 +2185,6 @@ fastcgi_request_done:
/* end of fastcgi loop */
}
fcgi_shutdown();
-#endif
if (cgi_sapi_module.php_ini_path_override) {
free(cgi_sapi_module.php_ini_path_override);
@@ -2118,7 +2197,6 @@ fastcgi_request_done:
} zend_end_try();
out:
-#if PHP_FASTCGI
if (benchmark) {
int sec;
#ifdef HAVE_GETTIMEOFDAY
@@ -2139,7 +2217,6 @@ out:
fprintf(stderr, "\nElapsed time: %d sec\n", sec);
#endif
}
-#endif
#ifndef PHP_WIN32
parent_out:
@@ -2150,7 +2227,7 @@ parent_out:
sapi_shutdown();
#ifdef ZTS
- /*tsrm_shutdown();*/
+ tsrm_shutdown();
#endif
#if defined(PHP_WIN32) && ZEND_DEBUG && 0
diff --git a/sapi/cgi/config.w32 b/sapi/cgi/config.w32
index 3e36b0e62..1e73e211f 100644
--- a/sapi/cgi/config.w32
+++ b/sapi/cgi/config.w32
@@ -1,26 +1,10 @@
// vim:ft=javascript
-// $Id: config.w32 220680 2006-09-28 09:37:52Z dmitry $
+// $Id: config.w32 243567 2007-10-05 16:00:30Z rrichards $
ARG_ENABLE('cgi', 'Build CGI version of PHP', 'yes');
-ARG_ENABLE('fastcgi', 'Build FastCGI support into CGI binary', 'yes');
-ARG_ENABLE('path-info-check',
- 'If this is disabled, paths such as /info.php/test?a=b will fail to work', 'yes');
-
-ARG_ENABLE("force-cgi-redirect", "Enable the security check for internal \
-server redirects. You should use this if you are running the CGI \
-version with Apache.", "yes");
-
-AC_DEFINE("FORCE_CGI_REDIRECT", PHP_FORCE_CGI_REDIRECT == "yes" ? 1 : 0, "CGI redirect mode");
-AC_DEFINE("ENABLE_PATHINFO_CHECK", PHP_PATH_INFO_CHECK == "yes" ? 1 : 0, "Pathinfo check");
if (PHP_CGI == "yes") {
- AC_DEFINE('PHP_FASTCGI', PHP_FASTCGI == "yes" ? 1 : 0);
ADD_FLAG("LDFLAGS_CGI", "/stack:8388608");
-
- if (PHP_FASTCGI == "yes") {
- SAPI('cgi', 'cgi_main.c getopt.c fastcgi.c', 'php-cgi.exe');
- ADD_FLAG('LIBS_CGI', 'ws2_32.lib kernel32.lib advapi32.lib');
- } else {
- SAPI('cgi', 'cgi_main.c getopt.c', 'php-cgi.exe');
- }
+ SAPI('cgi', 'cgi_main.c fastcgi.c', 'php-cgi.exe');
+ ADD_FLAG('LIBS_CGI', 'ws2_32.lib kernel32.lib advapi32.lib');
}
diff --git a/sapi/cgi/config9.m4 b/sapi/cgi/config9.m4
index 4ff90fdeb..5943c632b 100644
--- a/sapi/cgi/config9.m4
+++ b/sapi/cgi/config9.m4
@@ -1,27 +1,10 @@
dnl
-dnl $Id: config9.m4 239540 2007-07-11 23:20:37Z jani $
+dnl $Id: config9.m4 243300 2007-10-01 12:40:54Z jani $
dnl
PHP_ARG_ENABLE(cgi,,
[ --disable-cgi Disable building CGI version of PHP], yes, no)
-PHP_ARG_ENABLE(fastcgi,,
-[ --enable-fastcgi CGI: Enable FastCGI support in the CGI binary], no, no)
-
-PHP_ARG_ENABLE(force-cgi-redirect,,
-[ --enable-force-cgi-redirect
- CGI: Enable security check for internal server
- redirects. Use this if you run the PHP CGI with Apache], no, no)
-
-PHP_ARG_ENABLE(discard-path,,
-[ --enable-discard-path CGI: When this is enabled the PHP CGI binary can
- safely be placed outside of the web tree and people
- will not be able to circumvent .htaccess security], no, no)
-
-PHP_ARG_ENABLE(path-info-check,,
-[ --disable-path-info-check CGI: If this is disabled, paths such as
- /info.php/test?a=b will fail to work], yes, no)
-
dnl
dnl CGI setup
dnl
@@ -29,6 +12,33 @@ if test "$PHP_SAPI" = "default"; then
AC_MSG_CHECKING(whether to build CGI binary)
if test "$PHP_CGI" != "no"; then
AC_MSG_RESULT(yes)
+
+ AC_MSG_CHECKING([for socklen_t in sys/socket.h])
+ AC_EGREP_HEADER([socklen_t], [sys/socket.h],
+ [AC_MSG_RESULT([yes])
+ AC_DEFINE([HAVE_SOCKLEN_T], [1],
+ [Define if the socklen_t typedef is in sys/socket.h])],
+ AC_MSG_RESULT([no]))
+
+ AC_MSG_CHECKING([for sun_len in sys/un.h])
+ AC_EGREP_HEADER([sun_len], [sys/un.h],
+ [AC_MSG_RESULT([yes])
+ AC_DEFINE([HAVE_SOCKADDR_UN_SUN_LEN], [1],
+ [Define if sockaddr_un in sys/un.h contains a sun_len component])],
+ AC_MSG_RESULT([no]))
+
+ AC_MSG_CHECKING([whether cross-process locking is required by accept()])
+ case "`uname -sr`" in
+ IRIX\ 5.* | SunOS\ 5.* | UNIX_System_V\ 4.0)
+ AC_MSG_RESULT([yes])
+ AC_DEFINE([USE_LOCKING], [1],
+ [Define if cross-process locking is required by accept()])
+ ;;
+ *)
+ AC_MSG_RESULT([no])
+ ;;
+ esac
+
PHP_ADD_MAKEFILE_FRAGMENT($abs_srcdir/sapi/cgi/Makefile.frag)
dnl Set filename
@@ -42,51 +52,9 @@ if test "$PHP_SAPI" = "default"; then
esac
PHP_SUBST(SAPI_CGI_PATH)
- dnl --enable-fastcgi
- AC_MSG_CHECKING(whether to enable fastcgi support)
- if test "$PHP_FASTCGI" = "yes"; then
- PHP_ENABLE_FASTCGI=1
- PHP_FCGI_FILES="fastcgi.c"
- else
- PHP_ENABLE_FASTCGI=0
- PHP_FCGI_FILES=
- fi
- AC_DEFINE_UNQUOTED(PHP_FASTCGI, $PHP_ENABLE_FASTCGI, [ ])
- AC_MSG_RESULT($PHP_FASTCGI)
-
- dnl --enable-force-cgi-redirect
- AC_MSG_CHECKING(whether to force Apache CGI redirect)
- if test "$PHP_FORCE_CGI_REDIRECT" = "yes"; then
- CGI_REDIRECT=1
- else
- CGI_REDIRECT=0
- fi
- AC_DEFINE_UNQUOTED(FORCE_CGI_REDIRECT, $CGI_REDIRECT, [ ])
- AC_MSG_RESULT($PHP_FORCE_CGI_REDIRECT)
-
- dnl --enable-discard-path
- AC_MSG_CHECKING(whether to discard path_info + path_translated)
- if test "$PHP_DISCARD_PATH" = "yes"; then
- DISCARD_PATH=1
- else
- DISCARD_PATH=0
- fi
- AC_DEFINE_UNQUOTED(DISCARD_PATH, $DISCARD_PATH, [ ])
- AC_MSG_RESULT($PHP_DISCARD_PATH)
-
- dnl --enable-path-info-check
- AC_MSG_CHECKING(whether to enable path info checking)
- if test "$PHP_PATH_INFO_CHECK" = "yes"; then
- ENABLE_PATHINFO_CHECK=1
- else
- ENABLE_PATHINFO_CHECK=0
- fi
- AC_DEFINE_UNQUOTED(ENABLE_PATHINFO_CHECK, $ENABLE_PATHINFO_CHECK, [ ])
- AC_MSG_RESULT($PHP_PATH_INFO_CHECK)
-
dnl Set install target and select SAPI
INSTALL_IT="@echo \"Installing PHP CGI binary: \$(INSTALL_ROOT)\$(bindir)/\"; \$(INSTALL) -m 0755 \$(SAPI_CGI_PATH) \$(INSTALL_ROOT)\$(bindir)/\$(program_prefix)php-cgi\$(program_suffix)\$(EXEEXT)"
- PHP_SELECT_SAPI(cgi, program, $PHP_FCGI_FILES cgi_main.c getopt.c,, '$(SAPI_CGI_PATH)')
+ PHP_SELECT_SAPI(cgi, program, cgi_main.c fastcgi.c,, '$(SAPI_CGI_PATH)')
case $host_alias in
*aix*)
diff --git a/sapi/cgi/fastcgi.c b/sapi/cgi/fastcgi.c
index 58d5391b2..156a689c5 100644
--- a/sapi/cgi/fastcgi.c
+++ b/sapi/cgi/fastcgi.c
@@ -16,7 +16,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: fastcgi.c 287776 2009-08-26 19:15:13Z pajoye $ */
+/* $Id: fastcgi.c 287777 2009-08-26 19:17:32Z pajoye $ */
#include "php.h"
#include "fastcgi.h"
@@ -267,63 +267,63 @@ void fcgi_shutdown(void)
*/
static PACL prepare_named_pipe_acl(PSECURITY_DESCRIPTOR sd, LPSECURITY_ATTRIBUTES sa)
{
- DWORD req_acl_size;
- char everyone_buf[32], owner_buf[32];
- PSID sid_everyone, sid_owner;
- SID_IDENTIFIER_AUTHORITY
- siaWorld = SECURITY_WORLD_SID_AUTHORITY,
- siaCreator = SECURITY_CREATOR_SID_AUTHORITY;
- PACL acl;
+ DWORD req_acl_size;
+ char everyone_buf[32], owner_buf[32];
+ PSID sid_everyone, sid_owner;
+ SID_IDENTIFIER_AUTHORITY
+ siaWorld = SECURITY_WORLD_SID_AUTHORITY,
+ siaCreator = SECURITY_CREATOR_SID_AUTHORITY;
+ PACL acl;
- sid_everyone = (PSID)&everyone_buf;
- sid_owner = (PSID)&owner_buf;
+ sid_everyone = (PSID)&everyone_buf;
+ sid_owner = (PSID)&owner_buf;
- req_acl_size = sizeof(ACL) +
- (2 * ((sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD)) + GetSidLengthRequired(1)));
+ req_acl_size = sizeof(ACL) +
+ (2 * ((sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD)) + GetSidLengthRequired(1)));
- acl = malloc(req_acl_size);
+ acl = malloc(req_acl_size);
- if (acl == NULL) {
- return NULL;
- }
+ if (acl == NULL) {
+ return NULL;
+ }
- if (!InitializeSid(sid_everyone, &siaWorld, 1)) {
- goto out_fail;
- }
- *GetSidSubAuthority(sid_everyone, 0) = SECURITY_WORLD_RID;
+ if (!InitializeSid(sid_everyone, &siaWorld, 1)) {
+ goto out_fail;
+ }
+ *GetSidSubAuthority(sid_everyone, 0) = SECURITY_WORLD_RID;
- if (!InitializeSid(sid_owner, &siaCreator, 1)) {
- goto out_fail;
- }
- *GetSidSubAuthority(sid_owner, 0) = SECURITY_CREATOR_OWNER_RID;
+ if (!InitializeSid(sid_owner, &siaCreator, 1)) {
+ goto out_fail;
+ }
+ *GetSidSubAuthority(sid_owner, 0) = SECURITY_CREATOR_OWNER_RID;
- if (!InitializeAcl(acl, req_acl_size, ACL_REVISION)) {
- goto out_fail;
- }
+ if (!InitializeAcl(acl, req_acl_size, ACL_REVISION)) {
+ goto out_fail;
+ }
- if (!AddAccessAllowedAce(acl, ACL_REVISION, FILE_GENERIC_READ | FILE_GENERIC_WRITE, sid_everyone)) {
- goto out_fail;
- }
+ if (!AddAccessAllowedAce(acl, ACL_REVISION, FILE_GENERIC_READ | FILE_GENERIC_WRITE, sid_everyone)) {
+ goto out_fail;
+ }
- if (!AddAccessAllowedAce(acl, ACL_REVISION, FILE_ALL_ACCESS, sid_owner)) {
- goto out_fail;
- }
+ if (!AddAccessAllowedAce(acl, ACL_REVISION, FILE_ALL_ACCESS, sid_owner)) {
+ goto out_fail;
+ }
- if (!InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION)) {
- goto out_fail;
- }
+ if (!InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION)) {
+ goto out_fail;
+ }
- if (!SetSecurityDescriptorDacl(sd, TRUE, acl, FALSE)) {
- goto out_fail;
- }
+ if (!SetSecurityDescriptorDacl(sd, TRUE, acl, FALSE)) {
+ goto out_fail;
+ }
- sa->lpSecurityDescriptor = sd;
+ sa->lpSecurityDescriptor = sd;
- return acl;
+ return acl;
out_fail:
- free(acl);
- return NULL;
+ free(acl);
+ return NULL;
}
#endif
@@ -514,8 +514,8 @@ void fcgi_init_request(fcgi_request *req, int listen_socket)
req->in_len = 0;
req->in_pad = 0;
- req->out_hdr = NULL;
- req->out_pos = req->out_buf;
+ req->out_hdr = NULL;
+ req->out_pos = req->out_buf;
#ifdef _WIN32
req->tcp = !GetNamedPipeInfo((HANDLE)_get_osfhandle(req->listen_socket), NULL, NULL, NULL, NULL);
@@ -634,8 +634,8 @@ static int fcgi_get_params(fcgi_request *req, unsigned char *p, unsigned char *e
}
memcpy(tmp, p, name_len);
tmp[name_len] = 0;
- s = zend_strndup((char*)p + name_len, val_len);
- zend_hash_update(&req->env, tmp, name_len+1, &s, sizeof(char*), NULL);
+ s = estrndup((char*)p + name_len, val_len);
+ zend_hash_update(req->env, tmp, name_len+1, &s, sizeof(char*), NULL);
p += name_len + val_len;
}
if (tmp != buf && tmp != NULL) {
@@ -646,7 +646,7 @@ static int fcgi_get_params(fcgi_request *req, unsigned char *p, unsigned char *e
static void fcgi_free_var(char **s)
{
- free(*s);
+ efree(*s);
}
static int fcgi_read_request(fcgi_request *req)
@@ -656,10 +656,12 @@ static int fcgi_read_request(fcgi_request *req)
unsigned char buf[FCGI_MAX_LENGTH+8];
req->keep = 0;
+ req->closed = 0;
req->in_len = 0;
req->out_hdr = NULL;
req->out_pos = req->out_buf;
- zend_hash_init(&req->env, 0, NULL, (void (*)(void *)) fcgi_free_var, 1);
+ ALLOC_HASHTABLE(req->env);
+ zend_hash_init(req->env, 0, NULL, (void (*)(void *)) fcgi_free_var, 0);
if (safe_read(req, &hdr, sizeof(fcgi_header)) != sizeof(fcgi_header) ||
hdr.version < FCGI_VERSION_1) {
@@ -695,16 +697,16 @@ static int fcgi_read_request(fcgi_request *req)
req->keep = (((fcgi_begin_request*)buf)->flags & FCGI_KEEP_CONN);
switch ((((fcgi_begin_request*)buf)->roleB1 << 8) + ((fcgi_begin_request*)buf)->roleB0) {
case FCGI_RESPONDER:
- val = strdup("RESPONDER");
- zend_hash_update(&req->env, "FCGI_ROLE", sizeof("FCGI_ROLE"), &val, sizeof(char*), NULL);
+ val = estrdup("RESPONDER");
+ zend_hash_update(req->env, "FCGI_ROLE", sizeof("FCGI_ROLE"), &val, sizeof(char*), NULL);
break;
case FCGI_AUTHORIZER:
- val = strdup("AUTHORIZER");
- zend_hash_update(&req->env, "FCGI_ROLE", sizeof("FCGI_ROLE"), &val, sizeof(char*), NULL);
+ val = estrdup("AUTHORIZER");
+ zend_hash_update(req->env, "FCGI_ROLE", sizeof("FCGI_ROLE"), &val, sizeof(char*), NULL);
break;
case FCGI_FILTER:
- val = strdup("FILTER");
- zend_hash_update(&req->env, "FCGI_ROLE", sizeof("FCGI_ROLE"), &val, sizeof(char*), NULL);
+ val = estrdup("FILTER");
+ zend_hash_update(req->env, "FCGI_ROLE", sizeof("FCGI_ROLE"), &val, sizeof(char*), NULL);
break;
default:
return 0;
@@ -760,10 +762,10 @@ static int fcgi_read_request(fcgi_request *req)
return 0;
}
- zend_hash_internal_pointer_reset_ex(&req->env, &pos);
- while ((key_type = zend_hash_get_current_key_ex(&req->env, &str_index, &str_length, &num_index, 0, &pos)) != HASH_KEY_NON_EXISTANT) {
+ zend_hash_internal_pointer_reset_ex(req->env, &pos);
+ while ((key_type = zend_hash_get_current_key_ex(req->env, &str_index, &str_length, &num_index, 0, &pos)) != HASH_KEY_NON_EXISTANT) {
int zlen;
- zend_hash_move_forward_ex(&req->env, &pos);
+ zend_hash_move_forward_ex(req->env, &pos);
if (key_type != HASH_KEY_IS_STRING) {
continue;
}
@@ -865,8 +867,10 @@ int fcgi_read(fcgi_request *req, char *str, int len)
static inline void fcgi_close(fcgi_request *req, int force, int destroy)
{
- if (destroy) {
- zend_hash_destroy(&req->env);
+ if (destroy && req->env) {
+ zend_hash_destroy(req->env);
+ FREE_HASHTABLE(req->env);
+ req->env = NULL;
}
#ifdef _WIN32
@@ -912,7 +916,6 @@ int fcgi_accept_request(fcgi_request *req)
HANDLE pipe;
OVERLAPPED ov;
#endif
- fcgi_finish_request(req);
while (1) {
if (req->fd < 0) {
@@ -957,13 +960,13 @@ int fcgi_accept_request(fcgi_request *req)
int n = 0;
int allowed = 0;
- while (allowed_clients[n] != INADDR_NONE) {
- if (allowed_clients[n] == sa.sa_inet.sin_addr.s_addr) {
- allowed = 1;
- break;
- }
- n++;
- }
+ while (allowed_clients[n] != INADDR_NONE) {
+ if (allowed_clients[n] == sa.sa_inet.sin_addr.s_addr) {
+ allowed = 1;
+ break;
+ }
+ n++;
+ }
if (!allowed) {
fprintf(stderr, "Connection from disallowed IP address '%s' is dropped.\n", inet_ntoa(sa.sa_inet.sin_addr));
closesocket(req->fd);
@@ -1203,13 +1206,18 @@ int fcgi_write(fcgi_request *req, fcgi_request_type type, const char *str, int l
return len;
}
-int fcgi_finish_request(fcgi_request *req)
+int fcgi_finish_request(fcgi_request *req, int force_close)
{
+ int ret = 1;
+
if (req->fd >= 0) {
- fcgi_flush(req, 1);
- fcgi_close(req, 0, 1);
+ if (!req->closed) {
+ ret = fcgi_flush(req, 1);
+ req->closed = 1;
+ }
+ fcgi_close(req, force_close, 1);
}
- return 1;
+ return ret;
}
char* fcgi_getenv(fcgi_request *req, const char* var, int var_len)
@@ -1218,7 +1226,7 @@ char* fcgi_getenv(fcgi_request *req, const char* var, int var_len)
if (!req) return NULL;
- if (zend_hash_find(&req->env, (char*)var, var_len+1, (void**)&val) == SUCCESS) {
+ if (zend_hash_find(req->env, (char*)var, var_len+1, (void**)&val) == SUCCESS) {
return *val;
}
return NULL;
@@ -1228,12 +1236,12 @@ char* fcgi_putenv(fcgi_request *req, char* var, int var_len, char* val)
{
if (var && req) {
if (val == NULL) {
- zend_hash_del(&req->env, var, var_len+1);
+ zend_hash_del(req->env, var, var_len+1);
} else {
char **ret;
- val = strdup(val);
- if (zend_hash_update(&req->env, var, var_len+1, &val, sizeof(char*), (void**)&ret) == SUCCESS) {
+ val = estrdup(val);
+ if (zend_hash_update(req->env, var, var_len+1, &val, sizeof(char*), (void**)&ret) == SUCCESS) {
return *ret;
}
}
@@ -1253,7 +1261,7 @@ void fcgi_impersonate(void)
}
#endif
-void fcgi_set_mgmt_var(char * name, size_t name_len, const char * value, size_t value_len)
+void fcgi_set_mgmt_var(const char * name, size_t name_len, const char * value, size_t value_len)
{
zval * zvalue;
zvalue = pemalloc(sizeof(*zvalue), 1);
diff --git a/sapi/cgi/fastcgi.h b/sapi/cgi/fastcgi.h
index cfb3641cd..c4f62b8da 100644
--- a/sapi/cgi/fastcgi.h
+++ b/sapi/cgi/fastcgi.h
@@ -16,7 +16,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: fastcgi.h 272374 2008-12-31 11:17:49Z sebastian $ */
+/* $Id: fastcgi.h 272370 2008-12-31 11:15:49Z sebastian $ */
/* FastCGI protocol */
@@ -99,6 +99,7 @@ typedef struct _fcgi_request {
int fd;
int id;
int keep;
+ int closed;
int in_len;
int in_pad;
@@ -108,7 +109,7 @@ typedef struct _fcgi_request {
unsigned char out_buf[1024*8];
unsigned char reserved[sizeof(fcgi_end_request_rec)];
- HashTable env;
+ HashTable *env;
} fcgi_request;
int fcgi_init(void);
@@ -118,7 +119,7 @@ int fcgi_in_shutdown(void);
int fcgi_listen(const char *path, int backlog);
void fcgi_init_request(fcgi_request *req, int listen_socket);
int fcgi_accept_request(fcgi_request *req);
-int fcgi_finish_request(fcgi_request *req);
+int fcgi_finish_request(fcgi_request *req, int force_close);
char* fcgi_getenv(fcgi_request *req, const char* var, int var_len);
char* fcgi_putenv(fcgi_request *req, char* var, int var_len, char* val);
@@ -132,7 +133,7 @@ int fcgi_flush(fcgi_request *req, int close);
void fcgi_impersonate(void);
#endif
-void fcgi_set_mgmt_var(char * name, size_t name_len, const char * value, size_t value_len);
+void fcgi_set_mgmt_var(const char * name, size_t name_len, const char * value, size_t value_len);
void fcgi_free_mgmt_var_cb(void * ptr);
/*
diff --git a/sapi/cgi/getopt.c b/sapi/cgi/getopt.c
deleted file mode 100644
index b103e316a..000000000
--- a/sapi/cgi/getopt.c
+++ /dev/null
@@ -1,164 +0,0 @@
-/*
- +----------------------------------------------------------------------+
- | PHP Version 5 |
- +----------------------------------------------------------------------+
- | Copyright (c) 1997-2009 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 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: Marcus Boerger <helly@php.net> |
- +----------------------------------------------------------------------+
-*/
-
-/* $Id: getopt.c 272374 2008-12-31 11:17:49Z sebastian $ */
-
-#include <stdio.h>
-#include <string.h>
-#include <assert.h>
-#include <stdlib.h>
-#include "php_getopt.h"
-#define OPTERRCOLON (1)
-#define OPTERRNF (2)
-#define OPTERRARG (3)
-
-
-static int php_opt_error(int argc, char * const *argv, int oint, int optchr, int err, int show_err)
-{
- if (show_err)
- {
- fprintf(stderr, "Error in argument %d, char %d: ", oint, optchr+1);
- switch(err)
- {
- case OPTERRCOLON:
- fprintf(stderr, ": in flags\n");
- break;
- case OPTERRNF:
- fprintf(stderr, "option not found %c\n", argv[oint][optchr]);
- break;
- case OPTERRARG:
- fprintf(stderr, "no argument for option %c\n", argv[oint][optchr]);
- break;
- default:
- fprintf(stderr, "unknown\n");
- break;
- }
- }
- return('?');
-}
-
-int php_getopt(int argc, char* const *argv, const opt_struct opts[], char **optarg, int *optind, int show_err)
-{
- static int optchr = 0;
- static int dash = 0; /* have already seen the - */
- int arg_start = 2;
-
- int opts_idx = -1;
-
- if (*optind >= argc) {
- return(EOF);
- }
- if (!dash) {
- if ((argv[*optind][0] != '-')) {
- return(EOF);
- } else {
- if (!argv[*optind][1])
- {
- /*
- * use to specify stdin. Need to let pgm process this and
- * the following args
- */
- return(EOF);
- }
- }
- }
- if ((argv[*optind][0] == '-') && (argv[*optind][1] == '-')) {
- /* '--' indicates end of args if not followed by a known long option name */
- if (argv[*optind][2] == '\0') {
- (*optind)++;
- return(EOF);
- }
-
- while (1) {
- opts_idx++;
- if (opts[opts_idx].opt_char == '-') {
- (*optind)++;
- return(php_opt_error(argc, argv, *optind-1, optchr, OPTERRARG, show_err));
- } else if (opts[opts_idx].opt_name && !strcmp(&argv[*optind][2], opts[opts_idx].opt_name)) {
- break;
- }
- }
- optchr = 0;
- dash = 0;
- arg_start = 2 + strlen(opts[opts_idx].opt_name);
- } else {
- if (!dash) {
- dash = 1;
- optchr = 1;
- }
- /* Check if the guy tries to do a -: kind of flag */
- if (argv[*optind][optchr] == ':') {
- dash = 0;
- (*optind)++;
- return (php_opt_error(argc, argv, *optind-1, optchr, OPTERRCOLON, show_err));
- }
- arg_start = 1 + optchr;
- }
- if (opts_idx < 0) {
- while (1) {
- opts_idx++;
- if (opts[opts_idx].opt_char == '-') {
- int errind = *optind;
- int errchr = optchr;
-
- if (!argv[*optind][optchr+1]) {
- dash = 0;
- (*optind)++;
- } else {
- optchr++;
- arg_start++;
- }
- return(php_opt_error(argc, argv, errind, errchr, OPTERRNF, show_err));
- } else if (argv[*optind][optchr] == opts[opts_idx].opt_char) {
- break;
- }
- }
- }
- if (opts[opts_idx].need_param) {
- /* Check for cases where the value of the argument
- is in the form -<arg> <val> or in the form -<arg><val> */
- dash = 0;
- if(!argv[*optind][arg_start]) {
- (*optind)++;
- if (*optind == argc) {
- return(php_opt_error(argc, argv, *optind-1, optchr, OPTERRARG, show_err));
- }
- *optarg = argv[(*optind)++];
- } else {
- *optarg = &argv[*optind][arg_start];
- (*optind)++;
- }
- return opts[opts_idx].opt_char;
- } else {
- /* multiple options specified as one (exclude long opts) */
- if (arg_start >= 2 && !((argv[*optind][0] == '-') && (argv[*optind][1] == '-'))) {
- if (!argv[*optind][optchr+1])
- {
- dash = 0;
- (*optind)++;
- } else {
- optchr++;
- }
- } else {
- (*optind)++;
- }
- return opts[opts_idx].opt_char;
- }
- assert(0);
- return(0); /* never reached */
-}
diff --git a/sapi/cgi/php_getopt.h b/sapi/cgi/php_getopt.h
deleted file mode 100644
index eb4743d42..000000000
--- a/sapi/cgi/php_getopt.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- +----------------------------------------------------------------------+
- | PHP Version 5 |
- +----------------------------------------------------------------------+
- | Copyright (c) 1997-2009 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 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: Marcus Boerger <helly@php.net> |
- +----------------------------------------------------------------------+
-*/
-
-/* $Id: php_getopt.h 272374 2008-12-31 11:17:49Z sebastian $ */
-
-#include "php.h"
-
-#ifdef NETWARE
-/*
-As NetWare LibC has optind and optarg macros defined in unistd.h our local variables were getting mistakenly preprocessed so undeffing optind and optarg
-*/
-#undef optarg
-#undef optind
-#endif
-/* Define structure for one recognized option (both single char and long name).
- * If short_open is '-' this is the last option.
- */
-typedef struct _opt_struct {
- const char opt_char;
- const int need_param;
- const char * opt_name;
-} opt_struct;
-
-int php_getopt(int argc, char* const *argv, const opt_struct opts[], char **optarg, int *optind, int show_err);
diff --git a/sapi/cgi/tests/002.phpt b/sapi/cgi/tests/002.phpt
index 66e2424f2..884e6521e 100644
--- a/sapi/cgi/tests/002.phpt
+++ b/sapi/cgi/tests/002.phpt
@@ -29,24 +29,24 @@ echo "Done\n";
?>
--EXPECTF--
string(%d) "X-Powered-By: PHP/%s
-Content-type: text/html
+Content-type: text/html%r; charset=.*|%r
-string(3) "111"
+%unicode|string%(3) "111"
"
string(%d) "X-Powered-By: PHP/%s
-Content-type: text/html
+Content-type: text/html%r; charset=.*|%r
-string(3) "500"
+%unicode|string%(3) "500"
"
string(%d) "X-Powered-By: PHP/%s
-Content-type: text/html
+Content-type: text/html%r; charset=.*|%r
-string(3) "555"
+%unicode|string%(3) "555"
"
string(%d) "X-Powered-By: PHP/%s
-Content-type: text/html
+Content-type: text/html%r; charset=.*|%r
-string(3) "555"
-string(10) "/test/path"
+%unicode|string%(3) "555"
+%unicode|string%(10) "/test/path"
"
Done
diff --git a/sapi/cgi/tests/003.phpt b/sapi/cgi/tests/003.phpt
index ea418d104..533743323 100644
--- a/sapi/cgi/tests/003.phpt
+++ b/sapi/cgi/tests/003.phpt
@@ -42,7 +42,7 @@ echo "Done\n";
?>
--EXPECTF--
string(%d) "X-Powered-By: PHP/%s
-Content-type: text/html
+Content-type: text/html%r; charset=.*|%r
<?php
@@ -50,12 +50,12 @@ Content-type: text/html
"
string(%d) "Status: 404 Not Found
X-Powered-By: PHP/%s
-Content-type: text/html
+Content-type: text/html%r; charset=.*|%r
No input file specified.
"
string(%d) "X-Powered-By: PHP/%s
-Content-type: text/html
+Content-type: text/html%r; charset=.*|%r
<?php class test { function foo() {} } ?>
"
diff --git a/sapi/cgi/tests/007.phpt b/sapi/cgi/tests/007.phpt
index 92bf0f6aa..f2c9c0226 100644
--- a/sapi/cgi/tests/007.phpt
+++ b/sapi/cgi/tests/007.phpt
@@ -12,11 +12,11 @@ reset_env_vars();
var_dump(`"$php" -n -f some.php -f some.php`);
var_dump(`"$php" -n -s -w -l`);
-echo "Done\n";
?>
+===DONE===
--EXPECTF--
string(25) "No input file specified.
"
string(31) "No syntax errors detected in -
"
-Done
+===DONE===
diff --git a/sapi/cgi/tests/008.phpt b/sapi/cgi/tests/008.phpt
index 40140e879..7537664cc 100644
--- a/sapi/cgi/tests/008.phpt
+++ b/sapi/cgi/tests/008.phpt
@@ -39,7 +39,7 @@ echo "Done\n";
?>
--EXPECTF--
string(%d) "X-Powered-By: PHP/%s
-Content-type: text/html
+Content-type: text/html%r; charset=.*|%r
<code><span style="color: #000000">
<br /><span style="color: #0000BB">&lt;?php<br />$test&nbsp;</span><span style="color: #007700">=&nbsp;</span><span style="color: #DD0000">"var"</span><span style="color: #007700">;&nbsp;</span><span style="color: #FF8000">//var<br />/*&nbsp;test&nbsp;class&nbsp;*/<br /></span><span style="color: #007700">class&nbsp;</span><span style="color: #0000BB">test&nbsp;</span><span style="color: #007700">{<br />&nbsp;&nbsp;&nbsp;&nbsp;private&nbsp;</span><span style="color: #0000BB">$var&nbsp;</span><span style="color: #007700">=&nbsp;array();<br /><br />&nbsp;&nbsp;&nbsp;&nbsp;public&nbsp;static&nbsp;function&nbsp;</span><span style="color: #0000BB">foo</span><span style="color: #007700">(</span><span style="color: #0000BB">Test&nbsp;$arg</span><span style="color: #007700">)&nbsp;{<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;echo&nbsp;</span><span style="color: #DD0000">"hello"</span><span style="color: #007700">;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(</span><span style="color: #0000BB">$this</span><span style="color: #007700">);<br />&nbsp;&nbsp;&nbsp;&nbsp;}<br />}<br /><br /></span><span style="color: #0000BB">$o&nbsp;</span><span style="color: #007700">=&nbsp;new&nbsp;</span><span style="color: #0000BB">test</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">?&gt;<br /></span>
@@ -47,7 +47,7 @@ Content-type: text/html
</code>"
string(%d) "Status: 404 Not Found
X-Powered-By: PHP/%s
-Content-type: text/html
+Content-type: text/html%r; charset=.*|%r
No input file specified.
"
diff --git a/sapi/cgi/tests/009.phpt b/sapi/cgi/tests/009.phpt
index 1c429ac19..c8e9ae1af 100644
--- a/sapi/cgi/tests/009.phpt
+++ b/sapi/cgi/tests/009.phpt
@@ -24,7 +24,7 @@ echo "Done\n";
?>
--EXPECTF--
X-Powered-By: PHP/%s
-Content-type: text/html
+Content-type: text/html%r; charset=.*|%r
string(%d) "%s/x"
Done
diff --git a/sapi/cgi/tests/011.phpt b/sapi/cgi/tests/011.phpt
new file mode 100644
index 000000000..177df021a
--- /dev/null
+++ b/sapi/cgi/tests/011.phpt
@@ -0,0 +1,165 @@
+--TEST--
+header_remove()
+--SKIPIF--
+<?php include "skipif.inc"; ?>
+--FILE--
+<?php
+
+include "include.inc";
+
+$php = get_cgi_path();
+reset_env_vars();
+
+$f = tempnam(sys_get_temp_dir(), 'cgitest');
+
+function test($script) {
+ file_put_contents($GLOBALS['f'], $script);
+ $cmd = escapeshellcmd($GLOBALS['php']);
+ $cmd .= ' -n -dreport_zend_debug=0 -dhtml_errors=0 ' . escapeshellarg($GLOBALS['f']);
+ echo "----------\n";
+ echo rtrim($script) . "\n";
+ echo "----------\n";
+ passthru($cmd);
+}
+
+test('<?php ?>');
+test('<?php header_remove(); ?>');
+test('<?php header_remove("X-Foo"); ?>');
+test('<?php
+header("X-Foo: Bar");
+?>');
+test('<?php
+header("X-Foo: Bar");
+header("X-Bar: Baz");
+header_remove("X-Foo");
+?>');
+test('<?php
+header("X-Foo: Bar");
+header_remove("X-Foo: Bar");
+?>');
+test('<?php
+header("X-Foo: Bar");
+header_remove("X-Foo:");
+?>');
+test('<?php
+header("X-Foo: Bar");
+header_remove();
+?>');
+test('<?php
+header_remove("");
+?>');
+test('<?php
+header_remove(":");
+?>');
+test('<?php
+header("X-Foo: Bar");
+echo "flush\n";
+flush();
+header_remove("X-Foo");
+?>');
+
+@unlink($f);
+?>
+--EXPECTF--
+----------
+<?php ?>
+----------
+X-Powered-By: PHP/%s
+Content-type: text/html
+
+----------
+<?php header_remove(); ?>
+----------
+Content-type: text/html
+
+----------
+<?php header_remove("X-Foo"); ?>
+----------
+X-Powered-By: PHP/%s
+Content-type: text/html
+
+----------
+<?php
+header("X-Foo: Bar");
+?>
+----------
+X-Powered-By: PHP/%s
+X-Foo: Bar
+Content-type: text/html
+
+----------
+<?php
+header("X-Foo: Bar");
+header("X-Bar: Baz");
+header_remove("X-Foo");
+?>
+----------
+X-Powered-By: PHP/%s
+X-Bar: Baz
+Content-type: text/html
+
+----------
+<?php
+header("X-Foo: Bar");
+header_remove("X-Foo: Bar");
+?>
+----------
+X-Powered-By: PHP/%s
+X-Foo: Bar
+Content-type: text/html
+
+
+Warning: Header to delete may not contain colon. in %s on line 3
+----------
+<?php
+header("X-Foo: Bar");
+header_remove("X-Foo:");
+?>
+----------
+X-Powered-By: PHP/%s
+X-Foo: Bar
+Content-type: text/html
+
+
+Warning: Header to delete may not contain colon. in %s on line 3
+----------
+<?php
+header("X-Foo: Bar");
+header_remove();
+?>
+----------
+Content-type: text/html
+
+----------
+<?php
+header_remove("");
+?>
+----------
+X-Powered-By: PHP/%s
+Content-type: text/html
+
+----------
+<?php
+header_remove(":");
+?>
+----------
+X-Powered-By: PHP/%s
+Content-type: text/html
+
+
+Warning: Header to delete may not contain colon. in %s on line 2
+----------
+<?php
+header("X-Foo: Bar");
+echo "flush\n";
+flush();
+header_remove("X-Foo");
+?>
+----------
+X-Powered-By: PHP/%s
+X-Foo: Bar
+Content-type: text/html
+
+flush
+
+Warning: Cannot modify header information - headers already sent by (output started at %s:3) in %s on line 5