nginx-0.3.44-RELEASE import

    *) Feature: the "wait" parameter in the "include" SSI command.

    *) Feature: the Ukrainian and Byelorussian characters were added to
       koi-win conversion table.

    *) Bugfix: in the SSI.
diff --git a/src/http/modules/ngx_http_addition_filter_module.c b/src/http/modules/ngx_http_addition_filter_module.c
index 842124d..15231ce 100644
--- a/src/http/modules/ngx_http_addition_filter_module.c
+++ b/src/http/modules/ngx_http_addition_filter_module.c
@@ -143,7 +143,9 @@
         ctx->before_body_sent = 1;
 
         if (conf->before_body.len) {
-            if (ngx_http_subrequest(r, &conf->before_body, NULL, 0) != NGX_OK) {
+            if (ngx_http_subrequest(r, &conf->before_body, NULL, 0)
+                == NGX_ERROR)
+            {
                 return NGX_ERROR;
             }
         }
@@ -165,7 +167,7 @@
         return rc;
     }
 
-    if (ngx_http_subrequest(r, &conf->after_body, NULL, 0) != NGX_OK) {
+    if (ngx_http_subrequest(r, &conf->after_body, NULL, 0) == NGX_ERROR) {
         return NGX_ERROR;
     }
 
diff --git a/src/http/modules/ngx_http_autoindex_module.c b/src/http/modules/ngx_http_autoindex_module.c
index e1a0e86..b1ba178 100644
--- a/src/http/modules/ngx_http_autoindex_module.c
+++ b/src/http/modules/ngx_http_autoindex_module.c
@@ -162,7 +162,7 @@
         return NGX_DECLINED;
     }
 
-    if (r->method != NGX_HTTP_GET && r->method != NGX_HTTP_HEAD) {
+    if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD))) {
         return NGX_DECLINED;
     }
 
diff --git a/src/http/modules/ngx_http_empty_gif_module.c b/src/http/modules/ngx_http_empty_gif_module.c
index d72983a..82bf8c5 100644
--- a/src/http/modules/ngx_http_empty_gif_module.c
+++ b/src/http/modules/ngx_http_empty_gif_module.c
@@ -112,7 +112,7 @@
     ngx_buf_t    *b;
     ngx_chain_t   out;
 
-    if (r->method != NGX_HTTP_GET && r->method != NGX_HTTP_HEAD) {
+    if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD))) {
         return NGX_HTTP_NOT_ALLOWED;
     }
 
diff --git a/src/http/modules/ngx_http_index_module.c b/src/http/modules/ngx_http_index_module.c
index 4326e73..d4bed45 100644
--- a/src/http/modules/ngx_http_index_module.c
+++ b/src/http/modules/ngx_http_index_module.c
@@ -143,7 +143,7 @@
         return NGX_DECLINED;
     }
 
-    if (r->method != NGX_HTTP_GET && r->method != NGX_HTTP_HEAD) {
+    if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD))) {
         return NGX_DECLINED;
     }
 
diff --git a/src/http/modules/ngx_http_log_module.c b/src/http/modules/ngx_http_log_module.c
index 07ac113..3afb6a3 100644
--- a/src/http/modules/ngx_http_log_module.c
+++ b/src/http/modules/ngx_http_log_module.c
@@ -128,7 +128,8 @@
       NULL },
 
     { ngx_string("access_log"),
-      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE123,
+      NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
+                        |NGX_CONF_TAKE123,
       ngx_http_log_set_log,
       NGX_HTTP_LOC_CONF_OFFSET,
       0,
diff --git a/src/http/modules/ngx_http_memcached_module.c b/src/http/modules/ngx_http_memcached_module.c
index 73c018e..ace8723 100644
--- a/src/http/modules/ngx_http_memcached_module.c
+++ b/src/http/modules/ngx_http_memcached_module.c
@@ -154,7 +154,7 @@
     ngx_http_memcached_ctx_t       *ctx;
     ngx_http_memcached_loc_conf_t  *mlcf;
 
-    if (r->method != NGX_HTTP_GET && r->method != NGX_HTTP_HEAD) {
+    if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD))) {
         return NGX_HTTP_NOT_ALLOWED;
     }
 
diff --git a/src/http/modules/ngx_http_ssi_filter_module.c b/src/http/modules/ngx_http_ssi_filter_module.c
index 82ee7ac..5024d00 100644
--- a/src/http/modules/ngx_http_ssi_filter_module.c
+++ b/src/http/modules/ngx_http_ssi_filter_module.c
@@ -188,6 +188,7 @@
 
 #define  NGX_HTTP_SSI_INCLUDE_VIRTUAL  0
 #define  NGX_HTTP_SSI_INCLUDE_FILE     1
+#define  NGX_HTTP_SSI_INCLUDE_WAIT     2
 
 #define  NGX_HTTP_SSI_ECHO_VAR         0
 #define  NGX_HTTP_SSI_ECHO_DEFAULT     1
@@ -204,6 +205,7 @@
 static ngx_http_ssi_param_t  ngx_http_ssi_include_params[] = {
     { ngx_string("virtual"), NGX_HTTP_SSI_INCLUDE_VIRTUAL, 0, 0 },
     { ngx_string("file"), NGX_HTTP_SSI_INCLUDE_FILE, 0, 0 },
+    { ngx_string("wait"), NGX_HTTP_SSI_INCLUDE_WAIT, 0, 0 },
     { ngx_null_string, 0, 0, 0 }
 };
 
@@ -361,7 +363,12 @@
 
     ctx = ngx_http_get_module_ctx(r, ngx_http_ssi_filter_module);
 
-    if (ctx == NULL || (in == NULL && ctx->in == NULL && ctx->busy == NULL)) {
+    if (ctx == NULL
+        || (in == NULL
+            && ctx->buf == NULL
+            && ctx->in == NULL
+            && ctx->busy == NULL))
+    {
         return ngx_http_next_body_filter(r, in);
     }
 
@@ -373,6 +380,19 @@
         }
     }
 
+    if (ctx->wait) {
+        if (r->connection->data != r) {
+            ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                           "http ssi filter \"%V\" wait", &r->uri);
+            return NGX_AGAIN;
+        }
+
+        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                       "http ssi filter \"%V\" continue", &r->uri);
+
+        ctx->wait = 0;
+    }
+
     slcf = ngx_http_get_module_loc_conf(r, ngx_http_ssi_filter_module);
 
     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
@@ -632,6 +652,10 @@
                     continue;
                 }
 
+                if (rc == NGX_AGAIN) {
+                    return NGX_AGAIN;
+                }
+
                 if (rc == NGX_ERROR) {
                     return NGX_ERROR;
                 }
@@ -782,8 +806,13 @@
 
         cl = ctx->busy;
         ctx->busy = cl->next;
-        cl->next = ctx->free;
-        ctx->free = cl;
+
+        if (ngx_buf_in_memory(b) || b->in_file) {
+            /* add data bufs only to the free buf chain */
+
+            cl->next = ctx->free;
+            ctx->free = cl;
+        }
     }
 
     return rc;
@@ -1626,11 +1655,13 @@
 ngx_http_ssi_include(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
     ngx_str_t **params)
 {
-    ngx_str_t   *uri, *file, args;
+    ngx_int_t    rc;
+    ngx_str_t   *uri, *file, *wait, args;
     ngx_uint_t   flags;
 
     uri = params[NGX_HTTP_SSI_INCLUDE_VIRTUAL];
     file = params[NGX_HTTP_SSI_INCLUDE_FILE];
+    wait = params[NGX_HTTP_SSI_INCLUDE_WAIT];
 
     if (uri && file) {
         ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
@@ -1645,6 +1676,26 @@
         return NGX_HTTP_SSI_ERROR;
     }
 
+    if (wait) {
+        if (uri == NULL) {
+            ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+                          "\"wait\" may not be used with file=\"%V\"",
+                          uri, file);
+            return NGX_HTTP_SSI_ERROR;
+        }
+
+        if (wait->len == 2 && ngx_strncasecmp(wait->data, "no", 2) == 0) {
+            wait = NULL;
+
+        } else if (wait->len != 3 || ngx_strncasecmp(wait->data, "yes", 3) != 0)
+        {
+            ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+                          "invalid value \"%V\" in the \"wait\" parameter",
+                          &wait);
+            return NGX_HTTP_SSI_ERROR;
+        }
+    }
+
     if (uri == NULL) {
         uri = file;
     }
@@ -1666,11 +1717,21 @@
         return NGX_HTTP_SSI_ERROR;
     }
 
-    if (ngx_http_subrequest(r, uri, &args, flags) != NGX_OK) {
+    rc = ngx_http_subrequest(r, uri, &args, flags);
+
+    if (rc == NGX_ERROR) {
         return NGX_HTTP_SSI_ERROR;
     }
 
-    return NGX_OK;
+    if (wait == NULL) {
+        return NGX_OK;
+    }
+
+    if (rc == NGX_AGAIN) {
+        ctx->wait = 1;
+    }
+
+    return rc;
 }
 
 
diff --git a/src/http/modules/ngx_http_ssi_filter_module.h b/src/http/modules/ngx_http_ssi_filter_module.h
index eff2360..0d9618b 100644
--- a/src/http/modules/ngx_http_ssi_filter_module.h
+++ b/src/http/modules/ngx_http_ssi_filter_module.h
@@ -61,6 +61,7 @@
     unsigned                  conditional:2;
     unsigned                  output:1;
     unsigned                  output_chosen:1;
+    unsigned                  wait:1;
 
     void                     *value_buf;
     ngx_str_t                 timefmt;
diff --git a/src/http/modules/ngx_http_static_module.c b/src/http/modules/ngx_http_static_module.c
index 3399e50..ad08852 100644
--- a/src/http/modules/ngx_http_static_module.c
+++ b/src/http/modules/ngx_http_static_module.c
@@ -86,7 +86,7 @@
     ngx_pool_cleanup_file_t   *clnf;
     ngx_http_core_loc_conf_t  *clcf;
 
-    if (r->method != NGX_HTTP_GET && r->method != NGX_HTTP_HEAD) {
+    if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD))) {
         return NGX_HTTP_NOT_ALLOWED;
     }
 
diff --git a/src/http/modules/perl/nginx.pm b/src/http/modules/perl/nginx.pm
index d87b2ec..badd494 100644
--- a/src/http/modules/perl/nginx.pm
+++ b/src/http/modules/perl/nginx.pm
@@ -17,7 +17,7 @@
     HTTP_SERVER_ERROR
 );
 
-our $VERSION = '0.3.23';
+our $VERSION = '0.3.43';
 
 require XSLoader;
 XSLoader::load('nginx', $VERSION);
diff --git a/src/http/ngx_http_core_module.c b/src/http/ngx_http_core_module.c
index 6279f34..931be88 100644
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -1168,7 +1168,7 @@
 
     sr = ngx_pcalloc(r->pool, sizeof(ngx_http_request_t));
     if (sr == NULL) {
-        return NGX_HTTP_INTERNAL_SERVER_ERROR;
+        return NGX_ERROR;
     }
 
     sr->signature = NGX_HTTP_MODULE;
@@ -1178,14 +1178,14 @@
 
     sr->ctx = ngx_pcalloc(r->pool, sizeof(void *) * ngx_http_max_module);
     if (sr->ctx == NULL) {
-        return NGX_HTTP_INTERNAL_SERVER_ERROR;
+        return NGX_ERROR;
     }
 
     if (ngx_list_init(&sr->headers_out.headers, r->pool, 20,
                       sizeof(ngx_table_elt_t))
         == NGX_ERROR)
     {
-        return NGX_HTTP_INTERNAL_SERVER_ERROR;
+        return NGX_ERROR;
     }
 
     cscf = ngx_http_get_module_srv_conf(r, ngx_http_core_module);
@@ -1228,7 +1228,7 @@
     sr->http_protocol = r->http_protocol;
 
     if (ngx_http_set_exten(sr) != NGX_OK) {
-        return NGX_HTTP_INTERNAL_SERVER_ERROR;
+        return NGX_ERROR;
     }
 
     sr->main = r->main;
@@ -1251,7 +1251,7 @@
 
     pr = ngx_palloc(r->pool, sizeof(ngx_http_postponed_request_t));
     if (pr == NULL) {
-        return NGX_HTTP_INTERNAL_SERVER_ERROR;
+        return NGX_ERROR;
     }
 
     pr->request = sr;
@@ -1275,10 +1275,18 @@
     ngx_http_handler(sr);
 
     if (!c->destroyed) {
-        sr->fast_subrequest = 0;
-
         ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
                        "http subrequest done \"%V?%V\"", uri, &sr->args);
+
+        if (sr->fast_subrequest) {
+            sr->fast_subrequest = 0;
+
+            if (sr->done) {
+                return NGX_OK;
+            }
+        }
+
+        return NGX_AGAIN;
     }
 
     return NGX_OK;
diff --git a/src/http/ngx_http_request.c b/src/http/ngx_http_request.c
index d801e2c..680b3bd 100644
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -958,7 +958,7 @@
     }
 
     if (n == 0 || n == NGX_ERROR) {
-        ngx_http_close_request(r, NGX_HTTP_BAD_REQUEST);
+        ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
         return NGX_ERROR;
     }
 
@@ -1480,17 +1480,24 @@
             }
 
             if (r->fast_subrequest) {
+
+                if (rc == NGX_AGAIN) {
+                    r->fast_subrequest = 0;
+                }
+
                 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                            "http fast subrequest: \"%V?%V\" done",
                            &r->uri, &r->args);
                 return;
             }
 
-            ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
-                           "http wake parent request: \"%V?%V\"",
-                           &pr->uri, &pr->args);
+            if (rc != NGX_AGAIN) {
+                ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                               "http wake parent request: \"%V?%V\"",
+                               &pr->uri, &pr->args);
 
-            pr->write_event_handler(pr);
+                pr->write_event_handler(pr);
+            }
         }
 
         return;