shane Sun Dec 1 16:37:14 2002 EDT
Modified files:
/php4/main config.w32.h.in win95nt.h
/php4/sapi/cgi cgi_main.c
/php4/sapi/cgi/libfcgi fcgiapp.c
/php4/sapi/cgi/libfcgi/include fcgiapp.h
Log:
Fix CGI to match cgi spec.
This patch properly fixes support for CGI in PHP. For backwards compatible
broken behaviour, cgi.fix_pathinfo can be set to zero in php.ini.
CGI failed to work under apache at all, either using the cgi-script directive
or as a ScriptAlias setup. Typicaly it would try to parse itself. This will
still happen if you dissable fix_pathinfo, and set DISCARD_PATH.
This also fixes PATH_INFO, and finally we can run pres2 under cgi or fastcgi.
This patch has been tested under Apache 1.3, 2.0, IIS, as both cgi and fastcgi,
on Windows and OSX. A followup patch with build stuff for linux will follow.
Index: php4/main/config.w32.h.in
diff -u php4/main/config.w32.h.in:1.23 php4/main/config.w32.h.in:1.24
--- php4/main/config.w32.h.in:1.23 Wed Nov 13 16:28:16 2002
+++ php4/main/config.w32.h.in Sun Dec 1 16:37:13 2002
@@ -2,7 +2,7 @@
Build Configuration for Win32.
This has only been tested with MS VisualC++ 6 (and later).
- $Id: config.w32.h.in,v 1.23 2002/11/13 21:28:16 edink Exp $
+ $Id: config.w32.h.in,v 1.24 2002/12/01 21:37:13 shane Exp $
*/
/* Default PHP / PEAR directories */
@@ -42,13 +42,13 @@
#define HAVE_FTP 1
/* Enable / Disable MBSTRING extension (default: disabled) */
-/* #define HAVE_MBSTRING 0 */
-/* #define HAVE_MBREGEX 0 */
-/* #define HAVE_MBSTR_CN 0 */
-/* #define HAVE_MBSTR_JA 0 */
-/* #define HAVE_MBSTR_KR 0 */
-/* #define HAVE_MBSTR_RU 0 */
-/* #define HAVE_MBSTR_TW 0 */
+#define HAVE_MBSTRING 0
+#define HAVE_MBREGEX 0
+#define HAVE_MBSTR_CN 0
+#define HAVE_MBSTR_JA 0
+#define HAVE_MBSTR_KR 0
+#define HAVE_MBSTR_RU 0
+#define HAVE_MBSTR_TW 0
/* Enable / Disable MySQL extension (default: enabled) */
#define HAVE_MYSQL 1
@@ -82,6 +82,7 @@
#define MAGIC_QUOTES 0
#define USE_CONFIG_FILE 1
#define DEFAULT_SHORT_OPEN_TAG "1"
+#define ENABLE_PATHINFO_CHECK 1
/* Platform-Specific Configuration. Should not be changed. */
#define PHP_SIGCHILD 0
Index: php4/main/win95nt.h
diff -u php4/main/win95nt.h:1.14 php4/main/win95nt.h:1.15
--- php4/main/win95nt.h:1.14 Wed Aug 14 20:41:35 2002
+++ php4/main/win95nt.h Sun Dec 1 16:37:13 2002
@@ -18,6 +18,9 @@
#define S_IFIFO _IFIFO
#define S_IFBLK _IFBLK
#define S_IFLNK _IFLNK
+#ifndef S_ISREG
+#define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
+#endif
#define chdir(path) SetCurrentDirectory(path)
#define mkdir(a, b) _mkdir(a)
#define rmdir(a) _rmdir(a)
Index: php4/sapi/cgi/cgi_main.c
diff -u php4/sapi/cgi/cgi_main.c:1.198 php4/sapi/cgi/cgi_main.c:1.199
--- php4/sapi/cgi/cgi_main.c:1.198 Tue Nov 26 00:57:03 2002
+++ php4/sapi/cgi/cgi_main.c Sun Dec 1 16:37:13 2002
@@ -119,6 +119,24 @@
extern char *ap_php_optarg;
extern int ap_php_optind;
+#if ENABLE_PATHINFO_CHECK
+/* true global. this is retreived once only, even for fastcgi */
+int fix_pathinfo=1;
+#endif
+
+#ifdef PHP_WIN32
+#define TRANSLATE_SLASHES(path) \
+ { \
+ char *tmp = path; \
+ while (*tmp) { \
+ if (*tmp == '\\') *tmp = '/'; \
+ tmp++; \
+ } \
+ }
+#else
+#define TRANSLATE_SLASHES(path)
+#endif
+
#define OPTSTRING "aCc:d:ef:g:hilmnqsw?vz:"
static int print_module_info(zend_module_entry *module, void *arg TSRMLS_DC)
@@ -330,14 +348,8 @@
of a request. So we have to do our own lookup to get env
vars. This could probably be faster somehow. */
if (!FCGX_IsCGI()) {
- int cgi_env_size = 0;
FCGX_Request *request = (FCGX_Request *)SG(server_context);
- while( request->envp[ cgi_env_size ] ) {
- if (strncasecmp(name,request->envp[cgi_env_size],name_len) ==
0) {
- return (request->envp[cgi_env_size])+name_len+1;
- }
- cgi_env_size++;
- }
+ return FCGX_GetParam(name,request->envp);
}
#endif
/* if cgi, or fastcgi and not found in fcgi env
@@ -345,9 +357,40 @@
return getenv(name);
}
+static int _sapi_cgibin_putenv(char *name, char *value TSRMLS_DC)
+{
+ int len=0;
+ char *buf = NULL;
+ if (!name) return -1;
+ len = strlen(name) + (value?strlen(value):0) + sizeof("=") + 2;
+ buf = (char *)emalloc(len);
+ if (value) {
+ snprintf(buf,len-1,"%s=%s", name, value);
+ } else {
+ snprintf(buf,len-1,"%s=", 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. */
+ if (!FCGX_IsCGI()) {
+ FCGX_Request *request = (FCGX_Request *)SG(server_context);
+ FCGX_PutEnv(request,buf);
+ efree(buf);
+ return 0;
+ }
+#endif
+ /* if cgi, or fastcgi and not found in fcgi env
+ check the regular environment */
+ putenv(buf);
+ efree(buf);
+ return 0;
+}
+
static char *sapi_cgi_read_cookies(TSRMLS_D)
{
- return sapi_cgibin_getenv((char *)"HTTP_COOKIE",strlen("HTTP_COOKIE")
TSRMLS_CC);
+ return sapi_cgibin_getenv((char *)"HTTP_COOKIE",0 TSRMLS_CC);
}
#if PHP_FASTCGI
@@ -491,62 +534,218 @@
*/
static void init_request_info(TSRMLS_D)
{
- char *content_length =
sapi_cgibin_getenv("CONTENT_LENGTH",strlen("CONTENT_LENGTH") TSRMLS_CC);
- char *content_type = sapi_cgibin_getenv("CONTENT_TYPE",strlen("CONTENT_TYPE")
TSRMLS_CC);
+ char *content_length = sapi_cgibin_getenv("CONTENT_LENGTH",0 TSRMLS_CC);
+ char *content_type = sapi_cgibin_getenv("CONTENT_TYPE",0 TSRMLS_CC);
const char *auth;
+ char *env_path_translated;
-#if 0
-/* SG(request_info).path_translated is always set to NULL at the end of this function
- call so why the hell did this code exist in the first place? Am I missing
something? */
- char *script_filename;
+ SG(request_info).path_translated = NULL;
+ /*
+ * If for some reason the CGI interface is not setting the
+ * PATH_TRANSLATED correctly, SG(request_info).path_translated is NULL.
+ * We still call php_fopen_primary_script, because if you set doc_root
+ * or user_dir configuration directives, SCRIPT_NAME is used to construct
+ * the filename as a side effect of php_fopen_primary_script.
+ *
+ * Fixup path stuff to conform to CGI spec
+ *
+ * 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
+ *
+ * cgi/mod_fastcgi under apache produce:
+ *
+ * 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
+ *
+ */
+ env_path_translated = sapi_cgibin_getenv("PATH_TRANSLATED",0 TSRMLS_CC);
- script_filename =
sapi_cgibin_getenv("SCRIPT_FILENAME",strlen("SCRIPT_FILENAME") TSRMLS_CC);
- /* Hack for annoying servers that do not set SCRIPT_FILENAME for us */
- if (!script_filename) {
- script_filename = SG(request_info).argv0;
- }
-#ifdef PHP_WIN32
- /* FIXME WHEN APACHE NT IS FIXED */
- /* a hack for apache nt because it does not appear to set argv[1] and sets
- script filename to php.exe thus makes us parse php.exe instead of file.php
- requires we get the info from path translated. This can be removed at
- such a time that apache nt is fixed */
- if (!script_filename) {
- script_filename =
sapi_cgibin_getenv("PATH_TRANSLATED",strlen("PATH_TRANSLATED") TSRMLS_CC);
- }
+ if(env_path_translated) {
+#ifdef __riscos__
+ /* Convert path to unix format*/
+ __riscosify_control|=__RISCOSIFY_DONT_CHECK_DIR;
+ env_path_translated=__unixify(env_path_translated,0,NULL,1,0);
#endif
+
+#if ENABLE_PATHINFO_CHECK
+ /*
+ * if the file doesn't exist, try to extract PATH_INFO out
+ * of it by stat'ing back through the '/'
+ * this fixes url's like /info.php/test
+ *
+ * ini cgi.fix_pathinfo is on by default, but can be turned off
+ * if someone is running a server that does this correctly
+ */
+ if (fix_pathinfo) {
+ struct stat st;
+ char *env_script_name = sapi_cgibin_getenv("SCRIPT_NAME",0
+TSRMLS_CC);
+ char *env_path_info = sapi_cgibin_getenv("PATH_INFO",0
+TSRMLS_CC);
+ if (env_path_info) env_path_info = estrdup(env_path_info);
+ if (sapi_cgibin_getenv("REDIRECT_URL",0 TSRMLS_CC) ||
+ (env_script_name && env_path_info &&
+ strcmp(env_path_info,env_script_name)==0)) {
+ /*
+ * if PHP is setup under a ScriptAlias in Apache, the
+ * redirect_url variable will be set. In this case,
+script_*
+ * points to the executable, not the script. We have
+to
+ * reset this stuff and clear PATH_INFO since it is
+also wrong.
+ * This unfortunately is Apache specific. IIS sets
+PATH_INFO
+ * and SCRIPT_NAME to the same thing if there is no
+*real* PATH_INFO.
+ */
+
+_sapi_cgibin_putenv("SCRIPT_FILENAME",env_path_translated TSRMLS_CC);
+ _sapi_cgibin_putenv("PATH_INFO",NULL TSRMLS_CC);
+ }
- /* doc_root configuration variable is currently ignored,
- as it is with every other access method currently also. */
-
- /* We always need to emalloc() filename, since it gets placed into
- the include file hash table, and gets freed with that table.
- Notice that this means that we don't need to efree() it in
- php_destroy_request_info()! */
+ if (stat( env_path_translated, &st ) == -1 ) {
+ char *pt = estrdup(env_path_translated);
+ int len = strlen(pt);
+ char *ptr;
+
+ while( (ptr = strrchr(pt,'/')) || (ptr =
+strrchr(pt,'\\')) ) {
+ *ptr = 0;
+ if ( lstat(pt, &st) == 0 &&
+S_ISREG(st.st_mode) ) {
+ /*
+ * okay, we found the base script!
+ * work out how many chars we had to
+strip off;
+ * then we can modify PATH_INFO
+ * accordingly
+ *
+ * we now have the makings of
+ * PATH_INFO=/test
+ * SCRIPT_FILENAME=/docroot/info.php
+ *
+ * we now need to figure out what
+docroot is.
+ * if DOCUMENT_ROOT is set, this is
+easy, otherwise,
+ * we have to play the game of hide
+and seek to figure
+ * out what SCRIPT_NAME should be
+ */
+ char *env_document_root =
+sapi_cgibin_getenv("DOCUMENT_ROOT",0 TSRMLS_CC);
+ int slen = len - strlen(pt);
+ int pilen = strlen( env_path_info );
+ char *path_info = env_path_info +
+pilen - slen;
+
+
+_sapi_cgibin_putenv("PATH_INFO",path_info TSRMLS_CC);
+
+_sapi_cgibin_putenv("SCRIPT_FILENAME",pt TSRMLS_CC);
+ TRANSLATE_SLASHES(pt);
+
+ /* figure out docroot
+ SCRIPT_FILENAME minus SCRIPT_NAME
+ */
+ if (!env_document_root)
+ env_document_root =
+PG(doc_root);
+ if (env_document_root) {
+ int l =
+strlen(env_document_root);
+ int path_translated_len = 0;
+ char *path_translated = NULL;
+
+ /* we have docroot, so we
+should have:
+ * DOCUMENT_ROOT=/docroot
+ *
+SCRIPT_FILENAME=/docroot/info.php
+ *
+ * SCRIPT_NAME is the portion
+of the path beyond docroot
+ */
+
+_sapi_cgibin_putenv("SCRIPT_NAME",pt+l TSRMLS_CC);
+
+ /*
+ * PATH_TRANSATED =
+DOCUMENT_ROOT + PATH_INFO
+ */
+ path_translated_len = l +
+strlen(path_info) + 2;
+ path_translated = (char
+*)emalloc(path_translated_len);
+ *path_translated = 0;
+
+strcat(path_translated,env_document_root);
+
+strcat(path_translated,path_info);
+
+_sapi_cgibin_putenv("PATH_TRANSLATED",path_translated TSRMLS_CC);
+ efree(path_translated);
+ } else if (env_script_name &&
+ strstr(pt,env_script_name)) {
+ /*
+ * PATH_TRANSATED =
+PATH_TRANSATED - SCRIPT_NAME + PATH_INFO
+ */
+ int ptlen =
+strlen(pt)-strlen(env_script_name);
+ int path_translated_len =
+ptlen + strlen(path_info) + 2;
+ char *path_translated = NULL;
+ path_translated = (char
+*)emalloc(path_translated_len);
+ *path_translated = 0;
+
+strncat(path_translated,pt,ptlen);
+
+strcat(path_translated,path_info);
+
+_sapi_cgibin_putenv("PATH_TRANSLATED",path_translated TSRMLS_CC);
+ efree(path_translated);
+ }
+ break;
+ }
+ }
+ if (pt) efree(pt);
+ /*
+ * if we stripped out all the '/' and still didn't find
+ * a valid path... we will fail, badly. of course we
+would
+ * have failed anyway... is there a nice way to error?
+ */
+ }
+ if (env_path_info) efree(env_path_info);
+ } else
+#endif
+ {
+ /* old broken logic here, but at least reverts to
+ * previous behaviour if the fixup is ignored, or there
+ * is a working server.
+ *
+ * 1. DISCARD_PATH IS BAD
+ * 2. PATH_INFO will never be right
+ */
#if DISCARD_PATH
- if (script_filename) {
- SG(request_info).path_translated = estrdup(script_filename);
- } else {
- SG(request_info).path_translated = NULL;
- }
+ env_path_translated = sapi_cgibin_getenv("SCRIPT_FILENAME",0
+TSRMLS_CC);
+#else
+ env_path_translated = sapi_cgibin_getenv("PATH_TRANSLATED",0
+TSRMLS_CC);
#endif
+ SG(request_info).path_translated = env_path_translated;
+ }
+ }
-#endif /* 0 */
+ SG(request_info).request_method = sapi_cgibin_getenv("REQUEST_METHOD",0
+TSRMLS_CC);
+ SG(request_info).query_string = sapi_cgibin_getenv("QUERY_STRING",0 TSRMLS_CC);
+ SG(request_info).request_uri = sapi_cgibin_getenv("SCRIPT_NAME",0 TSRMLS_CC);
- SG(request_info).request_method =
sapi_cgibin_getenv("REQUEST_METHOD",strlen("REQUEST_METHOD") TSRMLS_CC);
- SG(request_info).query_string =
sapi_cgibin_getenv("QUERY_STRING",strlen("QUERY_STRING") TSRMLS_CC);
- SG(request_info).request_uri =
sapi_cgibin_getenv("PATH_INFO",strlen("PATH_INFO") TSRMLS_CC);
if (!SG(request_info).request_uri) {
- SG(request_info).request_uri =
sapi_cgibin_getenv("SCRIPT_NAME",strlen("SCRIPT_NAME") TSRMLS_CC);
+ /* this is old logic, and completely incorrect by CGI spec
+ * this is used to generate PHP_SELF, which should actually
+ * match SCRIPT_NAME. This is being left so PHP will be as broken
+ * as it was before if a server does not set SCRIPT_NAME.
+ */
+ SG(request_info).request_uri = sapi_cgibin_getenv("PATH_INFO",0
+TSRMLS_CC);
+ }
+ if (!SG(request_info).path_translated) {
+ /* if this didn't get set above, do it now, default to script_filename
+*/
+ SG(request_info).path_translated =
+sapi_cgibin_getenv("SCRIPT_FILENAME",0 TSRMLS_CC);
+ }
+ if (!SG(request_info).path_translated) {
+ /* server didn't set script_filename, default to path_translated */
+ SG(request_info).path_translated =
+sapi_cgibin_getenv("PATH_TRANSLATED",0 TSRMLS_CC);
}
- SG(request_info).path_translated = NULL; /* we have to update it later, when
we have that information */
+ if (SG(request_info).path_translated)
+ SG(request_info).path_translated =
+estrdup(SG(request_info).path_translated);
SG(request_info).content_type = (content_type ? content_type : "" );
SG(request_info).content_length = (content_length?atoi(content_length):0);
SG(sapi_headers).http_response_code = 200;
/* The CGI RFC allows servers to pass on unvalidated Authorization data */
- auth = sapi_cgibin_getenv("HTTP_AUTHORIZATION",strlen("HTTP_AUTHORIZATION")
TSRMLS_CC);
+ auth = sapi_cgibin_getenv("HTTP_AUTHORIZATION",0 TSRMLS_CC);
php_handle_auth_data(auth TSRMLS_CC);
}
/* }}} */
@@ -623,7 +822,6 @@
char *script_file=NULL;
zend_llist global_vars;
int interactive=0;
-
#if FORCE_CGI_REDIRECT
int force_redirect = 1;
char *redirect_status_env = NULL;
@@ -663,7 +861,6 @@
#endif
#endif
-
#ifdef ZTS
tsrm_startup(1, 1, 0, NULL);
#endif
@@ -794,6 +991,12 @@
}
#endif /* FORCE_CGI_REDIRECT */
+#if ENABLE_PATHINFO_CHECK
+ if (cfg_get_long("cgi.fix_pathinfo", &fix_pathinfo) == FAILURE) {
+ fix_pathinfo = 1;
+ }
+#endif
+
#if PHP_FASTCGI
if (bindpath) {
/* Pass on the arg to the FastCGI library, with one exception.
@@ -962,12 +1165,15 @@
#else
SG(server_context) = (void *) 1; /* avoid server_context==NULL checks
*/
#endif
+
init_request_info(TSRMLS_C);
SG(request_info).argv0 = argv0;
zend_llist_init(&global_vars, sizeof(char *), NULL, 0);
+ CG(interactive) = 0;
+
if (!cgi
#if PHP_FASTCGI
&& !fastcgi
@@ -1104,15 +1310,7 @@
break;
}
}
- } /* not cgi */
-
- CG(interactive) = interactive;
- if (!cgi
-#if PHP_FASTCGI
- && !fastcgi
-#endif
- ) {
if (!SG(request_info).query_string) {
len = 0;
if (script_file) {
@@ -1138,21 +1336,23 @@
}
SG(request_info).query_string = s;
}
- }
- if (script_file) {
- SG(request_info).path_translated = script_file;
- }
+ if (script_file) {
+ /* override path_translated if -f on command line */
+ SG(request_info).path_translated = script_file;
+ }
- if (php_request_startup(TSRMLS_C)==FAILURE) {
- php_module_shutdown(TSRMLS_C);
- return FAILURE;
- }
+ if (no_headers) {
+ SG(headers_sent) = 1;
+ SG(request_info).no_headers = 1;
+ }
- if (no_headers) {
- SG(headers_sent) = 1;
- SG(request_info).no_headers = 1;
+ if (!SG(request_info).path_translated && argc > ap_php_optind)
+{
+ /* file is on command line, but not in -f opt */
+ SG(request_info).path_translated =
+estrdup(argv[ap_php_optind]);
+ }
}
+
#if PHP_FASTCGI
if (fastcgi) {
file_handle.type = ZEND_HANDLE_FILENAME;
@@ -1168,41 +1368,17 @@
file_handle.opened_path = NULL;
file_handle.free_filename = 0;
- /* This actually destructs the elements of the list - ugly hack */
- zend_llist_apply(&global_vars, (llist_apply_func_t)
php_register_command_line_global_vars TSRMLS_CC);
- zend_llist_destroy(&global_vars);
-
- if (!cgi
-#if PHP_FASTCGI
- && !fastcgi
-#endif
- ) {
- if (!SG(request_info).path_translated && argc > ap_php_optind)
{
- SG(request_info).path_translated =
estrdup(argv[ap_php_optind]);
- }
- } else {
- /* If for some reason the CGI interface is not setting the
- PATH_TRANSLATED correctly, SG(request_info).path_translated is NULL.
- We still call php_fopen_primary_script, because if you set doc_root
- or user_dir configuration directives, PATH_INFO is used to construct
- the filename as a side effect of php_fopen_primary_script.
- */
- char *env_path_translated=NULL;
-#if DISCARD_PATH
- env_path_translated =
sapi_cgibin_getenv("SCRIPT_FILENAME",strlen("SCRIPT_FILENAME") TSRMLS_CC);
-#else
- env_path_translated =
sapi_cgibin_getenv("PATH_TRANSLATED",strlen("PATH_TRANSLATED") TSRMLS_CC);
-#endif
+ /* request startup only after we've done all we can to
+ get path_translated */
+ if (php_request_startup(TSRMLS_C)==FAILURE) {
+ php_module_shutdown(TSRMLS_C);
+ return FAILURE;
+ }
- if(env_path_translated) {
-#ifdef __riscos__
- /* Convert path to unix format*/
- __riscosify_control|=__RISCOSIFY_DONT_CHECK_DIR;
-
env_path_translated=__unixify(env_path_translated,0,NULL,1,0);
-#endif
- SG(request_info).path_translated =
estrdup(env_path_translated);
- }
- }
+ /* This actually destructs the elements of the list - ugly hack */
+ zend_llist_apply(&global_vars, (llist_apply_func_t)
+php_register_command_line_global_vars TSRMLS_CC);
+ zend_llist_destroy(&global_vars);
+
if (cgi || SG(request_info).path_translated) {
retval = php_fopen_primary_script(&file_handle TSRMLS_CC);
}
@@ -1216,7 +1392,7 @@
}
file_handle.filename = argv0;
file_handle.opened_path = expand_filepath(argv0, NULL
TSRMLS_CC);
- }
+ }
if (file_handle.handle.fp && (file_handle.handle.fp != stdin)) {
/* #!php support */
@@ -1291,6 +1467,7 @@
if (SG(request_info).path_translated) {
free(SG(request_info).path_translated);
+ SG(request_info).path_translated = NULL;
}
}
Index: php4/sapi/cgi/libfcgi/fcgiapp.c
diff -u php4/sapi/cgi/libfcgi/fcgiapp.c:1.2 php4/sapi/cgi/libfcgi/fcgiapp.c:1.3
--- php4/sapi/cgi/libfcgi/fcgiapp.c:1.2 Tue Nov 26 00:51:15 2002
+++ php4/sapi/cgi/libfcgi/fcgiapp.c Sun Dec 1 16:37:13 2002
@@ -11,7 +11,7 @@
*
*/
#ifndef lint
-static const char rcsid[] = "$Id: fcgiapp.c,v 1.2 2002/11/26 05:51:15 shane Exp $";
+static const char rcsid[] = "$Id: fcgiapp.c,v 1.3 2002/12/01 21:37:13 shane Exp $";
#endif /* not lint */
#include <assert.h>
@@ -980,24 +980,7 @@
*/
}
-/*
- *======================================================================
- * Parameters
- *======================================================================
- */
-/*
- * A vector of pointers representing the parameters received
- * by a FastCGI application server, with the vector's length
- * and last valid element so adding new parameters is efficient.
- */
-
-typedef struct Params {
- FCGX_ParamArray vec; /* vector of strings */
- int length; /* number of string vec can hold */
- char **cur; /* current item in vec; *cur == NULL */
-} Params;
-typedef Params *ParamsPtr;
/*
*----------------------------------------------------------------------
@@ -1071,13 +1054,45 @@
*paramsPtr->cur++ = nameValue;
size = paramsPtr->cur - paramsPtr->vec;
if(size >= paramsPtr->length) {
- paramsPtr->length *= 2;
- paramsPtr->vec = (FCGX_ParamArray)realloc(paramsPtr->vec, paramsPtr->length *
sizeof(char *));
- paramsPtr->cur = paramsPtr->vec + size;
+ paramsPtr->length *= 2;
+ paramsPtr->vec = (FCGX_ParamArray)realloc(paramsPtr->vec, paramsPtr->length *
+sizeof(char *));
+ paramsPtr->cur = paramsPtr->vec + size;
}
*paramsPtr->cur = NULL;
}
+
+void FCGX_PutEnv(FCGX_Request *request, char *var)
+{
+ char *nameValue;
+ char *e, **p;
+ int len;
+
+ if (!strchr(var,'=')) {
+ return;
+ }
+ nameValue = StringCopy(var);
+ e = strchr(nameValue,'=');
+ *e = 0;
+
+ /* find the name and replace it */
+ len = strlen(nameValue);
+
+ for (p = request->envp; p && *p; ++p) {
+ if((strncmp(nameValue, *p, len) == 0) && ((*p)[len] == '=')) {
+ free(*p);
+ *e = '=';
+ *p = nameValue;
+ return;
+ }
+ }
+ *e = '=';
+ /* this is a new var, add it to the environment */
+ PutParam(request->paramsPtr,nameValue);
+ request->envp = request->paramsPtr->vec;
+}
+
+
/*
*----------------------------------------------------------------------
*
@@ -1100,7 +1115,7 @@
len = strlen(name);
- for (p = envp; *p; ++p) {
+ for (p = envp; p && *p; ++p) {
if((strncmp(name, *p, len) == 0) && ((*p)[len] == '=')) {
return *p+len+1;
}
@@ -2027,6 +2042,7 @@
_FCGX_FreeStream(&request->out, FALSE);
_FCGX_FreeStream(&request->err, FALSE);
FreeParams(&request->paramsPtr);
+ request->envp = NULL;
if (close) {
OS_IpcClose(request->ipcFd);
Index: php4/sapi/cgi/libfcgi/include/fcgiapp.h
diff -u php4/sapi/cgi/libfcgi/include/fcgiapp.h:1.1
php4/sapi/cgi/libfcgi/include/fcgiapp.h:1.2
--- php4/sapi/cgi/libfcgi/include/fcgiapp.h:1.1 Sun Mar 10 16:39:28 2002
+++ php4/sapi/cgi/libfcgi/include/fcgiapp.h Sun Dec 1 16:37:14 2002
@@ -9,7 +9,7 @@
* See the file "LICENSE.TERMS" for information on usage and redistribution
* of this file, and for a DISCLAIMER OF ALL WARRANTIES.
*
- * $Id: fcgiapp.h,v 1.1 2002/03/10 21:39:28 shane Exp $
+ * $Id: fcgiapp.h,v 1.2 2002/12/01 21:37:14 shane Exp $
*/
#ifndef _FCGIAPP_H
@@ -80,6 +80,19 @@
typedef char **FCGX_ParamArray;
/*
+ * A vector of pointers representing the parameters received
+ * by a FastCGI application server, with the vector's length
+ * and last valid element so adding new parameters is efficient.
+ */
+
+typedef struct Params {
+ FCGX_ParamArray vec; /* vector of strings */
+ int length; /* number of string vec can hold */
+ char **cur; /* current item in vec; *cur == NULL */
+} Params;
+typedef Params *ParamsPtr;
+
+/*
* FCGX_Request Flags
*
* Setting FCGI_FAIL_ACCEPT_ON_INTR prevents FCGX_Accept() from
@@ -98,11 +111,11 @@
FCGX_Stream *in;
FCGX_Stream *out;
FCGX_Stream *err;
- char **envp;
+ FCGX_ParamArray envp;
/* Don't use anything below here */
- struct Params *paramsPtr;
+ ParamsPtr paramsPtr;
int ipcFd; /* < 0 means no connection */
int isBeginProcessed; /* FCGI_BEGIN_REQUEST seen */
int keepConnection; /* don't close ipcFd at end of request */
@@ -351,7 +364,8 @@
*----------------------------------------------------------------------
*/
DLLAPI char *FCGX_GetParam(const char *name, FCGX_ParamArray envp);
-
+DLLAPI void FCGX_PutEnv(FCGX_Request *request, char *nameValue);
+
/*
*======================================================================
* Readers
@@ -533,7 +547,7 @@
*----------------------------------------------------------------------
*/
DLLAPI int FCGX_FFlush(FCGX_Stream *stream);
-
+
/*
*======================================================================
* Both Readers and Writers
--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php