Diff for /embedaddon/php/sapi/cgi/fastcgi.c between versions 1.1.1.1 and 1.1.1.2

version 1.1.1.1, 2012/02/21 23:48:06 version 1.1.1.2, 2012/05/29 12:34:35
Line 67 Line 67
 # include <sys/socket.h>  # include <sys/socket.h>
 # include <sys/un.h>  # include <sys/un.h>
 # include <netinet/in.h>  # include <netinet/in.h>
   # include <netinet/tcp.h>
 # include <arpa/inet.h>  # include <arpa/inet.h>
 # include <netdb.h>  # include <netdb.h>
 # include <signal.h>  # include <signal.h>
Line 140  static int is_fastcgi = 0; Line 141  static int is_fastcgi = 0;
 static int in_shutdown = 0;  static int in_shutdown = 0;
 static in_addr_t *allowed_clients = NULL;  static in_addr_t *allowed_clients = NULL;
   
   /* hash table */
   
   #define FCGI_HASH_TABLE_SIZE 128
   #define FCGI_HASH_TABLE_MASK (FCGI_HASH_TABLE_SIZE - 1)
   #define FCGI_HASH_SEG_SIZE   4096
   
   typedef struct _fcgi_hash_bucket {
           unsigned int              hash_value;
           unsigned int              var_len;
           char                     *var;
           unsigned int              val_len;
           char                     *val;
           struct _fcgi_hash_bucket *next;
           struct _fcgi_hash_bucket *list_next;
   } fcgi_hash_bucket;
   
   typedef struct _fcgi_hash_buckets {
           unsigned int               idx;
           struct _fcgi_hash_buckets *next;
           struct _fcgi_hash_bucket   data[FCGI_HASH_TABLE_SIZE];
   } fcgi_hash_buckets;
   
   typedef struct _fcgi_data_seg {
           char                  *pos;
           char                  *end;
           struct _fcgi_data_seg *next;
           char                   data[1];
   } fcgi_data_seg;
   
   typedef struct _fcgi_hash {
           fcgi_hash_bucket  *hash_table[FCGI_HASH_TABLE_SIZE];
           fcgi_hash_bucket  *list;
           fcgi_hash_buckets *buckets;
           fcgi_data_seg     *data;
   } fcgi_hash;
   
   static void fcgi_hash_init(fcgi_hash *h)
   {
           memset(h->hash_table, 0, sizeof(h->hash_table));
           h->list = NULL;
           h->buckets = (fcgi_hash_buckets*)malloc(sizeof(fcgi_hash_buckets));
           h->buckets->idx = 0;
           h->buckets->next = NULL;
           h->data = (fcgi_data_seg*)malloc(sizeof(fcgi_data_seg) - 1 + FCGI_HASH_SEG_SIZE);
           h->data->pos = h->data->data;
           h->data->end = h->data->pos + FCGI_HASH_SEG_SIZE;
           h->data->next = NULL;
   }
   
   static void fcgi_hash_destroy(fcgi_hash *h)
   {
           fcgi_hash_buckets *b;
           fcgi_data_seg *p;
   
           b = h->buckets;
           while (b) {
                   fcgi_hash_buckets *q = b;
                   b = b->next;
                   free(q);
           }
           p = h->data;
           while (p) {
                   fcgi_data_seg *q = p;
                   p = p->next;
                   free(q);
           }
   }
   
   static void fcgi_hash_clean(fcgi_hash *h)
   {
           memset(h->hash_table, 0, sizeof(h->hash_table));
           h->list = NULL;
           /* delete all bucket blocks except the first one */
           while (h->buckets->next) {
                   fcgi_hash_buckets *q = h->buckets;
   
                   h->buckets = h->buckets->next;
                   free(q);
           }
           h->buckets->idx = 0;
           /* delete all data segments except the first one */
           while (h->data->next) {
                   fcgi_data_seg *q = h->data;
   
                   h->data = h->data->next;
                   free(q);
           }
           h->data->pos = h->data->data;
   }
   
   static inline char* fcgi_hash_strndup(fcgi_hash *h, char *str, unsigned int str_len)
   {
           char *ret;
   
           if (UNEXPECTED(h->data->pos + str_len + 1 >= h->data->end)) {
                   unsigned int seg_size = (str_len + 1 > FCGI_HASH_SEG_SIZE) ? str_len + 1 : FCGI_HASH_SEG_SIZE;
                   fcgi_data_seg *p = (fcgi_data_seg*)malloc(sizeof(fcgi_data_seg) - 1 + seg_size);
   
                   p->pos = p->data;
                   p->end = p->pos + seg_size;
                   p->next = h->data;
                   h->data = p;
           }
           ret = h->data->pos; 
           memcpy(ret, str, str_len);
           ret[str_len] = 0;
           h->data->pos += str_len + 1;
           return ret;
   }
   
   static char* fcgi_hash_set(fcgi_hash *h, unsigned int hash_value, char *var, unsigned int var_len, char *val, unsigned int val_len)
   {
           unsigned int      idx = hash_value & FCGI_HASH_TABLE_MASK;
           fcgi_hash_bucket *p = h->hash_table[idx];
   
           while (UNEXPECTED(p != NULL)) {
                   if (UNEXPECTED(p->hash_value == hash_value) &&
                       p->var_len == var_len &&
                       memcmp(p->var, var, var_len) == 0) {
   
                           p->val_len = val_len;
                           p->val = fcgi_hash_strndup(h, val, val_len);
                           return p->val;
                   }
                   p = p->next;
           }
   
           if (UNEXPECTED(h->buckets->idx >= FCGI_HASH_TABLE_SIZE)) {
                   fcgi_hash_buckets *b = (fcgi_hash_buckets*)malloc(sizeof(fcgi_hash_buckets));
                   b->idx = 0;
                   b->next = h->buckets;
                   h->buckets = b;
           }
           p = h->buckets->data + h->buckets->idx;
           h->buckets->idx++;
           p->next = h->hash_table[idx];
           h->hash_table[idx] = p;
           p->list_next = h->list;
           h->list = p;
           p->hash_value = hash_value;
           p->var_len = var_len;
           p->var = fcgi_hash_strndup(h, var, var_len);
           p->val_len = val_len;
           p->val = fcgi_hash_strndup(h, val, val_len);
           return p->val;
   }
   
   static void fcgi_hash_del(fcgi_hash *h, unsigned int hash_value, char *var, unsigned int var_len)
   {
           unsigned int      idx = hash_value & FCGI_HASH_TABLE_MASK;
           fcgi_hash_bucket **p = &h->hash_table[idx];
   
           while (*p != NULL) {
                   if ((*p)->hash_value == hash_value &&
                       (*p)->var_len == var_len &&
                       memcmp((*p)->var, var, var_len) == 0) {
   
                       (*p)->val = NULL; /* NULL value means deleted */
                       (*p)->val_len = 0;
                           *p = (*p)->next;
                       return;
                   }
                   p = &(*p)->next;
           }
   }
   
   static char *fcgi_hash_get(fcgi_hash *h, unsigned int hash_value, char *var, unsigned int var_len, unsigned int *val_len)
   {
           unsigned int      idx = hash_value & FCGI_HASH_TABLE_MASK;
           fcgi_hash_bucket *p = h->hash_table[idx];
   
           while (p != NULL) {
                   if (p->hash_value == hash_value &&
                       p->var_len == var_len &&
                       memcmp(p->var, var, var_len) == 0) {
                       *val_len = p->val_len;
                       return p->val;
                   }
                   p = p->next;
           }
           return NULL;
   }
   
   static void fcgi_hash_apply(fcgi_hash *h, fcgi_apply_func func, void *arg TSRMLS_DC)
   {
           fcgi_hash_bucket *p     = h->list;
   
           while (p) {
                   if (EXPECTED(p->val != NULL)) {
                           func(p->var, p->var_len, p->val, p->val_len, arg TSRMLS_CC);
                   }
                   p = p->list_next;
           }
   }
   
   struct _fcgi_request {
           int            listen_socket;
           int            tcp;
           int            fd;
           int            id;
           int            keep;
   #ifdef TCP_NODELAY
           int            nodelay;
   #endif
           int            closed;
   
           int            in_len;
           int            in_pad;
   
           fcgi_header   *out_hdr;
           unsigned char *out_pos;
           unsigned char  out_buf[1024*8];
           unsigned char  reserved[sizeof(fcgi_end_request_rec)];
   
           int            has_env;
           fcgi_hash      env;
   };
   
 #ifdef _WIN32  #ifdef _WIN32
   
 static DWORD WINAPI fcgi_shutdown_thread(LPVOID arg)  static DWORD WINAPI fcgi_shutdown_thread(LPVOID arg)
Line 180  int fcgi_in_shutdown(void) Line 399  int fcgi_in_shutdown(void)
         return in_shutdown;          return in_shutdown;
 }  }
   
   void fcgi_terminate(void)
   {
           in_shutdown = 1;
   }
   
 int fcgi_init(void)  int fcgi_init(void)
 {  {
         if (!is_initialized) {          if (!is_initialized) {
Line 417  int fcgi_listen(const char *path, int backlog) Line 641  int fcgi_listen(const char *path, int backlog)
                         8192, 8192, 0, &saw);                          8192, 8192, 0, &saw);
                 if (namedPipe == INVALID_HANDLE_VALUE) {                  if (namedPipe == INVALID_HANDLE_VALUE) {
                         return -1;                          return -1;
                }                               }
                 listen_socket = _open_osfhandle((long)namedPipe, 0);                  listen_socket = _open_osfhandle((long)namedPipe, 0);
                 if (!is_initialized) {                  if (!is_initialized) {
                         fcgi_init();                          fcgi_init();
Line 459  int fcgi_listen(const char *path, int backlog) Line 683  int fcgi_listen(const char *path, int backlog)
         if (!tcp) {          if (!tcp) {
                 chmod(path, 0777);                  chmod(path, 0777);
         } else {          } else {
                        char *ip = getenv("FCGI_WEB_SERVER_ADDRS");                char *ip = getenv("FCGI_WEB_SERVER_ADDRS");
                        char *cur, *end;                char *cur, *end;
                        int n;                int n;
                        
                        if (ip) {                if (ip) {
                                ip = strdup(ip);                        ip = strdup(ip);
                                cur = ip;                        cur = ip;
                                n = 0;                        n = 0;
                                while (*cur) {                        while (*cur) {
                                        if (*cur == ',') n++;                                if (*cur == ',') n++;
                                        cur++;                                cur++;
                         }
                         allowed_clients = malloc(sizeof(in_addr_t) * (n+2));
                         n = 0;
                         cur = ip;
                         while (cur) {
                                 end = strchr(cur, ',');
                                 if (end) {
                                         *end = 0;
                                         end++;
                                 }                                  }
                                allowed_clients = malloc(sizeof(in_addr_t) * (n+2));                                allowed_clients[n] = inet_addr(cur);
                                n = 0;                                if (allowed_clients[n] == INADDR_NONE) {
                                cur = ip; 
                                while (cur) { 
                                        end = strchr(cur, ','); 
                                        if (end) { 
                                                *end = 0; 
                                                end++; 
                                        } 
                                        allowed_clients[n] = inet_addr(cur); 
                                        if (allowed_clients[n] == INADDR_NONE) { 
                                         fprintf(stderr, "Wrong IP address '%s' in FCGI_WEB_SERVER_ADDRS\n", cur);                                          fprintf(stderr, "Wrong IP address '%s' in FCGI_WEB_SERVER_ADDRS\n", cur);
                                         }  
                                         n++;  
                                         cur = end;  
                                 }                                  }
                                allowed_clients[n] = INADDR_NONE;                                n++;
                                 cur = end;
                         }
                         allowed_clients[n] = INADDR_NONE;
                         free(ip);                          free(ip);
                 }                  }
         }          }
Line 507  int fcgi_listen(const char *path, int backlog) Line 731  int fcgi_listen(const char *path, int backlog)
         return listen_socket;          return listen_socket;
 }  }
   
void fcgi_init_request(fcgi_request *req, int listen_socket)fcgi_request *fcgi_init_request(int listen_socket)
 {  {
        memset(req, 0, sizeof(fcgi_request));        fcgi_request *req = (fcgi_request*)calloc(1, sizeof(fcgi_request));
         req->listen_socket = listen_socket;          req->listen_socket = listen_socket;
         req->fd = -1;          req->fd = -1;
         req->id = -1;          req->id = -1;
Line 523  void fcgi_init_request(fcgi_request *req, int listen_s Line 747  void fcgi_init_request(fcgi_request *req, int listen_s
 #ifdef _WIN32  #ifdef _WIN32
         req->tcp = !GetNamedPipeInfo((HANDLE)_get_osfhandle(req->listen_socket), NULL, NULL, NULL, NULL);          req->tcp = !GetNamedPipeInfo((HANDLE)_get_osfhandle(req->listen_socket), NULL, NULL, NULL, NULL);
 #endif  #endif
   
   #ifdef TCP_NODELAY
           req->nodelay = 0;
   #endif
   
           fcgi_hash_init(&req->env);
   
           return req;
 }  }
   
   void fcgi_destroy_request(fcgi_request *req)
   {
           fcgi_hash_destroy(&req->env);
           free(req);
   }
   
 static inline ssize_t safe_write(fcgi_request *req, const void *buf, size_t count)  static inline ssize_t safe_write(fcgi_request *req, const void *buf, size_t count)
 {  {
         int    ret;          int    ret;
Line 603  static inline int fcgi_make_header(fcgi_header *hdr, f Line 841  static inline int fcgi_make_header(fcgi_header *hdr, f
   
 static int fcgi_get_params(fcgi_request *req, unsigned char *p, unsigned char *end)  static int fcgi_get_params(fcgi_request *req, unsigned char *p, unsigned char *end)
 {  {
         char buf[128];  
         char *tmp = buf;  
         size_t buf_size = sizeof(buf);  
         unsigned int name_len, val_len;          unsigned int name_len, val_len;
         char *s;  
         int ret = 1;  
   
         while (p < end) {          while (p < end) {
                 name_len = *p++;                  name_len = *p++;
                if (name_len >= 128) {                if (UNEXPECTED(name_len >= 128)) {
                        if (p + 3 >= end) {                        if (UNEXPECTED(p + 3 >= end)) return 0;
                                ret = 0; 
                                break; 
                        } 
                         name_len = ((name_len & 0x7f) << 24);                          name_len = ((name_len & 0x7f) << 24);
                         name_len |= (*p++ << 16);                          name_len |= (*p++ << 16);
                         name_len |= (*p++ << 8);                          name_len |= (*p++ << 8);
                         name_len |= *p++;                          name_len |= *p++;
                 }                  }
                if (p >= end) {                if (UNEXPECTED(p >= end)) return 0;
                        ret = 0; 
                        break; 
                } 
                 val_len = *p++;                  val_len = *p++;
                if (val_len >= 128) {                if (UNEXPECTED(val_len >= 128)) {
                        if (p + 3 >= end) {                        if (UNEXPECTED(p + 3 >= end)) return 0;
                                ret = 0; 
                                break; 
                        } 
                         val_len = ((val_len & 0x7f) << 24);                          val_len = ((val_len & 0x7f) << 24);
                         val_len |= (*p++ << 16);                          val_len |= (*p++ << 16);
                         val_len |= (*p++ << 8);                          val_len |= (*p++ << 8);
                         val_len |= *p++;                          val_len |= *p++;
                 }                  }
                if (name_len + val_len > end - p) {                if (UNEXPECTED(name_len + val_len > (unsigned int) (end - p))) {
                         /* Malformated request */                          /* Malformated request */
                        ret = 0;                        return 0;
                        break; 
                 }                  }
                if (name_len+1 >= buf_size) {                fcgi_hash_set(&req->env, FCGI_HASH_FUNC(p, name_len), (char*)p, name_len, (char*)p + name_len, val_len);
                        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 = 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;                  p += name_len + val_len;
         }          }
        if (tmp != buf && tmp != NULL) {        return 1;
                efree(tmp); 
        } 
        return ret; 
 }  }
   
 static void fcgi_free_var(char **s)  
 {  
         efree(*s);  
 }  
   
 static int fcgi_read_request(fcgi_request *req)  static int fcgi_read_request(fcgi_request *req)
 {  {
         fcgi_header hdr;          fcgi_header hdr;
Line 674  static int fcgi_read_request(fcgi_request *req) Line 882  static int fcgi_read_request(fcgi_request *req)
         req->in_len = 0;          req->in_len = 0;
         req->out_hdr = NULL;          req->out_hdr = NULL;
         req->out_pos = req->out_buf;          req->out_pos = req->out_buf;
        ALLOC_HASHTABLE(req->env);        req->has_env = 1;
        zend_hash_init(req->env, 0, NULL, (void (*)(void *)) fcgi_free_var, 0); 
   
         if (safe_read(req, &hdr, sizeof(fcgi_header)) != sizeof(fcgi_header) ||          if (safe_read(req, &hdr, sizeof(fcgi_header)) != sizeof(fcgi_header) ||
             hdr.version < FCGI_VERSION_1) {              hdr.version < FCGI_VERSION_1) {
Line 702  static int fcgi_read_request(fcgi_request *req) Line 909  static int fcgi_read_request(fcgi_request *req)
         req->id = (hdr.requestIdB1 << 8) + hdr.requestIdB0;          req->id = (hdr.requestIdB1 << 8) + hdr.requestIdB0;
   
         if (hdr.type == FCGI_BEGIN_REQUEST && len == sizeof(fcgi_begin_request)) {          if (hdr.type == FCGI_BEGIN_REQUEST && len == sizeof(fcgi_begin_request)) {
                 char *val;  
   
                 if (safe_read(req, buf, len+padding) != len+padding) {                  if (safe_read(req, buf, len+padding) != len+padding) {
                         return 0;                          return 0;
                 }                  }
   
                 req->keep = (((fcgi_begin_request*)buf)->flags & FCGI_KEEP_CONN);                  req->keep = (((fcgi_begin_request*)buf)->flags & FCGI_KEEP_CONN);
   #ifdef TCP_NODELAY
                   if (req->keep && req->tcp && !req->nodelay) {
   # ifdef _WIN32
                           BOOL on = 1;
   # else
                           int on = 1;
   # endif
   
                           setsockopt(req->fd, IPPROTO_TCP, TCP_NODELAY, (char*)&on, sizeof(on));
                           req->nodelay = 1;
                   }
   #endif
                 switch ((((fcgi_begin_request*)buf)->roleB1 << 8) + ((fcgi_begin_request*)buf)->roleB0) {                  switch ((((fcgi_begin_request*)buf)->roleB1 << 8) + ((fcgi_begin_request*)buf)->roleB0) {
                         case FCGI_RESPONDER:                          case FCGI_RESPONDER:
                                val = estrdup("RESPONDER");                                fcgi_hash_set(&req->env, FCGI_HASH_FUNC("FCGI_ROLE", sizeof("FCGI_ROLE")-1), "FCGI_ROLE", sizeof("FCGI_ROLE")-1, "RESPONDER", sizeof("RESPONDER")-1);
                                zend_hash_update(req->env, "FCGI_ROLE", sizeof("FCGI_ROLE"), &val, sizeof(char*), NULL); 
                                 break;                                  break;
                         case FCGI_AUTHORIZER:                          case FCGI_AUTHORIZER:
                                val = estrdup("AUTHORIZER");                                fcgi_hash_set(&req->env, FCGI_HASH_FUNC("FCGI_ROLE", sizeof("FCGI_ROLE")-1), "FCGI_ROLE", sizeof("FCGI_ROLE")-1, "AUTHORIZER", sizeof("AUTHORIZER")-1);
                                zend_hash_update(req->env, "FCGI_ROLE", sizeof("FCGI_ROLE"), &val, sizeof(char*), NULL); 
                                 break;                                  break;
                         case FCGI_FILTER:                          case FCGI_FILTER:
                                val = estrdup("FILTER");                                fcgi_hash_set(&req->env, FCGI_HASH_FUNC("FCGI_ROLE", sizeof("FCGI_ROLE")-1), "FCGI_ROLE", sizeof("FCGI_ROLE")-1, "FILTER", sizeof("FILTER")-1);
                                zend_hash_update(req->env, "FCGI_ROLE", sizeof("FCGI_ROLE"), &val, sizeof(char*), NULL); 
                                 break;                                  break;
                         default:                          default:
                                 return 0;                                  return 0;
Line 759  static int fcgi_read_request(fcgi_request *req) Line 973  static int fcgi_read_request(fcgi_request *req)
                 }                  }
         } else if (hdr.type == FCGI_GET_VALUES) {          } else if (hdr.type == FCGI_GET_VALUES) {
                 unsigned char *p = buf + sizeof(fcgi_header);                  unsigned char *p = buf + sizeof(fcgi_header);
                 HashPosition pos;  
                 char * str_index;  
                 uint str_length;  
                 ulong num_index;  
                 int key_type;  
                 zval ** value;                  zval ** value;
                   unsigned int zlen;
                   fcgi_hash_bucket *q;
   
                 if (safe_read(req, buf, len+padding) != len+padding) {                  if (safe_read(req, buf, len+padding) != len+padding) {
                         req->keep = 0;                          req->keep = 0;
Line 776  static int fcgi_read_request(fcgi_request *req) Line 987  static int fcgi_read_request(fcgi_request *req)
                         return 0;                          return 0;
                 }                  }
   
                zend_hash_internal_pointer_reset_ex(req->env, &pos);                q = req->env.list;
                while ((key_type = zend_hash_get_current_key_ex(req->env, &str_index, &str_length, &num_index, 0, &pos)) != HASH_KEY_NON_EXISTANT) {                while (q != NULL) {
                        int zlen;                        if (zend_hash_find(&fcgi_mgmt_vars, q->var, q->var_len, (void**) &value) != SUCCESS) {
                        zend_hash_move_forward_ex(req->env, &pos); 
                        if (key_type != HASH_KEY_IS_STRING) { 
                                 continue;                                  continue;
                         }                          }
                         if (zend_hash_find(&fcgi_mgmt_vars, str_index, str_length, (void**) &value) != SUCCESS) {  
                                 continue;  
                         }  
                         --str_length;  
                         zlen = Z_STRLEN_PP(value);                          zlen = Z_STRLEN_PP(value);
                        if ((p + 4 + 4 + str_length + zlen) >= (buf + sizeof(buf))) {                        if ((p + 4 + 4 + q->var_len + zlen) >= (buf + sizeof(buf))) {
                                 break;                                  break;
                         }                          }
                        if (str_length < 0x80) {                        if (q->var_len < 0x80) {
                                *p++ = str_length;                                *p++ = q->var_len;
                         } else {                          } else {
                                *p++ = ((str_length >> 24) & 0xff) | 0x80;                                *p++ = ((q->var_len >> 24) & 0xff) | 0x80;
                                *p++ = (str_length >> 16) & 0xff;                                *p++ = (q->var_len >> 16) & 0xff;
                                *p++ = (str_length >> 8) & 0xff;                                *p++ = (q->var_len >> 8) & 0xff;
                                *p++ = str_length & 0xff;                                *p++ = q->var_len & 0xff;
                         }                          }
                         if (zlen < 0x80) {                          if (zlen < 0x80) {
                                 *p++ = zlen;                                  *p++ = zlen;
Line 807  static int fcgi_read_request(fcgi_request *req) Line 1012  static int fcgi_read_request(fcgi_request *req)
                                 *p++ = (zlen >> 8) & 0xff;                                  *p++ = (zlen >> 8) & 0xff;
                                 *p++ = zlen & 0xff;                                  *p++ = zlen & 0xff;
                         }                          }
                        memcpy(p, str_index, str_length);                        memcpy(p, q->var, q->var_len);
                        p += str_length;                        p += q->var_len;
                         memcpy(p, Z_STRVAL_PP(value), zlen);                          memcpy(p, Z_STRVAL_PP(value), zlen);
                         p += zlen;                          p += zlen;
                 }                  }
Line 881  int fcgi_read(fcgi_request *req, char *str, int len) Line 1086  int fcgi_read(fcgi_request *req, char *str, int len)
   
 static inline void fcgi_close(fcgi_request *req, int force, int destroy)  static inline void fcgi_close(fcgi_request *req, int force, int destroy)
 {  {
        if (destroy && req->env) {        if (destroy && req->has_env) {
                zend_hash_destroy(req->env);                fcgi_hash_clean(&req->env);
                FREE_HASHTABLE(req->env);                req->has_env = 0;
                req->env = NULL; 
         }          }
   
 #ifdef _WIN32  #ifdef _WIN32
Line 904  static inline void fcgi_close(fcgi_request *req, int f Line 1108  static inline void fcgi_close(fcgi_request *req, int f
                         DisconnectNamedPipe(pipe);                          DisconnectNamedPipe(pipe);
                 } else {                  } else {
                         if (!force) {                          if (!force) {
                                char buf[8];                                fcgi_header buf;
   
                                 shutdown(req->fd, 1);                                  shutdown(req->fd, 1);
                                while (recv(req->fd, buf, sizeof(buf), 0) > 0) {}                                /* read the last FCGI_STDIN header (it may be omitted) */
                                 recv(req->fd, &buf, sizeof(buf), 0);
                         }                          }
                         closesocket(req->fd);                          closesocket(req->fd);
                 }                  }
 #else  #else
                 if (!force) {                  if (!force) {
                        char buf[8];                        fcgi_header buf;
   
                         shutdown(req->fd, 1);                          shutdown(req->fd, 1);
                        while (recv(req->fd, buf, sizeof(buf), 0) > 0) {}                        /* read the last FCGI_STDIN header (it may be omitted) */
                         recv(req->fd, &buf, sizeof(buf), 0);
                 }                  }
                 close(req->fd);                  close(req->fd);
 #endif  #endif
   #ifdef TCP_NODELAY
                   req->nodelay = 0;
   #endif
                 req->fd = -1;                  req->fd = -1;
         }          }
 }  }
Line 970  int fcgi_accept_request(fcgi_request *req) Line 1179  int fcgi_accept_request(fcgi_request *req)
                                         FCGI_LOCK(req->listen_socket);                                          FCGI_LOCK(req->listen_socket);
                                         req->fd = accept(listen_socket, (struct sockaddr *)&sa, &len);                                          req->fd = accept(listen_socket, (struct sockaddr *)&sa, &len);
                                         FCGI_UNLOCK(req->listen_socket);                                          FCGI_UNLOCK(req->listen_socket);
                                        if (req->fd >= 0 && allowed_clients) {                                        if (req->fd >= 0) {
                                                int n = 0;                                                if (((struct sockaddr *)&sa)->sa_family == AF_INET) {
                                                int allowed = 0;#ifndef _WIN32
                                                         req->tcp = 1;
 #endif
                                                         if (allowed_clients) {
                                                                 int n = 0;
                                                                 int allowed = 0;
   
                                                        while (allowed_clients[n] != INADDR_NONE) {                                                                while (allowed_clients[n] != INADDR_NONE) {
                                                                if (allowed_clients[n] == sa.sa_inet.sin_addr.s_addr) {                                                                        if (allowed_clients[n] == sa.sa_inet.sin_addr.s_addr) {
                                                                        allowed = 1;                                                                                allowed = 1;
                                                                        break;                                                                                break;
                                                                         }
                                                                         n++;
                                                                 }                                                                  }
                                                                n++;                                                                if (!allowed) {
                                                                         fprintf(stderr, "Connection from disallowed IP address '%s' is dropped.\n", inet_ntoa(sa.sa_inet.sin_addr));
                                                                         closesocket(req->fd);
                                                                         req->fd = -1;
                                                                         continue;
                                                                 }
                                                         }                                                          }
                                                if (!allowed) {#ifndef _WIN32
                                                        fprintf(stderr, "Connection from disallowed IP address '%s' is dropped.\n", inet_ntoa(sa.sa_inet.sin_addr));                                                } else {
                                                        closesocket(req->fd);                                                        req->tcp = 0;
                                                        req->fd = -1;#endif
                                                        continue; 
                                                 }                                                  }
                                         }                                          }
                                 }                                  }
Line 1195  int fcgi_write(fcgi_request *req, fcgi_request_type ty Line 1415  int fcgi_write(fcgi_request *req, fcgi_request_type ty
                                 return -1;                                  return -1;
                         }                          }
                         pos += 0xfff8;                          pos += 0xfff8;
                }                               }
                
                 pad = (((len - pos) + 7) & ~7) - (len - pos);                  pad = (((len - pos) + 7) & ~7) - (len - pos);
                 rest = pad ? 8 - pad : 0;                  rest = pad ? 8 - pad : 0;
   
Line 1236  int fcgi_finish_request(fcgi_request *req, int force_c Line 1456  int fcgi_finish_request(fcgi_request *req, int force_c
   
 char* fcgi_getenv(fcgi_request *req, const char* var, int var_len)  char* fcgi_getenv(fcgi_request *req, const char* var, int var_len)
 {  {
        char **val;        unsigned int val_len;
   
         if (!req) return NULL;          if (!req) return NULL;
   
        if (zend_hash_find(req->env, (char*)var, var_len+1, (void**)&val) == SUCCESS) {        return fcgi_hash_get(&req->env, FCGI_HASH_FUNC(var, var_len), (char*)var, var_len, &val_len);
                return *val; 
        } 
        return NULL; 
 }  }
   
   char* fcgi_quick_getenv(fcgi_request *req, const char* var, int var_len, unsigned int hash_value)
   {
           unsigned int val_len;
   
           return fcgi_hash_get(&req->env, hash_value, (char*)var, var_len, &val_len);
   }
   
 char* fcgi_putenv(fcgi_request *req, char* var, int var_len, char* val)  char* fcgi_putenv(fcgi_request *req, char* var, int var_len, char* val)
 {  {
        if (var && req) {        if (!req) return NULL;
                if (val == NULL) {        if (val == NULL) {
                        zend_hash_del(req->env, var, var_len+1);                fcgi_hash_del(&req->env, FCGI_HASH_FUNC(var, var_len), var, var_len);
                } else {                return NULL;
                        char **ret;        } else {
                 return fcgi_hash_set(&req->env, FCGI_HASH_FUNC(var, var_len), var, var_len, val, strlen(val));
         }
 }
   
                        val = estrdup(val);char* fcgi_quick_putenv(fcgi_request *req, char* var, int var_len, unsigned int hash_value, char* val)
                        if (zend_hash_update(req->env, var, var_len+1, &val, sizeof(char*), (void**)&ret) == SUCCESS) {{
                                return *ret;        if (val == NULL) {
                        }                fcgi_hash_del(&req->env, hash_value, var, var_len);
                }                return NULL;
         } else {
                 return fcgi_hash_set(&req->env, hash_value, var, var_len, val, strlen(val));
         }          }
         return NULL;  
 }  }
   
   void fcgi_loadenv(fcgi_request *req, fcgi_apply_func func, zval *array TSRMLS_DC)
   {
           fcgi_hash_apply(&req->env, func, array TSRMLS_CC);
   }
   
 #ifdef _WIN32  #ifdef _WIN32
 void fcgi_impersonate(void)  void fcgi_impersonate(void)
 {  {
Line 1282  void fcgi_set_mgmt_var(const char * name, size_t name_ Line 1515  void fcgi_set_mgmt_var(const char * name, size_t name_
         Z_TYPE_P(zvalue) = IS_STRING;          Z_TYPE_P(zvalue) = IS_STRING;
         Z_STRVAL_P(zvalue) = pestrndup(value, value_len, 1);          Z_STRVAL_P(zvalue) = pestrndup(value, value_len, 1);
         Z_STRLEN_P(zvalue) = value_len;          Z_STRLEN_P(zvalue) = value_len;
        zend_hash_add(&fcgi_mgmt_vars, name, name_len + 1, &zvalue, sizeof(zvalue), NULL);        zend_hash_add(&fcgi_mgmt_vars, name, name_len, &zvalue, sizeof(zvalue), NULL);
 }  }
   
 void fcgi_free_mgmt_var_cb(void * ptr)  void fcgi_free_mgmt_var_cb(void * ptr)

Removed from v.1.1.1.1  
changed lines
  Added in v.1.1.1.2


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>