dmitry          Mon May 15 14:30:50 2006 UTC

  Modified files:              
    /php-src/sapi/cgi   cgi_main.c fastcgi.c fastcgi.h 
  Log:
  - Removed source compatibility with libfcgi
  - Optimized access to FastCGI environment using HashTable instead of linear 
sear
  ch
  - Allowed PHP_FCGI_MAX_REQUESTS=0 to disable PHP die
  - Allowed PHP_FCGI_CHILDREN=0 to disable PHP spawn workers
  
  
http://cvs.php.net/viewcvs.cgi/php-src/sapi/cgi/cgi_main.c?r1=1.286&r2=1.287&diff_format=u
Index: php-src/sapi/cgi/cgi_main.c
diff -u php-src/sapi/cgi/cgi_main.c:1.286 php-src/sapi/cgi/cgi_main.c:1.287
--- php-src/sapi/cgi/cgi_main.c:1.286   Wed May  3 19:40:49 2006
+++ php-src/sapi/cgi/cgi_main.c Mon May 15 14:30:50 2006
@@ -17,10 +17,11 @@
    |          Zeev Suraski <[EMAIL PROTECTED]>                                |
    | FastCGI: Ben Mansell <[EMAIL PROTECTED]>                           |
    |          Shane Caraveo <[EMAIL PROTECTED]>                           |
+   |          Dmitry Stogov <[EMAIL PROTECTED]>                             |
    +----------------------------------------------------------------------+
 */
 
-/* $Id: cgi_main.c,v 1.286 2006/05/03 19:40:49 tony2001 Exp $ */
+/* $Id: cgi_main.c,v 1.287 2006/05/15 14:30:50 dmitry Exp $ */
 
 #include "php.h"
 #include "php_globals.h"
@@ -81,9 +82,7 @@
 
 #include "fastcgi.h"
 
-#ifdef PHP_WIN32
-extern int OS_SetImpersonate(void);
-#else
+#ifndef PHP_WIN32
 /* XXX this will need to change later when threaded fastcgi is
    implemented.  shane */
 struct sigaction act, old_term, old_quit, old_int;
@@ -227,9 +226,9 @@
        size_t ret;
 #endif
 
-       if (!FCGX_IsCGI()) {
-               FCGX_Request *request = (FCGX_Request *) SG(server_context);
-               long ret = FCGX_PutStr(str, str_length, request->out);
+       if (fcgi_is_fastcgi()) {
+               fcgi_request *request = (fcgi_request*) SG(server_context);
+               long ret = fcgi_write(request, FCGI_STDOUT, str, str_length);
                if (ret <= 0) {
                        return 0;
                }
@@ -268,13 +267,13 @@
 
 static void sapi_cgibin_flush(void *server_context)
 {
-       if (!FCGX_IsCGI()) {
-               FCGX_Request *request = (FCGX_Request *) server_context;
+       if (fcgi_is_fastcgi()) {
+               fcgi_request *request = (fcgi_request*) server_context;
                if (
 #ifndef PHP_WIN32
                !parent && 
 #endif
-               request && FCGX_FFlush(request->out) == -1) {
+               request && fcgi_flush(request, 0) == -1) {
                        php_handle_aborted_connection();
                }
                return;
@@ -337,9 +336,9 @@
 
        count_bytes = MIN(count_bytes, (uint) SG(request_info).content_length - 
SG(read_post_bytes));
        while (read_bytes < count_bytes) {
-               if (!FCGX_IsCGI()) {
-                       FCGX_Request *request = (FCGX_Request *) 
SG(server_context);
-                       tmp_read_bytes = FCGX_GetStr(pos, count_bytes - 
read_bytes, request->in);
+               if (fcgi_is_fastcgi()) {
+                       fcgi_request *request = (fcgi_request*) 
SG(server_context);
+                       tmp_read_bytes = fcgi_read(request, pos, count_bytes - 
read_bytes);
                        pos += tmp_read_bytes;
                } else {
                        tmp_read_bytes = read(0, buffer + read_bytes, 
count_bytes - read_bytes);
@@ -358,9 +357,9 @@
           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);
-               return FCGX_GetParam(name,request->envp);
+       if (fcgi_is_fastcgi()) {
+               fcgi_request *request = (fcgi_request*) SG(server_context);
+               return fcgi_getenv(request, name, name_len);
        }
        /*  if cgi, or fastcgi and not found in fcgi env
                check the regular environment */
@@ -369,43 +368,46 @@
 
 static char *_sapi_cgibin_putenv(char *name, char *value TSRMLS_DC)
 {
-       int len = 0;
-       char *buf = NULL;
+       int name_len;
+       int len;
+       char *buf;
+
        if (!name) {
                return NULL;
        }
-       len = strlen(name) + (value ? strlen(value) : 0) + sizeof("=") + 2;
-       buf = (char *) malloc(len);
-       if (buf == NULL) {
-               return getenv(name);
-       }
-       if (value) {
-               snprintf(buf, len - 1, "%s=%s", name, value);
-       } else {
-               snprintf(buf, len - 1, "%s=", name);
-       }
+       name_len = strlen(name);
+
        /* 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);
-               free(buf);
-               return sapi_cgibin_getenv(name,0 TSRMLS_CC);
+       if (fcgi_is_fastcgi()) {
+               fcgi_request *request = (fcgi_request*) SG(server_context);
+               return fcgi_putenv(request, name, name_len, value);
        }
+
        /*  if cgi, or fastcgi and not found in fcgi env
                check the regular environment 
                this leaks, but it's only cgi anyway, we'll fix
                it for 5.0
        */
+       len = name_len + (value ? strlen(value) : 0) + sizeof("=") + 2;
+       buf = (char *) malloc(len);
+       if (buf == NULL) {
+               return getenv(name);
+       }
+       if (value) {
+               len = snprintf(buf, len - 1, "%s=%s", name, value);
+       } else {
+               len = snprintf(buf, len - 1, "%s=", name);
+       }
        putenv(buf);
        return getenv(name);
 }
 
 static char *sapi_cgi_read_cookies(TSRMLS_D)
 {
-       return sapi_cgibin_getenv((char *) "HTTP_COOKIE", 0 TSRMLS_CC);
+       return sapi_cgibin_getenv((char *) "HTTP_COOKIE", 
sizeof("HTTP_COOKIE")-1 TSRMLS_CC);
 }
 
 void cgi_php_import_environment_variables(zval *array_ptr TSRMLS_DC)
@@ -425,18 +427,19 @@
            zval_copy_ctor(array_ptr);
            return;
        }
-       if (!FCGX_IsCGI()) {
-               FCGX_Request *request = (FCGX_Request *) SG(server_context);
-               char **env, *p;
-
-               for (env = request->envp; env != NULL && *env != NULL; env++) {
-                       p = strchr(*env, '=');
-                       if (!p) {                               /* malformed 
entry? */
-                               continue;
-                       }
-                       *p = 0;
-                       php_register_variable(*env, p + 1, array_ptr TSRMLS_CC);
-                       *p = '=';
+       if (fcgi_is_fastcgi()) {
+               fcgi_request *request = (fcgi_request*) SG(server_context);
+               HashPosition pos;
+               zstr var;
+               uint var_len;
+               char **val;
+               ulong idx;
+
+               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)) {
+                       php_register_variable(var.s, *val, array_ptr TSRMLS_CC);
                }
        }
        /* call php's original import as a catch-all */
@@ -455,12 +458,21 @@
 
 static void sapi_cgi_log_message(char *message)
 {
-       if (!FCGX_IsCGI() && fcgi_logging) {
+       if (fcgi_is_fastcgi() && fcgi_logging) {
+               fcgi_request *request;
                TSRMLS_FETCH();
-
-               FCGX_Request *request = (FCGX_Request *) SG(server_context);
-               if (request) {
-                       FCGX_FPrintF(request->err, "%s\n", message);
+               
+               request = (fcgi_request*) SG(server_context);
+               if (request) {                  
+                       int len = strlen(message);
+                       char *buf = malloc(len+2);
+
+                       memcpy(buf, message, len);
+                       memcpy(buf + len, "\n", sizeof("\n"));
+                       fcgi_write(request, FCGI_STDERR, buf, len+1);
+                       free(buf);
+               } else {
+                       fprintf(stderr, "%s\n", message);
                }
                /* ignore return code */
        } else {
@@ -635,8 +647,8 @@
  */
 static void init_request_info(TSRMLS_D)
 {
-       char *env_script_filename = sapi_cgibin_getenv("SCRIPT_FILENAME", 0 
TSRMLS_CC);
-       char *env_path_translated = sapi_cgibin_getenv("PATH_TRANSLATED", 0 
TSRMLS_CC);
+       char *env_script_filename = sapi_cgibin_getenv("SCRIPT_FILENAME", 
sizeof("SCRIPT_FILENAME")-1 TSRMLS_CC);
+       char *env_path_translated = sapi_cgibin_getenv("PATH_TRANSLATED", 
sizeof("PATH_TRANSLATED")-1 TSRMLS_CC);
        char *script_path_translated = env_script_filename;
 
        /* some broken servers do not have script_filename or argv0
@@ -662,15 +674,15 @@
           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", 0 
TSRMLS_CC);
-               char *content_type = sapi_cgibin_getenv("CONTENT_TYPE", 0 
TSRMLS_CC);
-               char *env_path_info = sapi_cgibin_getenv("PATH_INFO", 0 
TSRMLS_CC);
-               char *env_script_name = sapi_cgibin_getenv("SCRIPT_NAME", 0 
TSRMLS_CC);
+               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 (fix_pathinfo) {
                        struct stat st;
-                       char *env_redirect_url = 
sapi_cgibin_getenv("REDIRECT_URL", 0 TSRMLS_CC);
-                       char *env_document_root = 
sapi_cgibin_getenv("DOCUMENT_ROOT", 0 TSRMLS_CC);
+                       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);
 
                        /* save the originals first for anything we change 
later */
                        if (env_path_translated) {
@@ -818,7 +830,7 @@
                                _sapi_cgibin_putenv("PATH_INFO", NULL 
TSRMLS_CC);
                                _sapi_cgibin_putenv("PATH_TRANSLATED", NULL 
TSRMLS_CC);
                        }
-                       SG(request_info).request_uri = 
sapi_cgibin_getenv("SCRIPT_NAME",0 TSRMLS_CC);
+                       SG(request_info).request_uri = 
sapi_cgibin_getenv("SCRIPT_NAME", sizeof("SCRIPT_NAME")-1 TSRMLS_CC);
                } else {
                        /* pre 4.3 behaviour, shouldn't be used but provides BC 
*/
                        if (env_path_info) {
@@ -831,9 +843,9 @@
                        }
                }
 
-               SG(request_info).request_method = 
sapi_cgibin_getenv("REQUEST_METHOD", 0 TSRMLS_CC);
+               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", 0 TSRMLS_CC);
+               SG(request_info).query_string = 
sapi_cgibin_getenv("QUERY_STRING", sizeof("REQUEST_METHOD")-1 TSRMLS_CC);
                /* some server configurations allow '..' to slip through in the
                   translated path.   We'll just refuse to handle such a path. 
*/
                if (script_path_translated && !strstr(script_path_translated, 
"..")) {
@@ -843,7 +855,7 @@
                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",0 TSRMLS_CC);
+               auth = sapi_cgibin_getenv("HTTP_AUTHORIZATION", 
sizeof("HTTP_AUTHORIZATION")-1 TSRMLS_CC);
                php_handle_auth_data(auth TSRMLS_CC);
        }
 }
@@ -926,12 +938,12 @@
 
        int max_requests = 500;
        int requests = 0;
-       int fastcgi = !FCGX_IsCGI();
+       int fastcgi = fcgi_is_fastcgi();
 #ifndef PHP_WIN32
        char *bindpath = NULL;
 #endif
        int fcgi_fd = 0;
-       FCGX_Request request;
+       fcgi_request request;
 #ifdef PHP_WIN32
        long impersonate = 0;
 #else
@@ -1124,14 +1136,10 @@
        /* for windows, socket listening is broken in the fastcgi library itself
           so dissabling this feature on windows till time is available to fix 
it */
        if (bindpath) {
-               /* this must be done to make FCGX_OpenSocket work correctly 
-                  bug 23664 */
-               close(0);
                /* Pass on the arg to the FastCGI library, with one exception.
                 * If just a port is specified, then we prepend a ':' onto the
                 * path (it's what the fastcgi library expects)
-                */
-               
+                */             
                if (strchr(bindpath, ':') == NULL && is_port_number(bindpath)) {
                        char *tmp;
 
@@ -1139,10 +1147,10 @@
                        tmp[0] = ':';
                        memcpy(tmp + 1, bindpath, strlen(bindpath) + 1);
 
-                       fcgi_fd = FCGX_OpenSocket(tmp, 128);
+                       fcgi_fd = fcgi_listen(tmp, 128);
                        free(tmp);
                } else {
-                       fcgi_fd = FCGX_OpenSocket(bindpath, 128);
+                       fcgi_fd = fcgi_listen(bindpath, 128);
                }
                if (fcgi_fd < 0) {
                        fprintf(stderr, "Couldn't create FastCGI listen socket 
on port %s\n", bindpath);
@@ -1151,14 +1159,14 @@
 #endif
                        return FAILURE;
                }
-               fastcgi = !FCGX_IsCGI();
+               fastcgi = fcgi_is_fastcgi();
        }
 #endif
        if (fastcgi) {
                /* How many times to run PHP scripts before dying */
                if (getenv("PHP_FCGI_MAX_REQUESTS")) {
                        max_requests = atoi(getenv("PHP_FCGI_MAX_REQUESTS"));
-                       if (!max_requests) {
+                       if (max_requests < 0) {
                                fprintf(stderr, "PHP_FCGI_MAX_REQUESTS is not 
valid\n");
                                return FAILURE;
                        }
@@ -1169,14 +1177,13 @@
                php_import_environment_variables = 
cgi_php_import_environment_variables;
 
                /* library is already initialized, now init our request */
-               FCGX_Init();
-               FCGX_InitRequest(&request, fcgi_fd, 0);
+               fcgi_init_request(&request, fcgi_fd);
 
 #ifndef PHP_WIN32
        /* Pre-fork, if required */
        if (getenv("PHP_FCGI_CHILDREN")) {
                children = atoi(getenv("PHP_FCGI_CHILDREN"));
-               if (!children) {
+               if (children < 0) {
                        fprintf(stderr, "PHP_FCGI_CHILDREN is not valid\n");
                        return FAILURE;
                }
@@ -1276,10 +1283,10 @@
                        if (cfg_get_long("fastcgi.impersonate", &impersonate) 
== FAILURE) {
                                impersonate = 0;
                        }
-                       if (impersonate) OS_SetImpersonate();
+                       if (impersonate) fcgi_impersonate();
                }
 #endif
-               while (!fastcgi || FCGX_Accept_r(&request) >= 0) {
+               while (!fastcgi || fcgi_accept_request(&request) >= 0) {
                        SG(server_context) = (void *) &request;
                        init_request_info(TSRMLS_C);
                        zend_llist_init(&global_vars, sizeof(char *), NULL, 0);
@@ -1474,7 +1481,7 @@
                           get path_translated */
                        if (php_request_startup(TSRMLS_C) == FAILURE) {
                                if (fastcgi) {
-                                       FCGX_Finish_r(&request);
+                                       fcgi_finish_request(&request);
                                }
                                php_module_shutdown(TSRMLS_C);
                                return FAILURE;
@@ -1607,7 +1614,7 @@
                        /* only fastcgi will get here */
                        requests++;
                        if (max_requests && (requests == max_requests)) {
-                               FCGX_Finish_r(&request);
+                               fcgi_finish_request(&request);
 #ifndef PHP_WIN32
                                if (bindpath) {
                                        free(bindpath);
http://cvs.php.net/viewcvs.cgi/php-src/sapi/cgi/fastcgi.c?r1=1.15&r2=1.16&diff_format=u
Index: php-src/sapi/cgi/fastcgi.c
diff -u php-src/sapi/cgi/fastcgi.c:1.15 php-src/sapi/cgi/fastcgi.c:1.16
--- php-src/sapi/cgi/fastcgi.c:1.15     Tue May  9 22:00:36 2006
+++ php-src/sapi/cgi/fastcgi.c  Mon May 15 14:30:50 2006
@@ -16,10 +16,10 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: fastcgi.c,v 1.15 2006/05/09 22:00:36 iliaa Exp $ */
+/* $Id: fastcgi.c,v 1.16 2006/05/15 14:30:50 dmitry Exp $ */
 
-#include "fastcgi.h"
 #include "php.h"
+#include "fastcgi.h"
 
 #include <string.h>
 #include <stdlib.h>
@@ -125,14 +125,15 @@
 } sa_t;
 
 typedef struct _fcgi_mgmt_rec {
-       char* name;
-       char  val;
+       char*  name;
+       size_t name_len;
+       char   val;
 } fcgi_mgmt_rec;
 
 static const fcgi_mgmt_rec fcgi_mgmt_vars[] = {
-       {"FCGI_MAX_CONNS",  1},
-       {"FCGI_MAX_REQS",   1},
-       {"FCGI_MPXS_CONNS", 0}
+       {"FCGI_MAX_CONNS",  sizeof("FCGI_MAX_CONNS")-1,  1},
+       {"FCGI_MAX_REQS",   sizeof("FCGI_MAX_REQS")-1,   1},
+       {"FCGI_MPXS_CONNS", sizeof("FCGI_MPXS_CONNS")-1, 0}
 };
 
 
@@ -140,13 +141,6 @@
 static int is_fastcgi = 0;
 static int in_shutdown = 0;
 
-static inline char* fcgi_strndup(const char *str, int len)
-{
-       char *s = malloc(len+1);
-       memcpy(s, str, len+1);
-       return s;
-}
-
 #ifdef _WIN32
 
 static DWORD WINAPI fcgi_shutdown_thread(LPVOID arg)
@@ -396,8 +390,11 @@
        return pad;
 }
 
-static int fcgi_get_params(fcgi_request *req, unsigned char *p, unsigned char 
*end, int n)
+static void fcgi_get_params(fcgi_request *req, unsigned char *p, unsigned char 
*end)
 {
+       char buf[128];
+       char *tmp = buf;
+       size_t buf_size = sizeof(buf);
        int name_len, val_len;
        char *s;
 
@@ -416,35 +413,37 @@
                        val_len |= (*p++ << 8);
                        val_len |= *p++;
                }
-               req->env[n] = s = malloc(name_len + val_len + 2);
-               memcpy(s, p, name_len);
-               p += name_len;
-               s[name_len] = '=';
-               memcpy(s+name_len+1, p, val_len);
-               p += val_len;
-               s[name_len+1+val_len] = '\0';
-               n++;
-               if (n > sizeof(req->env)/sizeof(req->env[0])) {
-                       /* TODO: to many environment variables */
-                       return n;
+               if (name_len+1 >= buf_size) {
+                       buf_size = name_len + 64;
+                       tmp = (tmp == buf ? emalloc(buf_size): erealloc(tmp, 
buf_size));
                }
+               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);
+               p += name_len + val_len;
+       }
+       if (tmp != buf && tmp != NULL) {
+               efree(tmp);
        }
-       return n;
+}
+
+static void fcgi_free_var(char **s)
+{
+       free(*s);
 }
 
 static int fcgi_read_request(fcgi_request *req)
 {
        fcgi_header hdr;
        int len, padding;
-       int n = 1;
-       char *s;
        unsigned char buf[FCGI_MAX_LENGTH+8];
 
        req->keep = 0;
        req->in_len = 0;
        req->out_hdr = NULL;
        req->out_pos = req->out_buf;
-       memset(req->env, 0, sizeof(req->env));
+       zend_hash_init(&req->env, 0, NULL, (void (*)(void *)) fcgi_free_var, 1);
 
        if (safe_read(req, &hdr, sizeof(fcgi_header)) != sizeof(fcgi_header) ||
            hdr.version < FCGI_VERSION_1) {
@@ -467,6 +466,8 @@
        req->id = (hdr.requestIdB1 << 8) + hdr.requestIdB0;
 
        if (hdr.type == FCGI_BEGIN_REQUEST && len == 
sizeof(fcgi_begin_request)) {
+               char *val;
+
                if (safe_read(req, buf, len+padding) != len+padding) {
                        return 0;
                }
@@ -474,13 +475,16 @@
                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:
-                               req->env[0] = 
fcgi_strndup("FCGI_ROLE=RESPONDER", sizeof("FCGI_ROLE=RESPONDER")-1);
+                               val = strdup("RESPONDER");
+                               zend_hash_update(&req->env, "FCGI_ROLE", 
sizeof("FCGI_ROLE"), &val, sizeof(char*), NULL);
                                break;
                        case FCGI_AUTHORIZER:
-                               req->env[0] = 
fcgi_strndup("FCGI_ROLE=AUTHORIZER", sizeof("FCGI_ROLE=AUTHORIZER")-1);
+                               val = strdup("AUTHORIZER");
+                               zend_hash_update(&req->env, "FCGI_ROLE", 
sizeof("FCGI_ROLE"), &val, sizeof(char*), NULL);
                                break;
                        case FCGI_FILTER:
-                               req->env[0] = fcgi_strndup("FCGI_ROLE=FILTER", 
sizeof("FCGI_ROLE=FILTER")-1);
+                               val = strdup("FILTER");
+                               zend_hash_update(&req->env, "FCGI_ROLE", 
sizeof("FCGI_ROLE"), val, sizeof(char*), NULL);
                                break;
                        default:
                                return 0;
@@ -499,7 +503,7 @@
                                req->keep = 0;
                                return 0;
                        }
-                       n = fcgi_get_params(req, buf, buf+len, n);
+                       fcgi_get_params(req, buf, buf+len);
 
                        if (safe_read(req, &hdr, sizeof(fcgi_header)) != 
sizeof(fcgi_header) ||
                            hdr.version < FCGI_VERSION_1) {
@@ -510,26 +514,18 @@
                        padding = hdr.paddingLength;
                }
        } else if (hdr.type == FCGI_GET_VALUES) {
-               int i, j;
-               int name_len;
+               int j;
                unsigned char *p = buf + sizeof(fcgi_header);
 
                if (safe_read(req, buf, len+padding) != len+padding) {
                        return 0;
                }
-               n = fcgi_get_params(req, buf, buf+len, 0);
-               for (i = 0; i < n; i++) {
-                       if ((s = strchr(req->env[i], '=')) != NULL) {
-                               *s = '\0';
-                               name_len = s - req->env[i];
-                       } else {
-                               name_len = strlen(req->env[i]);
-                       }
-                       for (j = 0; j < 
sizeof(fcgi_mgmt_vars)/sizeof(fcgi_mgmt_vars[0]); j++) {
-                               if (strncmp(req->env[i], 
fcgi_mgmt_vars[j].name, name_len) == 0) {
-                       sprintf((char*)p, "%c%c%s%c", name_len, 1, 
fcgi_mgmt_vars[j].name, fcgi_mgmt_vars[j].val);
-                       p += name_len+3;
-                               }
+               fcgi_get_params(req, buf, buf+len);
+
+               for (j = 0; j < 
sizeof(fcgi_mgmt_vars)/sizeof(fcgi_mgmt_vars[0]); j++) {
+                       if (zend_hash_exists(&req->env, fcgi_mgmt_vars[j].name, 
fcgi_mgmt_vars[j].name_len+1) == 0) {
+                sprintf((char*)p, "%c%c%s%c", fcgi_mgmt_vars[j].name_len, 1, 
fcgi_mgmt_vars[j].name, fcgi_mgmt_vars[j].val);
+                p += fcgi_mgmt_vars[j].name_len + 3;
                        }
                }
                len = p - buf - sizeof(fcgi_header);
@@ -601,10 +597,7 @@
 static inline void fcgi_close(fcgi_request *req, int force, int destroy)
 {
        if (destroy) {
-               char **env = req->env;
-               while (*env) {
-                       free(*env++);
-               }
+               zend_hash_destroy(&req->env);
        }
        if ((force || !req->keep) && req->fd >= 0) {
 #ifdef _WIN32
@@ -866,62 +859,36 @@
        return 1;
 }
 
-char* fcgi_getenv_helper(char** env, const char *name, int len)
-{
-       if (name && env) {
-               while (*env) {
-                       if ((strncmp(name, *env, len) == 0) && ((*env)[len] == 
'=')) {
-                               return *env+len+1;
-                       }
-                       env++;
-               }
-       }
-       return NULL;
-}
-
 char* fcgi_getenv(fcgi_request *req, const char* var, int var_len)
 {
+       char **val;
+
        if (!req) return NULL;
-       return fcgi_getenv_helper(req->env, var, var_len);
+
+       if (zend_hash_find(&req->env, (char*)var, var_len+1, (void**)&val) == 
SUCCESS) {
+               return *val;
+       }
+       return NULL;
 }
 
-void fcgi_putenv(fcgi_request *req, char* var, int var_len)
+char* fcgi_putenv(fcgi_request *req, char* var, int var_len, char* val)
 {
        if (var && req) {
-               char **env = req->env;
-               char *s = strchr(var, '=');
-               int len;
+               char **ret;
 
-               if (!s) return ;
-               len = s - var + 1;
-               while (*env) {
-                       if ((strncmp(var, *env, len) == 0)) {
-                               free(*env);
-                               *env = fcgi_strndup(var, var_len);
-                               return;
-                       }
-                       env++;
+               if (val == NULL) {
+                       val = "";
+               }
+               val = strdup(val);
+               if (zend_hash_update(&req->env, var, var_len+1, &val, 
sizeof(char*), (void**)&ret) == SUCCESS) {
+                       return *ret;
                }
-               *env = fcgi_strndup(var, var_len);
        }
-}
-
-int FCGX_FPrintF(FCGX_Stream stream, const char *format, ...)
-{
-    int result;
-    va_list args;
-    char buf[4096];
-
-    va_start(args, format);
-       result = vsnprintf(buf, sizeof(buf), format, args);
-    va_end(args);
-
-    fcgi_write(stream.req, stream.type, buf, result);
-    return result;
+       return NULL;
 }
 
 #ifdef _WIN32
-void OS_SetImpersonate(void)
+void fcgi_impersonate(void)
 {
        char *os_name;
 
http://cvs.php.net/viewcvs.cgi/php-src/sapi/cgi/fastcgi.h?r1=1.4&r2=1.5&diff_format=u
Index: php-src/sapi/cgi/fastcgi.h
diff -u php-src/sapi/cgi/fastcgi.h:1.4 php-src/sapi/cgi/fastcgi.h:1.5
--- php-src/sapi/cgi/fastcgi.h:1.4      Wed May  3 15:48:33 2006
+++ php-src/sapi/cgi/fastcgi.h  Mon May 15 14:30:50 2006
@@ -16,7 +16,7 @@
    +----------------------------------------------------------------------+
 */
 
-/* $Id: fastcgi.h,v 1.4 2006/05/03 15:48:33 dmitry Exp $ */
+/* $Id: fastcgi.h,v 1.5 2006/05/15 14:30:50 dmitry Exp $ */
 
 /* FastCGI protocol */
 
@@ -105,7 +105,7 @@
        unsigned char  out_buf[1024*8];
        unsigned char  reserved[sizeof(fcgi_end_request_rec)];
 
-       char          *env[128];
+       HashTable      env;
 } fcgi_request;
 
 int fcgi_init(void);
@@ -116,63 +116,16 @@
 int fcgi_finish_request(fcgi_request *req);
 
 char* fcgi_getenv(fcgi_request *req, const char* var, int var_len);
-void fcgi_putenv(fcgi_request *req, char* var, int var_len);
+char* fcgi_putenv(fcgi_request *req, char* var, int var_len, char* val);
 
 int fcgi_read(fcgi_request *req, char *str, int len);
 
 int fcgi_write(fcgi_request *req, fcgi_request_type type, const char *str, int 
len);
 int fcgi_flush(fcgi_request *req, int close);
 
-/* Some defines for limited libfcgi comatibility */
-
-typedef struct _FCGX_Stream {
-       fcgi_request      *req;
-       fcgi_request_type  type;
-} FCGX_Stream;
-
-typedef struct _FCGX_Request {
-       fcgi_request req;
-       FCGX_Stream  in;
-       FCGX_Stream  out;
-       FCGX_Stream  err;
-       char **envp;
-} FCGX_Request;
-
-#define FCGX_Init()
-#define FCGX_IsCGI()                                           
(!fcgi_is_fastcgi())
-#define FCGX_OpenSocket(path, backlog)         fcgi_listen(path, backlog)
-
-#define FCGX_InitRequest(r, sock, flags)       \
-       do {                                                                    
\
-               fcgi_init_request(&(r)->req, sock);     \
-               (r)->in.req = &(r)->req;                        \
-               (r)->out.req = &(r)->req;                       \
-               (r)->err.req = &(r)->req;                       \
-               (r)->in.type = FCGI_STDIN;                      \
-               (r)->out.type = FCGI_STDOUT;            \
-               (r)->err.type = FCGI_STDERR;            \
-               (r)->envp = (r)->req.env;                       \
-       } while (0);
-
-
-#define FCGX_Accept_r(r)                                       
fcgi_accept_request(&(r)->req)
-#define FCGX_Finish_r(r)                                       
fcgi_finish_request(&(r)->req)
-
-#define FCGX_PutStr(str, len, stream)          fcgi_write((stream).req, 
(stream).type, str, len)
-#define FCGX_PutS(str, len, stream)                    
fcgi_write((stream).req, (stream).type, str, len)
-#define FCGX_FFlush(stream)                 fcgi_flush((stream).req, 0)
-#define FCGX_GetStr(str, len, stream)       fcgi_read((stream).req, str, len)
-
-#define FCGX_GetParam(var, envp)                       
fcgi_getenv_helper(envp, var, strlen(var));
-
-#define FCGX_PutEnv(r, var)                                    
fcgi_putenv(&(r)->req, var, strlen(var));
-
-int FCGX_FPrintF(FCGX_Stream stream, const char *format, ...);
-
-/* Internal helper functions. They shouldn't be used directly. */
-
-char* fcgi_getenv_helper(char** env, const char *name, int len);
-
+#ifdef PHP_WIN32
+void fcgi_impersonate(void);
+#endif
 /*
  * Local variables:
  * tab-width: 4

-- 
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to