nginx-0.1.43-RELEASE import

    *) Feature: the listen(2) backlog in the "listen" directive can be
       changed using the -HUP signal.

    *) Feature: the geo2nginx.pl script was added to contrib.

    *) Change: the FastCGI parameters with the empty values now are passed
       to a server.

    *) Bugfix: the segmentation fault occurred or the worker process may
       got caught in an endless loop if the proxied or FastCGI server sent
       the "Cache-Control" header line and the "expires" directive was
       used; in the proxied mode the the bug had appeared in 0.1.29.
diff --git a/src/http/modules/ngx_http_fastcgi_module.c b/src/http/modules/ngx_http_fastcgi_module.c
index 480a228..c5a2c4b 100644
--- a/src/http/modules/ngx_http_fastcgi_module.c
+++ b/src/http/modules/ngx_http_fastcgi_module.c
@@ -144,15 +144,6 @@
 };
 
 
-#if 0
-static ngx_str_t ngx_http_fastcgi_methods[] = {
-    ngx_string("GET"),
-    ngx_string("HEAD"),
-    ngx_string("POST")
-};
-#endif
-
-
 static ngx_str_t  ngx_http_fastcgi_script_name =
     ngx_string("fastcgi_script_name");
 
@@ -428,9 +419,7 @@
             }
             le.ip += sizeof(uintptr_t);
 
-            if (val_len) {
-                len += 1 + key_len + ((val_len > 127) ? 4 : 1) + val_len;
-            }
+            len += 1 + key_len + ((val_len > 127) ? 4 : 1) + val_len;
         }
     }
 
@@ -527,22 +516,18 @@
             }
             le.ip += sizeof(uintptr_t);
 
-            if (val_len) {
-                *e.pos++ = (u_char) key_len;
+            *e.pos++ = (u_char) key_len;
 
-                if (val_len > 127) {
-                    *e.pos++ = (u_char) (((val_len >> 24) & 0x7f) | 0x80);
-                    *e.pos++ = (u_char) ((val_len >> 16) & 0xff);
-                    *e.pos++ = (u_char) ((val_len >> 8) & 0xff);
-                    *e.pos++ = (u_char) (val_len & 0xff);
+            if (val_len > 127) {
+                *e.pos++ = (u_char) (((val_len >> 24) & 0x7f) | 0x80);
+                *e.pos++ = (u_char) ((val_len >> 16) & 0xff);
+                *e.pos++ = (u_char) ((val_len >> 8) & 0xff);
+                *e.pos++ = (u_char) (val_len & 0xff);
 
-                } else {
-                    *e.pos++ = (u_char) val_len;
-                }
+            } else {
+                *e.pos++ = (u_char) val_len;
             }
 
-            e.skip = val_len ? 0 : 1;
-
             while (*(uintptr_t *) e.ip) {
                 code = *(ngx_http_script_code_pt *) e.ip;
                 code((ngx_http_script_engine_t *) &e);
diff --git a/src/http/modules/ngx_http_headers_filter_module.c b/src/http/modules/ngx_http_headers_filter_module.c
index f27ab47..91bebdc 100644
--- a/src/http/modules/ngx_http_headers_filter_module.c
+++ b/src/http/modules/ngx_http_headers_filter_module.c
@@ -73,7 +73,7 @@
 {
     size_t                    len;
     ngx_uint_t                i;
-    ngx_table_elt_t          *expires, *cc;
+    ngx_table_elt_t          *expires, *cc, **ccp;
     ngx_http_headers_conf_t  *conf;
 
     if (r->headers_out.status != NGX_HTTP_OK || r->main) {
@@ -103,9 +103,20 @@
         len = sizeof("Mon, 28 Sep 1970 06:00:00 GMT");
         expires->value.len = len - 1;
 
-        cc = r->headers_out.cache_control.elts;
+        ccp = r->headers_out.cache_control.elts;
 
-        if (cc == NULL) {
+        if (ccp == NULL) {
+
+            if (ngx_array_init(&r->headers_out.cache_control, r->pool,
+                               1, sizeof(ngx_table_elt_t *)) != NGX_OK)
+            {
+                return NGX_ERROR;
+            }
+
+            ccp = ngx_array_push(&r->headers_out.cache_control);
+            if (ccp == NULL) {
+                return NGX_ERROR;
+            }
 
             cc = ngx_list_push(&r->headers_out.headers);
             if (cc == NULL) {
@@ -116,10 +127,14 @@
             cc->key.len = sizeof("Cache-Control") - 1;
             cc->key.data = (u_char *) "Cache-Control";
 
+            *ccp = cc;
+
         } else {
             for (i = 1; i < r->headers_out.cache_control.nelts; i++) {
-                cc[i].hash = 0;
+                ccp[i]->hash = 0;
             }
+
+            cc = ccp[0];
         }
 
         if (conf->expires == NGX_HTTP_EXPIRES_EPOCH) {
diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c
index c6a5809..b8e97d2 100644
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -637,8 +637,24 @@
                            "http exten: \"%V\"", &r->exten);
 
             if (r->http_version < NGX_HTTP_VERSION_10) {
+
+                if (rev->timer_set) {
+                    ngx_del_timer(rev);
+                }
+
+#if (NGX_STAT_STUB)
+                ngx_atomic_dec(ngx_stat_reading);
+                r->stat_reading = 0;
+                ngx_atomic_inc(ngx_stat_writing);
+                r->stat_writing = 1;
+#endif
+
+                rev->handler = ngx_http_request_handler;
+                c->write->handler = ngx_http_request_handler;
                 r->read_event_handler = ngx_http_block_read;
+
                 ngx_http_handler(r);
+
                 return;
             }
 
@@ -868,6 +884,7 @@
             r->read_event_handler = ngx_http_block_read;
 
             ngx_http_handler(r);
+
             return;
         }
 
@@ -1783,6 +1800,8 @@
         return NGX_OK;
     }
 
+    r->discard_body = 1;
+
     size = r->header_in->last - r->header_in->pos;
 
     if (size) {
diff --git a/src/http/ngx_http_request.h b/src/http/ngx_http_request.h
index 2e80991..fe56b26 100644
--- a/src/http/ngx_http_request.h
+++ b/src/http/ngx_http_request.h
@@ -362,6 +362,7 @@
     unsigned                          header_only:1;
     unsigned                          keepalive:1;
     unsigned                          lingering_close:1;
+    unsigned                          discard_body:1;
     unsigned                          internal:1;
     unsigned                          done:1;
     unsigned                          utf8:1;
diff --git a/src/http/ngx_http_request_body.c b/src/http/ngx_http_request_body.c
index eb2e6a5..66c7c67 100644
--- a/src/http/ngx_http_request_body.c
+++ b/src/http/ngx_http_request_body.c
@@ -31,7 +31,7 @@
     ngx_http_request_body_t   *rb;
     ngx_http_core_loc_conf_t  *clcf;
 
-    if (r->request_body) {
+    if (r->request_body || r->discard_body) {
         post_handler(r);
         return NGX_OK;
     }
diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c
index f59ff17..c575347 100644
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -241,7 +241,9 @@
 
     u = r->upstream;
 
-    u->request_bufs = r->request_body->bufs;
+    if (r->request_body) {
+        u->request_bufs = r->request_body->bufs;
+    }
 
     if (u->conf->method == NGX_CONF_UNSET_UINT) {
         u->method = r->method;
@@ -250,7 +252,7 @@
         u->method = u->conf->method;
     }
 
-    if (u->create_request(r) == NGX_ERROR) {
+    if (u->create_request(r) != NGX_OK) {
         ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
         return;
     }
@@ -615,9 +617,8 @@
         && !u->request_sent
         && c->write->pending_eof)
     {
-        ngx_log_error(NGX_LOG_ERR, c->log, c->write->kq_errno,
-                      "connect() failed");
-
+        (void) ngx_connection_error(c, c->write->kq_errno,
+                                    "kevent() reported that connect() failed");
         ngx_http_upstream_next(r, u, NGX_HTTP_UPSTREAM_FT_ERROR);
         return;
     }
@@ -716,12 +717,6 @@
         return;
     }
 
-    if (r->connection->write->eof && (!u->cachable || !u->request_sent)) {
-        ngx_http_upstream_finalize_request(r, u,
-                                           NGX_HTTP_INTERNAL_SERVER_ERROR);
-        return;
-    }
-
     ngx_http_upstream_send_request(r, u);
 }
 
@@ -1788,6 +1783,7 @@
 ngx_http_upstream_log_error(ngx_http_request_t *r, u_char *buf, size_t len)
 {
     u_char                 *p;
+    ngx_str_t               line;
     uintptr_t               escape;
     ngx_http_upstream_t    *u;
     ngx_peer_connection_t  *peer;
@@ -1824,32 +1820,34 @@
             buf += r->uri.len - u->conf->location->len + escape;
             len -= r->uri.len - u->conf->location->len + escape;
 
-            if (r->args.len) {
-                p = ngx_snprintf(buf, len, "?%V", &r->args);
-                len -= p - buf;
-                buf = p;
+        } else {
+            p = ngx_palloc(r->pool,
+                           r->uri.len - u->conf->location->len + escape);
+            if (p == NULL) {
+                return buf;
             }
 
-            return ngx_http_log_error_info(r, buf, len);
+            ngx_escape_uri(p, r->uri.data + u->conf->location->len,
+                           r->uri.len - u->conf->location->len, NGX_ESCAPE_URI);
+
+            line.len = len;
+            line.data = p;
+
+            return ngx_snprintf(buf, len, "%V", &line);
         }
 
-        p = ngx_palloc(r->pool, r->uri.len - u->conf->location->len + escape);
-        if (p == NULL) {
-            return buf;
-        }
-
-        ngx_escape_uri(p, r->uri.data + u->conf->location->len,
-                       r->uri.len - u->conf->location->len, NGX_ESCAPE_URI);
-
-        p = ngx_cpymem(buf, p, r->uri.len - u->conf->location->len + escape);
-
     } else {
-        p = ngx_cpymem(buf, r->uri.data + u->conf->location->len,
-                       r->uri.len - u->conf->location->len);
-    }
+        line.len = r->uri.len - u->conf->location->len;
+        if (line.len > len) {
+            line.len = len;
+        }
 
-    len -= p - buf;
-    buf = p;
+        line.data = r->uri.data + u->conf->location->len;
+        p = ngx_snprintf(buf, len, "%V", &line);
+
+        len -= p - buf;
+        buf = p;
+    }
 
     if (r->args.len) {
         p = ngx_snprintf(buf, len, "?%V", &r->args);