changeset 340:10cc350ed8a1 NGINX_0_6_14

nginx 0.6.14 *) Change: now by default the "echo" SSI command uses entity encoding. *) Feature: the "encoding" parameter in the "echo" SSI command. *) Feature: the "access_log" directive may be used inside the "limit_except" block. *) Bugfix: if all upstream servers were failed, then all servers had got weight the was equal one until servers became alive; bug appeared in 0.6.6. *) Bugfix: a segmentation fault occurred in worker process if $date_local and $date_gmt were used outside the ngx_http_ssi_filter_module. *) Bugfix: a segmentation fault might occur in worker process if debug log was enabled. Thanks to Andrei Nigmatulin. *) Bugfix: ngx_http_memcached_module did not set $upstream_response_time. Thanks to Maxim Dounin. *) Bugfix: a worker process may got caught in an endless loop, if the memcached was used. *) Bugfix: nginx supported low case only "close" and "keep-alive" values in the "Connection" request header line; bug appeared in 0.6.11. *) Bugfix: sub_filter did not work with empty substitution. *) Bugfix: in sub_filter parsing.
author Igor Sysoev <http://sysoev.ru>
date Mon, 15 Oct 2007 00:00:00 +0400
parents d19550b67059
children 183b4761fe5b
files CHANGES CHANGES.ru src/core/nginx.h src/core/ngx_conf_file.c src/core/ngx_inet.c src/core/ngx_inet.h src/core/ngx_string.c src/core/ngx_string.h src/event/ngx_event_busy_lock.c src/event/ngx_event_busy_lock.h src/event/ngx_event_pipe.c src/event/ngx_event_pipe.h src/http/modules/ngx_http_browser_module.c src/http/modules/ngx_http_empty_gif_module.c src/http/modules/ngx_http_fastcgi_module.c src/http/modules/ngx_http_flv_module.c src/http/modules/ngx_http_geo_module.c src/http/modules/ngx_http_gzip_filter_module.c src/http/modules/ngx_http_log_module.c src/http/modules/ngx_http_map_module.c src/http/modules/ngx_http_memcached_module.c src/http/modules/ngx_http_proxy_module.c src/http/modules/ngx_http_referer_module.c src/http/modules/ngx_http_rewrite_module.c src/http/modules/ngx_http_ssi_filter_module.c src/http/modules/ngx_http_ssi_filter_module.h src/http/modules/ngx_http_ssl_module.c src/http/modules/ngx_http_stub_status_module.c src/http/modules/ngx_http_sub_filter_module.c src/http/modules/ngx_http_userid_filter_module.c src/http/modules/perl/nginx.pm src/http/modules/perl/nginx.xs src/http/modules/perl/ngx_http_perl_module.c src/http/ngx_http_busy_lock.c src/http/ngx_http_busy_lock.h src/http/ngx_http_core_module.c src/http/ngx_http_request.c src/http/ngx_http_request.h src/http/ngx_http_script.c src/http/ngx_http_script.h src/http/ngx_http_upstream.c src/http/ngx_http_upstream.h src/http/ngx_http_upstream_round_robin.c src/http/ngx_http_variables.c src/http/ngx_http_variables.h src/mail/ngx_mail_auth_http_module.c src/mail/ngx_mail_core_module.c src/os/unix/ngx_process_cycle.c src/os/unix/ngx_solaris_init.c
diffstat 49 files changed, 561 insertions(+), 240 deletions(-) [+]
line wrap: on
line diff
--- a/CHANGES
+++ b/CHANGES
@@ -1,4 +1,41 @@
 
+Changes with nginx 0.6.14                                        15 Oct 2007
+
+    *) Change: now by default the "echo" SSI command uses entity encoding.
+
+    *) Feature: the "encoding" parameter in the "echo" SSI command.
+
+    *) Feature: the "access_log" directive may be used inside the 
+       "limit_except" block.
+
+    *) Bugfix: if all upstream servers were failed, then all servers had 
+       got weight the was equal one until servers became alive; bug 
+       appeared in 0.6.6.
+
+    *) Bugfix: a segmentation fault occurred in worker process if 
+       $date_local and $date_gmt were used outside the 
+       ngx_http_ssi_filter_module.
+
+    *) Bugfix: a segmentation fault might occur in worker process if debug 
+       log was enabled.
+       Thanks to Andrei Nigmatulin.
+
+    *) Bugfix: ngx_http_memcached_module did not set 
+       $upstream_response_time.
+       Thanks to Maxim Dounin.
+
+    *) Bugfix: a worker process may got caught in an endless loop, if the 
+       memcached was used.
+
+    *) Bugfix: nginx supported low case only "close" and "keep-alive" 
+       values in the "Connection" request header line; bug appeared in 
+       0.6.11.
+
+    *) Bugfix: sub_filter did not work with empty substitution.
+
+    *) Bugfix: in sub_filter parsing.
+
+
 Changes with nginx 0.6.13                                        24 Sep 2007
 
     *) Bugfix: nginx did not close directory file on HEAD request if 
--- a/CHANGES.ru
+++ b/CHANGES.ru
@@ -1,4 +1,42 @@
 
+Изменения в nginx 0.6.14                                          15.10.2007
+
+    *) Изменение: теперь по умолчанию команда SSI echo использует 
+       кодирование entity.
+
+    *) Добавление: параметр encoding в команде SSI echo.
+
+    *) Добавление: директиву access_log можно использовать внутри блока 
+       limit_except.
+
+    *) Исправление: если все сервера апстрима оказывались недоступными, то 
+       до восстановления работоспособности у всех серверов вес становился 
+       равным одному; ошибка появилась в 0.6.6.
+
+    *) Исправление: при использовании переменных $date_local и $date_gmt 
+       вне модуля ngx_http_ssi_filter_module в рабочем процессе происходил 
+       segmentation fault.
+
+    *) Исправление: при использовании включённом отладочном логе в рабочем 
+       процессе мог произойти segmentation fault.
+       Спасибо Андрею Нигматулину.
+
+    *) Исправление: ngx_http_memcached_module не устанавливал 
+       upstream_response_time.
+       Спасибо Максиму Дунину.
+
+    *) Исправление: рабочий процесс мог зациклиться при использовании 
+       memcached.
+
+    *) Исправление: nginx распознавал параметры "close" и "keep-alive" в 
+       строке "Connection" в заголовке запроса только, если они были в 
+       нижнем регистре; ошибка появилась в 0.6.11.
+
+    *) Исправление: sub_filter не работал с пустую строку замены.
+
+    *) Исправление: в парсинге sub_filter.
+
+
 Изменения в nginx 0.6.13                                          24.09.2007
 
     *) Исправление: nginx не закрывал файл каталога для запроса HEAD, если 
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -8,7 +8,7 @@
 #define _NGINX_H_INCLUDED_
 
 
-#define NGINX_VERSION      "0.6.13"
+#define NGINX_VERSION      "0.6.14"
 #define NGINX_VER          "nginx/" NGINX_VERSION
 
 #define NGINX_VAR          "NGINX"
--- a/src/core/ngx_conf_file.c
+++ b/src/core/ngx_conf_file.c
@@ -117,7 +117,7 @@ ngx_conf_parse(ngx_conf_t *cf, ngx_str_t
         cf->conf_file->file.name.len = filename->len;
         cf->conf_file->file.name.data = filename->data;
         cf->conf_file->file.offset = 0;
-        cf->conf_file->file.log = cf->log;;
+        cf->conf_file->file.log = cf->log;
         cf->conf_file->line = 1;
 
         block = 0;
--- a/src/core/ngx_inet.c
+++ b/src/core/ngx_inet.c
@@ -225,7 +225,7 @@ ngx_ptocidr(ngx_str_t *text, void *cidr)
 
 
 ngx_int_t
-ngx_parse_url(ngx_conf_t *cf, ngx_url_t *u)
+ngx_parse_url(ngx_pool_t *pool, ngx_url_t *u)
 {
     u_char              *p, *host, *port_start;
     size_t               len, port_len;
@@ -273,12 +273,12 @@ ngx_parse_url(ngx_conf_t *cf, ngx_url_t 
             return NGX_ERROR;
         }
 
-        u->addrs = ngx_pcalloc(cf->pool, sizeof(ngx_peer_addr_t));
+        u->addrs = ngx_pcalloc(pool, sizeof(ngx_peer_addr_t));
         if (u->addrs == NULL) {
             return NGX_ERROR;
         }
 
-        saun = ngx_pcalloc(cf->pool, sizeof(struct sockaddr_un));
+        saun = ngx_pcalloc(pool, sizeof(struct sockaddr_un));
         if (saun == NULL) {
             return NGX_ERROR;
         }
@@ -408,12 +408,12 @@ no_port:
 
         if (u->host.len) {
 
-           host = ngx_palloc(cf->temp_pool, u->host.len + 1);
-           if (host == NULL) {
-               return NGX_ERROR;
-           }
+            host = ngx_alloc(u->host.len + 1, pool->log);
+            if (host == NULL) {
+                return NGX_ERROR;
+            }
 
-           (void) ngx_cpystrn(host, u->host.data, u->host.len + 1);
+            (void) ngx_cpystrn(host, u->host.data, u->host.len + 1);
 
             u->addr.in_addr = inet_addr((const char *) host);
 
@@ -421,6 +421,7 @@ no_port:
                 h = gethostbyname((const char *) host);
 
                 if (h == NULL || h->h_addr_list[0] == NULL) {
+                    ngx_free(host);
                     u->err = "host not found";
                     return NGX_ERROR;
                 }
@@ -428,6 +429,8 @@ no_port:
                 u->addr.in_addr = *(in_addr_t *) (h->h_addr_list[0]);
             }
 
+            ngx_free(host);
+
         } else {
             u->addr.in_addr = INADDR_ANY;
         }
@@ -453,7 +456,7 @@ no_port:
         return NGX_ERROR;
     }
 
-    if (ngx_inet_resolve_host(cf, u) != NGX_OK) {
+    if (ngx_inet_resolve_host(pool, u) != NGX_OK) {
         return NGX_ERROR;
     }
 
@@ -462,7 +465,7 @@ no_port:
 
 
 ngx_int_t
-ngx_inet_resolve_host(ngx_conf_t *cf, ngx_url_t *u)
+ngx_inet_resolve_host(ngx_pool_t *pool, ngx_url_t *u)
 {
     u_char              *p, *host;
     size_t               len;
@@ -471,7 +474,7 @@ ngx_inet_resolve_host(ngx_conf_t *cf, ng
     struct hostent      *h;
     struct sockaddr_in  *sin;
 
-    host = ngx_palloc(cf->temp_pool, u->host.len + 1);
+    host = ngx_alloc(u->host.len + 1, pool->log);
     if (host == NULL) {
         return NGX_ERROR;
     }
@@ -485,6 +488,8 @@ ngx_inet_resolve_host(ngx_conf_t *cf, ng
     if (in_addr == INADDR_NONE) {
         h = gethostbyname((char *) host);
 
+        ngx_free(host);
+
         if (h == NULL || h->h_addr_list[0] == NULL) {
             u->err = "host not found";
             return NGX_ERROR;
@@ -499,7 +504,7 @@ ngx_inet_resolve_host(ngx_conf_t *cf, ng
 
         /* MP: ngx_shared_palloc() */
 
-        u->addrs = ngx_pcalloc(cf->pool, i * sizeof(ngx_peer_addr_t));
+        u->addrs = ngx_pcalloc(pool, i * sizeof(ngx_peer_addr_t));
         if (u->addrs == NULL) {
             return NGX_ERROR;
         }
@@ -508,7 +513,7 @@ ngx_inet_resolve_host(ngx_conf_t *cf, ng
 
         for (i = 0; h->h_addr_list[i] != NULL; i++) {
 
-            sin = ngx_pcalloc(cf->pool, sizeof(struct sockaddr_in));
+            sin = ngx_pcalloc(pool, sizeof(struct sockaddr_in));
             if (sin == NULL) {
                 return NGX_ERROR;
             }
@@ -522,7 +527,7 @@ ngx_inet_resolve_host(ngx_conf_t *cf, ng
 
             len = INET_ADDRSTRLEN - 1 + 1 + sizeof(":65536") - 1;
 
-            p = ngx_palloc(cf->pool, len);
+            p = ngx_palloc(pool, len);
             if (p == NULL) {
                 return NGX_ERROR;
             }
@@ -535,14 +540,16 @@ ngx_inet_resolve_host(ngx_conf_t *cf, ng
 
     } else {
 
+        ngx_free(host);
+
         /* MP: ngx_shared_palloc() */
 
-        u->addrs = ngx_pcalloc(cf->pool, sizeof(ngx_peer_addr_t));
+        u->addrs = ngx_pcalloc(pool, sizeof(ngx_peer_addr_t));
         if (u->addrs == NULL) {
             return NGX_ERROR;
         }
 
-        sin = ngx_pcalloc(cf->pool, sizeof(struct sockaddr_in));
+        sin = ngx_pcalloc(pool, sizeof(struct sockaddr_in));
         if (sin == NULL) {
             return NGX_ERROR;
         }
@@ -556,7 +563,7 @@ ngx_inet_resolve_host(ngx_conf_t *cf, ng
         u->addrs[0].sockaddr = (struct sockaddr *) sin;
         u->addrs[0].socklen = sizeof(struct sockaddr_in);
 
-        p = ngx_palloc(cf->pool, u->host.len + sizeof(":65536") - 1);
+        p = ngx_palloc(pool, u->host.len + sizeof(":65536") - 1);
         if (p == NULL) {
             return NGX_ERROR;
         }
--- a/src/core/ngx_inet.h
+++ b/src/core/ngx_inet.h
@@ -61,8 +61,8 @@ typedef struct {
 size_t ngx_sock_ntop(int family, struct sockaddr *sa, u_char *text, size_t len);
 size_t ngx_inet_ntop(int family, void *addr, u_char *text, size_t len);
 ngx_int_t ngx_ptocidr(ngx_str_t *text, void *cidr);
-ngx_int_t ngx_parse_url(ngx_conf_t *cf, ngx_url_t *u);
-ngx_int_t ngx_inet_resolve_host(ngx_conf_t *cf, ngx_url_t *u);
+ngx_int_t ngx_parse_url(ngx_pool_t *pool, ngx_url_t *u);
+ngx_int_t ngx_inet_resolve_host(ngx_pool_t *pool, ngx_url_t *u);
 
 
 
--- a/src/core/ngx_string.c
+++ b/src/core/ngx_string.c
@@ -442,7 +442,7 @@ ngx_vsnprintf(u_char *buf, size_t max, c
 
 
 /*
- * We use ngx_strcasecmp()/ngx_strncasecmp() for 7-bit ASCII string only,
+ * We use ngx_strcasecmp()/ngx_strncasecmp() for 7-bit ASCII strings only,
  * and implement our own ngx_strcasecmp()/ngx_strncasecmp()
  * to avoid libc locale overhead.  Besides, we use the ngx_uint_t's
  * instead of the u_char's, because they are slightly faster.
@@ -503,6 +503,95 @@ ngx_strncasecmp(u_char *s1, u_char *s2, 
 }
 
 
+u_char *
+ngx_strnstr(u_char *s1, char *s2, size_t len)
+{
+    u_char  c1, c2;
+    size_t  n;
+
+    c2 = *(u_char *) s2++;
+
+    n = ngx_strlen(s2);
+
+    do {
+        do {
+            if (len-- == 0) {
+                return NULL;
+            }
+
+            c1 = *s1++;
+
+            if (c1 == 0) {
+                return NULL;
+            }
+
+        } while (c1 != c2);
+
+        if (n > len) {
+            return NULL;
+        }
+
+    } while (ngx_strncmp(s1, (u_char *) s2, n) != 0);
+
+    return --s1;
+}
+
+
+/*
+ * ngx_strstrn() and ngx_strcasestrn() are intended to search for static
+ * substring with known length in null-terminated string. The argument n
+ * must be length of the second substring - 1.
+ */
+
+u_char *
+ngx_strstrn(u_char *s1, char *s2, size_t n)
+{
+    u_char  c1, c2;
+
+    c2 = *(u_char *) s2++;
+
+    do {
+        do {
+            c1 = *s1++;
+
+            if (c1 == 0) {
+                return NULL;
+            }
+
+        } while (c1 != c2);
+
+    } while (ngx_strncmp(s1, (u_char *) s2, n) != 0);
+
+    return --s1;
+}
+
+
+u_char *
+ngx_strcasestrn(u_char *s1, char *s2, size_t n)
+{
+    ngx_uint_t  c1, c2;
+
+    c2 = (ngx_uint_t) *s2++;
+    c2  = (c2 >= 'A' && c2 <= 'Z') ? (c2 | 0x20) : c2;
+
+    do {
+        do {
+            c1 = (ngx_uint_t) *s1++;
+
+            if (c1 == 0) {
+                return NULL;
+            }
+
+            c1  = (c1 >= 'A' && c1 <= 'Z') ? (c1 | 0x20) : c1;
+
+        } while (c1 != c2);
+
+    } while (ngx_strncasecmp(s1, (u_char *) s2, n) != 0);
+
+    return --s1;
+}
+
+
 ngx_int_t
 ngx_rstrncmp(u_char *s1, u_char *s2, size_t n)
 {
@@ -1250,6 +1339,67 @@ done:
 }
 
 
+uintptr_t
+ngx_escape_html(u_char *dst, u_char *src, size_t size)
+{
+    u_char      ch;
+    ngx_uint_t  i, len;
+
+    if (dst == NULL) {
+
+        len = 0;
+
+        for (i = 0; i < size; i++) {
+            switch (*src++) {
+
+            case '<':
+                len += sizeof("&lt;") - 2;
+                break;
+
+            case '>':
+                len += sizeof("&gt;") - 2;
+                break;
+
+            case '&':
+                len += sizeof("&amp;") - 2;
+                break;
+
+            default:
+                break;
+            }
+        }
+
+        return (uintptr_t) len;
+    }
+
+    for (i = 0; i < size; i++) {
+        ch = *src++;
+
+        switch (ch) {
+
+        case '<':
+            *dst++ = '&'; *dst++ = 'l'; *dst++ = 't'; *dst++ = ';';
+            break;
+
+        case '>':
+            *dst++ = '&'; *dst++ = 'g'; *dst++ = 't'; *dst++ = ';';
+            break;
+
+        case '&':
+            *dst++ = '&'; *dst++ = 'a'; *dst++ = 'm'; *dst++ = 'p';
+            *dst++ = ';';
+            break;
+
+        default:
+            *dst++ = ch;
+            break;
+        }
+    }
+
+    return (uintptr_t) dst;
+}
+
+
 /* ngx_sort() is implemented as insertion sort because we need stable sort */
 
 void
--- a/src/core/ngx_string.h
+++ b/src/core/ngx_string.h
@@ -28,7 +28,7 @@ typedef struct {
     unsigned    len:29;
 
     unsigned    valid:1;
-    unsigned    no_cachable:1;
+    unsigned    no_cacheable:1;
     unsigned    not_found:1;
 
     u_char     *data;
@@ -126,6 +126,11 @@ u_char *ngx_vsnprintf(u_char *buf, size_
 ngx_int_t ngx_strcasecmp(u_char *s1, u_char *s2);
 ngx_int_t ngx_strncasecmp(u_char *s1, u_char *s2, size_t n);
 
+u_char *ngx_strnstr(u_char *s1, char *s2, size_t n);
+
+u_char *ngx_strstrn(u_char *s1, char *s2, size_t n);
+u_char *ngx_strcasestrn(u_char *s1, char *s2, size_t n);
+
 ngx_int_t ngx_rstrncmp(u_char *s1, u_char *s2, size_t n);
 ngx_int_t ngx_rstrncasecmp(u_char *s1, u_char *s2, size_t n);
 ngx_int_t ngx_memn2cmp(u_char *s1, u_char *s2, size_t n1, size_t n2);
@@ -162,6 +167,8 @@ u_char *ngx_utf_cpystrn(u_char *dst, u_c
 uintptr_t ngx_escape_uri(u_char *dst, u_char *src, size_t size,
     ngx_uint_t type);
 void ngx_unescape_uri(u_char **dst, u_char **src, size_t size, ngx_uint_t type);
+uintptr_t ngx_escape_html(u_char *dst, u_char *src, size_t size);
+
 
 
 void ngx_sort(void *base, size_t n, size_t size,
--- a/src/event/ngx_event_busy_lock.c
+++ b/src/event/ngx_event_busy_lock.c
@@ -9,7 +9,7 @@
 #include <ngx_event.h>
 
 
-static ngx_int_t ngx_event_busy_lock_look_cachable(ngx_event_busy_lock_t *bl,
+static ngx_int_t ngx_event_busy_lock_look_cacheable(ngx_event_busy_lock_t *bl,
     ngx_event_busy_lock_ctx_t *ctx);
 static void ngx_event_busy_lock_handler(ngx_event_t *ev);
 static void ngx_event_busy_lock_posted_handler(ngx_event_t *ev);
@@ -65,14 +65,14 @@ ngx_event_busy_lock(ngx_event_busy_lock_
 
 
 ngx_int_t
-ngx_event_busy_lock_cachable(ngx_event_busy_lock_t *bl,
+ngx_event_busy_lock_cacheable(ngx_event_busy_lock_t *bl,
     ngx_event_busy_lock_ctx_t *ctx)
 {
     ngx_int_t  rc;
 
     ngx_mutex_lock(bl->mutex);
 
-    rc = ngx_event_busy_lock_look_cachable(bl, ctx);
+    rc = ngx_event_busy_lock_look_cacheable(bl, ctx);
 
     ngx_log_debug3(NGX_LOG_DEBUG_EVENT, ctx->event->log, 0,
                    "event busy lock: %d w:%d mw:%d",
@@ -201,14 +201,14 @@ ngx_event_busy_lock_cancel(ngx_event_bus
 
 
 static ngx_int_t
-ngx_event_busy_lock_look_cachable(ngx_event_busy_lock_t *bl,
+ngx_event_busy_lock_look_cacheable(ngx_event_busy_lock_t *bl,
     ngx_event_busy_lock_ctx_t *ctx)
 {
     ngx_int_t    free;
-    ngx_uint_t   i, bit, cachable, mask;
+    ngx_uint_t   i, bit, cacheable, mask;
 
     bit = 0;
-    cachable = 0;
+    cacheable = 0;
     free = -1;
 
 #if (NGX_SUPPRESS_WARN)
@@ -227,14 +227,14 @@ ngx_event_busy_lock_look_cachable(ngx_ev
                 ctx->slot = i;
                 return NGX_AGAIN;
             }
-            cachable++;
+            cacheable++;
 
         } else if (free == -1) {
             free = i;
         }
 
-        if (cachable == bl->cachable) {
-            if (free == -1 && cachable < bl->max_busy) {
+        if (cacheable == bl->cacheable) {
+            if (free == -1 && cacheable < bl->max_busy) {
                 free = i + 1;
             }
 
@@ -259,7 +259,7 @@ ngx_event_busy_lock_look_cachable(ngx_ev
     bl->md5_mask[free / 8] |= 1 << (free & 7);
     ctx->slot = free;
 
-    bl->cachable++;
+    bl->cacheable++;
     bl->busy++;
 
     return NGX_OK;
--- a/src/event/ngx_event_busy_lock.h
+++ b/src/event/ngx_event_busy_lock.h
@@ -34,7 +34,7 @@ struct ngx_event_busy_lock_ctx_s {
 typedef struct {
     u_char                     *md5_mask;
     char                       *md5;
-    ngx_uint_t                  cachable;
+    ngx_uint_t                  cacheable;
 
     ngx_uint_t                  busy;
     ngx_uint_t                  max_busy;
@@ -53,7 +53,7 @@ typedef struct {
 
 ngx_int_t ngx_event_busy_lock(ngx_event_busy_lock_t *bl,
     ngx_event_busy_lock_ctx_t *ctx);
-ngx_int_t ngx_event_busy_lock_cachable(ngx_event_busy_lock_t *bl,
+ngx_int_t ngx_event_busy_lock_cacheable(ngx_event_busy_lock_t *bl,
     ngx_event_busy_lock_ctx_t *ctx);
 void ngx_event_busy_unlock(ngx_event_busy_lock_t *bl,
     ngx_event_busy_lock_ctx_t *ctx);
--- a/src/event/ngx_event_pipe.c
+++ b/src/event/ngx_event_pipe.c
@@ -192,7 +192,7 @@ ngx_event_pipe_read_upstream(ngx_event_p
                 chain->buf = b;
                 chain->next = NULL;
 
-            } else if (!p->cachable
+            } else if (!p->cacheable
                        && p->downstream->data == p->output_ctx
                        && p->downstream->write->ready
                        && !p->downstream->write->delayed)
@@ -209,7 +209,7 @@ ngx_event_pipe_read_upstream(ngx_event_p
 
                 break;
 
-            } else if (p->cachable
+            } else if (p->cacheable
                        || p->temp_file->offset < p->max_temp_file_size)
             {
 
@@ -406,7 +406,7 @@ ngx_event_pipe_read_upstream(ngx_event_p
         }
     }
 
-    if (p->cachable && p->in) {
+    if (p->cacheable && p->in) {
         if (ngx_event_pipe_write_chain_to_temp_file(p) == NGX_ABORT) {
             return NGX_ABORT;
         }
@@ -542,7 +542,7 @@ ngx_event_pipe_write_to_downstream(ngx_e
 
                 ngx_event_pipe_free_shadow_raw_buf(&p->free_raw_bufs, cl->buf);
 
-            } else if (!p->cachable && p->in) {
+            } else if (!p->cacheable && p->in) {
                 cl = p->in;
 
                 ngx_log_debug3(NGX_LOG_DEBUG_EVENT, p->log, 0,
@@ -612,7 +612,7 @@ ngx_event_pipe_write_to_downstream(ngx_e
         for (cl = p->free; cl; cl = cl->next) {
 
             if (cl->buf->temp_file) {
-                if (p->cachable || !p->cyclic_temp_file) {
+                if (p->cacheable || !p->cyclic_temp_file) {
                     continue;
                 }
 
@@ -659,7 +659,7 @@ ngx_event_pipe_write_chain_to_temp_file(
         out = p->in;
     }
 
-    if (!p->cachable) {
+    if (!p->cacheable) {
 
         size = 0;
         cl = out;
--- a/src/event/ngx_event_pipe.h
+++ b/src/event/ngx_event_pipe.h
@@ -47,7 +47,7 @@ struct ngx_event_pipe_s {
     void                             *output_ctx;
 
     unsigned           read:1;
-    unsigned           cachable:1;
+    unsigned           cacheable:1;
     unsigned           single_buf:1;
     unsigned           free_bufs:1;
     unsigned           upstream_done:1;
--- a/src/http/modules/ngx_http_browser_module.c
+++ b/src/http/modules/ngx_http_browser_module.c
@@ -397,7 +397,7 @@ ngx_http_browser_add_variable(ngx_conf_t
 
     for (var = ngx_http_browsers; var->name.len; var++) {
 
-        v = ngx_http_add_variable(cf, &var->name, NGX_HTTP_VAR_CHANGABLE);
+        v = ngx_http_add_variable(cf, &var->name, NGX_HTTP_VAR_CHANGEABLE);
         if (v == NULL) {
             return NGX_ERROR;
         }
@@ -673,7 +673,7 @@ ngx_http_modern_browser_value(ngx_conf_t
 
     bcf->modern_browser_value->len = value[1].len;
     bcf->modern_browser_value->valid = 1;
-    bcf->modern_browser_value->no_cachable = 0;
+    bcf->modern_browser_value->no_cacheable = 0;
     bcf->modern_browser_value->not_found = 0;
     bcf->modern_browser_value->data = value[1].data;
 
@@ -698,7 +698,7 @@ ngx_http_ancient_browser_value(ngx_conf_
 
     bcf->ancient_browser_value->len = value[1].len;
     bcf->ancient_browser_value->valid = 1;
-    bcf->ancient_browser_value->no_cachable = 0;
+    bcf->ancient_browser_value->no_cacheable = 0;
     bcf->ancient_browser_value->not_found = 0;
     bcf->ancient_browser_value->data = value[1].data;
 
--- a/src/http/modules/ngx_http_empty_gif_module.c
+++ b/src/http/modules/ngx_http_empty_gif_module.c
@@ -127,6 +127,8 @@ ngx_http_empty_gif_handler(ngx_http_requ
 
     if (r->method == NGX_HTTP_HEAD) {
         r->headers_out.status = NGX_HTTP_OK;
+        r->headers_out.content_length_n = sizeof(ngx_empty_gif);
+        r->headers_out.last_modified_time = 23349600;
 
         return ngx_http_send_header(r);
     }
--- a/src/http/modules/ngx_http_fastcgi_module.c
+++ b/src/http/modules/ngx_http_fastcgi_module.c
@@ -505,7 +505,7 @@ ngx_http_fastcgi_create_request(ngx_http
     if (flcf->params_len) {
         ngx_memzero(&le, sizeof(ngx_http_script_engine_t));
 
-        ngx_http_script_flush_no_cachable_variables(r, flcf->flushes);
+        ngx_http_script_flush_no_cacheable_variables(r, flcf->flushes);
         le.flushed = 1;
 
         le.ip = flcf->params_len->elts;
@@ -1186,8 +1186,8 @@ ngx_http_fastcgi_process_header(ngx_http
 
                 u->state->status = u->headers_in.status_n;
 #if 0
-                if (u->cachable) {
-                    u->cachable = ngx_http_upstream_is_cachable(r);
+                if (u->cacheable) {
+                    u->cacheable = ngx_http_upstream_is_cacheable(r);
                 }
 #endif
 
@@ -1610,7 +1610,7 @@ ngx_http_fastcgi_add_variables(ngx_conf_
     ngx_http_variable_t  *var;
 
     var = ngx_http_add_variable(cf, &ngx_http_fastcgi_script_name,
-                                NGX_HTTP_VAR_NOHASH|NGX_HTTP_VAR_NOCACHABLE);
+                                NGX_HTTP_VAR_NOHASH|NGX_HTTP_VAR_NOCACHEABLE);
     if (var == NULL) {
         return NGX_ERROR;
     }
@@ -2104,7 +2104,7 @@ ngx_http_fastcgi_script_name_variable(ng
 
     if (r->uri.len) {
         v->valid = 1;
-        v->no_cachable = 0;
+        v->no_cacheable = 0;
         v->not_found = 0;
 
         flcf = ngx_http_get_module_loc_conf(r, ngx_http_fastcgi_module);
@@ -2128,7 +2128,7 @@ ngx_http_fastcgi_script_name_variable(ng
     } else {
         v->len = 0;
         v->valid = 1;
-        v->no_cachable = 0;
+        v->no_cacheable = 0;
         v->not_found = 0;
         v->data = NULL;
 
@@ -2215,7 +2215,7 @@ ngx_http_fastcgi_store(ngx_conf_t *cf, n
     sc.source = &value[1];
     sc.lengths = &flcf->upstream.store_lengths;
     sc.values = &flcf->upstream.store_values;
-    sc.variables = ngx_http_script_variables_count(&value[1]);;
+    sc.variables = ngx_http_script_variables_count(&value[1]);
     sc.complete_lengths = 1;
     sc.complete_values = 1;
 
--- a/src/http/modules/ngx_http_flv_module.c
+++ b/src/http/modules/ngx_http_flv_module.c
@@ -110,7 +110,7 @@ ngx_http_flv_handler(ngx_http_request_t 
     of.retest = clcf->open_file_cache_retest;
     of.errors = clcf->open_file_cache_errors;
     of.events = clcf->open_file_cache_events;
-    
+
     rc = ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool);
 
     if (rc == NGX_ERROR) {
@@ -166,7 +166,7 @@ ngx_http_flv_handler(ngx_http_request_t 
     i = 1;
 
     if (r->args.len) {
-        p = (u_char *) ngx_strstr(r->args.data, "start=");
+        p = (u_char *) ngx_strnstr(r->args.data, "start=", r->args.len);
 
         if (p) {
             p += 6;
--- a/src/http/modules/ngx_http_geo_module.c
+++ b/src/http/modules/ngx_http_geo_module.c
@@ -116,7 +116,7 @@ ngx_http_geo_block(ngx_conf_t *cf, ngx_c
         name.data++;
     }
 
-    var = ngx_http_add_variable(cf, &name, NGX_HTTP_VAR_CHANGABLE);
+    var = ngx_http_add_variable(cf, &name, NGX_HTTP_VAR_CHANGEABLE);
     if (var == NULL) {
         return NGX_CONF_ERROR;
     }
@@ -257,7 +257,7 @@ ngx_http_geo(ngx_conf_t *cf, ngx_command
         }
 
         var->valid = 1;
-        var->no_cachable = 0;
+        var->no_cacheable = 0;
         var->not_found = 0;
 
         v = ngx_array_push(&ctx->values);
--- a/src/http/modules/ngx_http_gzip_filter_module.c
+++ b/src/http/modules/ngx_http_gzip_filter_module.c
@@ -279,7 +279,9 @@ ngx_http_gzip_header_filter(ngx_http_req
         || r->headers_in.accept_encoding == NULL
         || (r->headers_out.content_length_n != -1
             && r->headers_out.content_length_n < conf->min_length)
-        || ngx_strstr(r->headers_in.accept_encoding->value.data, "gzip") == NULL
+        || ngx_strcasestrn(r->headers_in.accept_encoding->value.data,
+                           "gzip", 4 - 1)
+           == NULL
        )
     {
         return ngx_http_next_header_filter(r);
@@ -938,7 +940,7 @@ ngx_http_gzip_ratio_variable(ngx_http_re
     ngx_http_gzip_ctx_t  *ctx;
 
     v->valid = 1;
-    v->no_cachable = 0;
+    v->no_cacheable = 0;
     v->not_found = 0;
 
     ctx = ngx_http_get_module_ctx(r, ngx_http_gzip_filter_module);
--- a/src/http/modules/ngx_http_log_module.c
+++ b/src/http/modules/ngx_http_log_module.c
@@ -114,7 +114,7 @@ static ngx_command_t  ngx_http_log_comma
 
     { ngx_string("access_log"),
       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_HTTP_LIF_CONF
-                        |NGX_CONF_TAKE123,
+                        |NGX_HTTP_LMT_CONF|NGX_CONF_TAKE123,
       ngx_http_log_set_log,
       NGX_HTTP_LOC_CONF_OFFSET,
       0,
--- a/src/http/modules/ngx_http_map_module.c
+++ b/src/http/modules/ngx_http_map_module.c
@@ -221,7 +221,7 @@ ngx_http_map_block(ngx_conf_t *cf, ngx_c
     name.len--;
     name.data++;
 
-    var = ngx_http_add_variable(cf, &name, NGX_HTTP_VAR_CHANGABLE);
+    var = ngx_http_add_variable(cf, &name, NGX_HTTP_VAR_CHANGEABLE);
     if (var == NULL) {
         return NGX_CONF_ERROR;
     }
@@ -430,7 +430,7 @@ ngx_http_map(ngx_conf_t *cf, ngx_command
     }
 
     var->valid = 1;
-    var->no_cachable = 0;
+    var->no_cacheable = 0;
     var->not_found = 0;
 
     vp = ngx_array_push(&ctx->values_hash[key]);
--- a/src/http/modules/ngx_http_memcached_module.c
+++ b/src/http/modules/ngx_http_memcached_module.c
@@ -371,6 +371,7 @@ found:
         }
 
         u->headers_in.status_n = 200;
+        u->state->status = 200;
         u->buffer.pos = p + 1;
 
         return NGX_OK;
@@ -381,6 +382,7 @@ found:
                       "key: \"%V\" was not found by memcached", &ctx->key);
 
         u->headers_in.status_n = 404;
+        u->state->status = 404;
 
         return NGX_OK;
     }
@@ -425,16 +427,16 @@ ngx_http_memcached_filter(void *data, ss
     if (u->length == ctx->rest) {
 
         if (ngx_strncmp(b->last,
-                        ngx_http_memcached_end + NGX_HTTP_MEMCACHED_END
-                                                 - ctx->rest,
-                        bytes) != 0)
+                   ngx_http_memcached_end + NGX_HTTP_MEMCACHED_END - ctx->rest,
+                   ctx->rest)
+            != 0)
         {
             ngx_log_error(NGX_LOG_ERR, ctx->request->connection->log, 0,
                           "memcached sent invalid trailer");
         }
 
-        u->length -= bytes;
-        ctx->rest -= bytes;
+        u->length = 0;
+        ctx->rest = 0;
 
         return NGX_OK;
     }
@@ -453,7 +455,8 @@ ngx_http_memcached_filter(void *data, ss
 
     *ll = cl;
 
-    cl->buf->pos = b->last;
+    last = b->last;
+    cl->buf->pos = last;
     b->last += bytes;
     cl->buf->last = b->last;
 
@@ -461,20 +464,19 @@ ngx_http_memcached_filter(void *data, ss
                    "memcached filter bytes:%z size:%z length:%z rest:%z",
                    bytes, b->last - b->pos, u->length, ctx->rest);
 
-    if (b->last - b->pos <= (ssize_t) (u->length - NGX_HTTP_MEMCACHED_END)) {
+    if (bytes <= (ssize_t) (u->length - NGX_HTTP_MEMCACHED_END)) {
         u->length -= bytes;
         return NGX_OK;
     }
 
-
-    last = b->pos + u->length - NGX_HTTP_MEMCACHED_END;
+    last += u->length - NGX_HTTP_MEMCACHED_END;
 
     if (ngx_strncmp(last, ngx_http_memcached_end, b->last - last) != 0) {
         ngx_log_error(NGX_LOG_ERR, ctx->request->connection->log, 0,
                       "memcached sent invalid trailer");
     }
 
-    ctx->rest = u->length - (b->last - b->pos);
+    ctx->rest -= b->last - last;
     b->last = last;
     cl->buf->last = last;
     u->length = ctx->rest;
--- a/src/http/modules/ngx_http_proxy_module.c
+++ b/src/http/modules/ngx_http_proxy_module.c
@@ -420,10 +420,10 @@ static ngx_str_t  ngx_http_proxy_hide_he
 static ngx_http_variable_t  ngx_http_proxy_vars[] = {
 
     { ngx_string("proxy_host"), NULL, ngx_http_proxy_host_variable, 0,
-      NGX_HTTP_VAR_CHANGABLE|NGX_HTTP_VAR_NOHASH, 0 },
+      NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOHASH, 0 },
 
     { ngx_string("proxy_port"), NULL, ngx_http_proxy_port_variable, 0,
-      NGX_HTTP_VAR_CHANGABLE|NGX_HTTP_VAR_NOHASH, 0 },
+      NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOHASH, 0 },
 
     { ngx_string("proxy_add_x_forwarded_for"), NULL,
       ngx_http_proxy_add_x_forwarded_for_variable, 0, NGX_HTTP_VAR_NOHASH, 0 },
@@ -561,7 +561,7 @@ ngx_http_proxy_create_request(ngx_http_r
         len += r->uri.len - loc_len + escape + sizeof("?") - 1 + r->args.len;
     }
 
-    ngx_http_script_flush_no_cachable_variables(r, plcf->flushes);
+    ngx_http_script_flush_no_cacheable_variables(r, plcf->flushes);
 
     if (plcf->body_set_len) {
         le.ip = plcf->body_set_len->elts;
@@ -1249,7 +1249,7 @@ ngx_http_proxy_host_variable(ngx_http_re
 
     v->len = plcf->host_header.len;
     v->valid = 1;
-    v->no_cachable = 0;
+    v->no_cacheable = 0;
     v->not_found = 0;
     v->data = plcf->host_header.data;
 
@@ -1267,7 +1267,7 @@ ngx_http_proxy_port_variable(ngx_http_re
 
     v->len = plcf->port.len;
     v->valid = 1;
-    v->no_cachable = 0;
+    v->no_cacheable = 0;
     v->not_found = 0;
     v->data = plcf->port.data;
 
@@ -1282,7 +1282,7 @@ ngx_http_proxy_add_x_forwarded_for_varia
     u_char  *p;
 
     v->valid = 1;
-    v->no_cachable = 0;
+    v->no_cacheable = 0;
     v->not_found = 0;
 
     if (r->headers_in.x_forwarded_for == NULL) {
@@ -1326,7 +1326,7 @@ ngx_http_proxy_internal_body_length_vari
     }
 
     v->valid = 1;
-    v->no_cachable = 0;
+    v->no_cacheable = 0;
     v->not_found = 0;
 
     v->data = ngx_palloc(r->connection->pool, NGX_SIZE_T_LEN);
@@ -2429,7 +2429,7 @@ ngx_http_proxy_store(ngx_conf_t *cf, ngx
     sc.source = &value[1];
     sc.lengths = &plcf->upstream.store_lengths;
     sc.values = &plcf->upstream.store_values;
-    sc.variables = ngx_http_script_variables_count(&value[1]);;
+    sc.variables = ngx_http_script_variables_count(&value[1]);
     sc.complete_lengths = 1;
     sc.complete_values = 1;
 
--- a/src/http/modules/ngx_http_referer_module.c
+++ b/src/http/modules/ngx_http_referer_module.c
@@ -367,7 +367,7 @@ ngx_http_valid_referers(ngx_conf_t *cf, 
     name.data = (u_char *) "invalid_referer";
 
     var = ngx_http_add_variable(cf, &name,
-                                NGX_HTTP_VAR_CHANGABLE|NGX_HTTP_VAR_NOHASH);
+                                NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOHASH);
     if (var == NULL) {
         return NGX_CONF_ERROR;
     }
--- a/src/http/modules/ngx_http_rewrite_module.c
+++ b/src/http/modules/ngx_http_rewrite_module.c
@@ -924,7 +924,7 @@ ngx_http_rewrite_set(ngx_conf_t *cf, ngx
     value[1].len--;
     value[1].data++;
 
-    v = ngx_http_add_variable(cf, &value[1], NGX_HTTP_VAR_CHANGABLE);
+    v = ngx_http_add_variable(cf, &value[1], NGX_HTTP_VAR_CHANGEABLE);
     if (v == NULL) {
         return NGX_CONF_ERROR;
     }
--- a/src/http/modules/ngx_http_ssi_filter_module.c
+++ b/src/http/modules/ngx_http_ssi_filter_module.c
@@ -212,6 +212,7 @@ static ngx_str_t ngx_http_ssi_null_strin
 
 #define  NGX_HTTP_SSI_ECHO_VAR         0
 #define  NGX_HTTP_SSI_ECHO_DEFAULT     1
+#define  NGX_HTTP_SSI_ECHO_ENCODING    2
 
 #define  NGX_HTTP_SSI_CONFIG_ERRMSG    0
 #define  NGX_HTTP_SSI_CONFIG_TIMEFMT   1
@@ -237,6 +238,7 @@ static ngx_http_ssi_param_t  ngx_http_ss
 static ngx_http_ssi_param_t  ngx_http_ssi_echo_params[] = {
     { ngx_string("var"), NGX_HTTP_SSI_ECHO_VAR, 1, 0 },
     { ngx_string("default"), NGX_HTTP_SSI_ECHO_DEFAULT, 0, 0 },
+    { ngx_string("encoding"), NGX_HTTP_SSI_ECHO_ENCODING, 0, 0 },
     { ngx_null_string, 0, 0, 0 }
 };
 
@@ -301,10 +303,10 @@ static ngx_http_ssi_command_t  ngx_http_
 static ngx_http_variable_t  ngx_http_ssi_vars[] = {
 
     { ngx_string("date_local"), NULL, ngx_http_ssi_date_gmt_local_variable, 0,
-      NGX_HTTP_VAR_NOCACHABLE, 0 },
+      NGX_HTTP_VAR_NOCACHEABLE, 0 },
 
     { ngx_string("date_gmt"), NULL, ngx_http_ssi_date_gmt_local_variable, 1,
-      NGX_HTTP_VAR_NOCACHABLE, 0 },
+      NGX_HTTP_VAR_NOCACHEABLE, 0 },
 
     { ngx_null_string, NULL, NULL, 0, 0, 0 }
 };
@@ -355,6 +357,7 @@ found:
     ctx->value_len = slcf->value_len;
     ctx->last_out = &ctx->out;
 
+    ctx->encoding = NGX_HTTP_SSI_ENTITY_ENCODING;
     ctx->output = 1;
 
     ctx->params.elts = ctx->params_array;
@@ -2119,10 +2122,12 @@ static ngx_int_t
 ngx_http_ssi_echo(ngx_http_request_t *r, ngx_http_ssi_ctx_t *ctx,
     ngx_str_t **params)
 {
+    u_char                     *p;
+    uintptr_t                   len;
     ngx_int_t                   key;
     ngx_uint_t                  i;
     ngx_buf_t                  *b;
-    ngx_str_t                  *var, *value, text;
+    ngx_str_t                  *var, *value, *enc, text;
     ngx_chain_t                *cl;
     ngx_http_variable_value_t  *vv;
 
@@ -2170,6 +2175,69 @@ ngx_http_ssi_echo(ngx_http_request_t *r,
         }
     }
 
+    enc = params[NGX_HTTP_SSI_ECHO_ENCODING];
+
+    if (enc) {
+        if (enc->len == 4 && ngx_strncmp(enc->data, "none", 4) == 0) {
+
+            ctx->encoding = NGX_HTTP_SSI_NO_ENCODING;
+
+        } else if (enc->len == 3 && ngx_strncmp(enc->data, "url", 3) == 0) {
+
+            ctx->encoding = NGX_HTTP_SSI_URL_ENCODING;
+
+        } else if (enc->len == 6 && ngx_strncmp(enc->data, "entity", 6) == 0) {
+
+            ctx->encoding = NGX_HTTP_SSI_ENTITY_ENCODING;
+
+        } else {
+            ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+                          "unknown encoding \"%V\" in the \"echo\" command",
+                          enc);
+        }
+    }
+
+    switch (ctx->encoding) {
+
+    case NGX_HTTP_SSI_NO_ENCODING:
+        break;
+
+    case NGX_HTTP_SSI_URL_ENCODING:
+        len = 2 * ngx_escape_uri(NULL, value->data, value->len,
+                                 NGX_ESCAPE_HTML);
+
+        if (len) {
+            p = ngx_palloc(r->pool, value->len + len);
+            if (p == NULL) {
+                return NGX_HTTP_SSI_ERROR;
+            }
+
+            (void) ngx_escape_uri(p, value->data, value->len, NGX_ESCAPE_HTML);
+
+            value->len += len;
+            value->data = p;
+        }
+
+        break;
+
+    case NGX_HTTP_SSI_ENTITY_ENCODING:
+        len = ngx_escape_html(NULL, value->data, value->len);
+
+        if (len) {
+            p = ngx_palloc(r->pool, value->len + len);
+            if (p == NULL) {
+                return NGX_HTTP_SSI_ERROR;
+            }
+
+            (void) ngx_escape_html(p, value->data, value->len);
+
+            value->len += len;
+            value->data = p;
+        }
+
+        break;
+    }
+
     b = ngx_calloc_buf(r->pool);
     if (b == NULL) {
         return NGX_HTTP_SSI_ERROR;
@@ -2573,15 +2641,16 @@ ngx_http_ssi_date_gmt_local_variable(ngx
     char                 buf[NGX_HTTP_SSI_DATE_LEN];
 
     v->valid = 1;
-    v->no_cachable = 0;
+    v->no_cacheable = 0;
     v->not_found = 0;
 
     tp = ngx_timeofday();
 
     ctx = ngx_http_get_module_ctx(r, ngx_http_ssi_filter_module);
 
-    if (ctx->timefmt.len == sizeof("%s") - 1
-        && ctx->timefmt.data[0] == '%' && ctx->timefmt.data[1] == 's')
+    if (ctx == NULL
+        || (ctx->timefmt.len == sizeof("%s") - 1
+            && ctx->timefmt.data[0] == '%' && ctx->timefmt.data[1] == 's'))
     {
         v->data = ngx_palloc(r->pool, NGX_TIME_T_LEN);
         if (v->data == NULL) {
--- a/src/http/modules/ngx_http_ssi_filter_module.h
+++ b/src/http/modules/ngx_http_ssi_filter_module.h
@@ -13,15 +13,20 @@
 #include <ngx_http.h>
 
 
-#define NGX_HTTP_SSI_MAX_PARAMS     16
+#define NGX_HTTP_SSI_MAX_PARAMS       16
 
-#define NGX_HTTP_SSI_COMMAND_LEN    32
-#define NGX_HTTP_SSI_PARAM_LEN      32
-#define NGX_HTTP_SSI_PARAMS_N       4
+#define NGX_HTTP_SSI_COMMAND_LEN      32
+#define NGX_HTTP_SSI_PARAM_LEN        32
+#define NGX_HTTP_SSI_PARAMS_N         4
 
 
-#define NGX_HTTP_SSI_COND_IF        1
-#define NGX_HTTP_SSI_COND_ELSE      2
+#define NGX_HTTP_SSI_COND_IF          1
+#define NGX_HTTP_SSI_COND_ELSE        2
+
+
+#define NGX_HTTP_SSI_NO_ENCODING      0
+#define NGX_HTTP_SSI_URL_ENCODING     1
+#define NGX_HTTP_SSI_ENTITY_ENCODING  2
 
 
 typedef struct {
@@ -60,6 +65,7 @@ typedef struct {
     ngx_array_t              *blocks;
 
     unsigned                  conditional:2;
+    unsigned                  encoding:2;
     unsigned                  block:1;
     unsigned                  output:1;
     unsigned                  output_chosen:1;
--- a/src/http/modules/ngx_http_ssl_module.c
+++ b/src/http/modules/ngx_http_ssl_module.c
@@ -170,19 +170,19 @@ ngx_module_t  ngx_http_ssl_module = {
 static ngx_http_variable_t  ngx_http_ssl_vars[] = {
 
     { ngx_string("ssl_protocol"), NULL, ngx_http_ssl_static_variable,
-      (uintptr_t) ngx_ssl_get_protocol, NGX_HTTP_VAR_CHANGABLE, 0 },
+      (uintptr_t) ngx_ssl_get_protocol, NGX_HTTP_VAR_CHANGEABLE, 0 },
 
     { ngx_string("ssl_cipher"), NULL, ngx_http_ssl_static_variable,
-      (uintptr_t) ngx_ssl_get_cipher_name, NGX_HTTP_VAR_CHANGABLE, 0 },
+      (uintptr_t) ngx_ssl_get_cipher_name, NGX_HTTP_VAR_CHANGEABLE, 0 },
 
     { ngx_string("ssl_client_s_dn"), NULL, ngx_http_ssl_variable,
-      (uintptr_t) ngx_ssl_get_subject_dn, NGX_HTTP_VAR_CHANGABLE, 0 },
+      (uintptr_t) ngx_ssl_get_subject_dn, NGX_HTTP_VAR_CHANGEABLE, 0 },
 
     { ngx_string("ssl_client_i_dn"), NULL, ngx_http_ssl_variable,
-      (uintptr_t) ngx_ssl_get_issuer_dn, NGX_HTTP_VAR_CHANGABLE, 0 },
+      (uintptr_t) ngx_ssl_get_issuer_dn, NGX_HTTP_VAR_CHANGEABLE, 0 },
 
     { ngx_string("ssl_client_serial"), NULL, ngx_http_ssl_variable,
-      (uintptr_t) ngx_ssl_get_serial_number, NGX_HTTP_VAR_CHANGABLE, 0 },
+      (uintptr_t) ngx_ssl_get_serial_number, NGX_HTTP_VAR_CHANGEABLE, 0 },
 
     { ngx_null_string, NULL, NULL, 0, 0, 0 }
 };
@@ -210,7 +210,7 @@ ngx_http_ssl_static_variable(ngx_http_re
 
         v->len = len;
         v->valid = 1;
-        v->no_cachable = 0;
+        v->no_cacheable = 0;
         v->not_found = 0;
 
         return NGX_OK;
@@ -241,7 +241,7 @@ ngx_http_ssl_variable(ngx_http_request_t
 
         if (v->len) {
             v->valid = 1;
-            v->no_cachable = 0;
+            v->no_cacheable = 0;
             v->not_found = 0;
 
             return NGX_OK;
--- a/src/http/modules/ngx_http_stub_status_module.c
+++ b/src/http/modules/ngx_http_stub_status_module.c
@@ -129,7 +129,7 @@ static ngx_int_t ngx_http_status_handler
         return rc;
     }
 
-    return ngx_http_output_filter(r, &out);;
+    return ngx_http_output_filter(r, &out);
 }
 
 
--- a/src/http/modules/ngx_http_sub_filter_module.c
+++ b/src/http/modules/ngx_http_sub_filter_module.c
@@ -369,9 +369,14 @@ ngx_http_sub_body_filter(ngx_http_reques
                 }
             }
 
-            b->memory = 1;
-            b->pos = ctx->sub.data;
-            b->last = ctx->sub.data + ctx->sub.len;
+            if (ctx->sub.len) {
+                b->memory = 1;
+                b->pos = ctx->sub.data;
+                b->last = ctx->sub.data + ctx->sub.len;
+
+            } else {
+                b->sync = 1;
+            }
 
             cl->buf = b;
             cl->next = NULL;
@@ -557,6 +562,7 @@ ngx_http_sub_parse(ngx_http_request_t *r
                 ch = ngx_tolower(ch);
             }
 
+            ctx->state = state;
             ctx->pos = p;
             ctx->looked = looked;
             ctx->copy_end = p;
@@ -578,6 +584,10 @@ ngx_http_sub_parse(ngx_http_request_t *r
             looked++;
 
             if (looked == ctx->match.len) {
+                if ((size_t) (p - ctx->pos) < looked) {
+                    ctx->saved = 0;
+                }
+
                 ctx->state = sub_start_state;
                 ctx->pos = p + 1;
                 ctx->looked = looked;
--- a/src/http/modules/ngx_http_userid_filter_module.c
+++ b/src/http/modules/ngx_http_userid_filter_module.c
@@ -493,7 +493,7 @@ ngx_http_userid_variable(ngx_http_reques
     }
 
     v->valid = 1;
-    v->no_cachable = 0;
+    v->no_cacheable = 0;
     v->not_found = 0;
 
     ngx_sprintf(v->data, "%V=%08XD%08XD%08XD%08XD",
--- a/src/http/modules/perl/nginx.pm
+++ b/src/http/modules/perl/nginx.pm
@@ -47,7 +47,7 @@ our @EXPORT = qw(
     HTTP_INSUFFICIENT_STORAGE
 );
 
-our $VERSION = '0.6.13';
+our $VERSION = '0.6.14';
 
 require XSLoader;
 XSLoader::load('nginx', $VERSION);
--- a/src/http/modules/perl/nginx.xs
+++ b/src/http/modules/perl/nginx.xs
@@ -637,11 +637,11 @@ sendfile(r, filename, offset = -1, bytes
     }
 
     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
-    
+
     of.test_dir = 0;
-    of.retest = clcf->open_file_cache_retest; 
-    of.errors = clcf->open_file_cache_errors; 
-    of.events = clcf->open_file_cache_events; 
+    of.retest = clcf->open_file_cache_retest;
+    of.errors = clcf->open_file_cache_errors;
+    of.events = clcf->open_file_cache_events;
 
     path.len = ngx_strlen(filename);
 
@@ -651,7 +651,7 @@ sendfile(r, filename, offset = -1, bytes
     }
 
     (void) ngx_cpystrn(path.data, filename, path.len + 1);
- 
+
     rc = ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool);
 
     if (rc == NGX_ERROR) {
@@ -912,7 +912,7 @@ variable(r, name, value = NULL)
     if (value) {
         vv->len = val.len;
         vv->valid = 1;
-        vv->no_cachable = 0;
+        vv->no_cacheable = 0;
         vv->not_found = 0;
         vv->data = val.data;
 
--- a/src/http/modules/perl/ngx_http_perl_module.c
+++ b/src/http/modules/perl/ngx_http_perl_module.c
@@ -336,7 +336,7 @@ ngx_http_perl_variable(ngx_http_request_
     if (value.data) {
         v->len = value.len;
         v->valid = 1;
-        v->no_cachable = 0;
+        v->no_cacheable = 0;
         v->not_found = 0;
         v->data = value.data;
 
@@ -954,7 +954,7 @@ ngx_http_perl_set(ngx_conf_t *cf, ngx_co
     value[1].len--;
     value[1].data++;
 
-    v = ngx_http_add_variable(cf, &value[1], NGX_HTTP_VAR_CHANGABLE);
+    v = ngx_http_add_variable(cf, &value[1], NGX_HTTP_VAR_CHANGEABLE);
     if (v == NULL) {
         return NGX_CONF_ERROR;
     }
--- a/src/http/ngx_http_busy_lock.c
+++ b/src/http/ngx_http_busy_lock.c
@@ -10,9 +10,9 @@
 
 
 
-static int ngx_http_busy_lock_look_cachable(ngx_http_busy_lock_t *bl,
-                                            ngx_http_busy_lock_ctx_t *bc,
-                                            int lock);
+static int ngx_http_busy_lock_look_cacheable(ngx_http_busy_lock_t *bl,
+                                             ngx_http_busy_lock_ctx_t *bc,
+                                             int lock);
 
 
 int ngx_http_busy_lock(ngx_http_busy_lock_t *bl, ngx_http_busy_lock_ctx_t *bc)
@@ -60,12 +60,12 @@ int ngx_http_busy_lock(ngx_http_busy_loc
 }
 
 
-int ngx_http_busy_lock_cachable(ngx_http_busy_lock_t *bl,
-                                ngx_http_busy_lock_ctx_t *bc, int lock)
+int ngx_http_busy_lock_cacheable(ngx_http_busy_lock_t *bl,
+                                 ngx_http_busy_lock_ctx_t *bc, int lock)
 {
     int  rc;
 
-    rc = ngx_http_busy_lock_look_cachable(bl, bc, lock);
+    rc = ngx_http_busy_lock_look_cacheable(bl, bc, lock);
 
     ngx_log_debug3(NGX_LOG_DEBUG_HTTP, bc->event->log, 0,
                    "http busylock: %d w:%d mw::%d",
@@ -121,22 +121,22 @@ void ngx_http_busy_unlock(ngx_http_busy_
 
     if (bl->md5) {
         bl->md5_mask[bc->slot / 8] &= ~(1 << (bc->slot & 7));
-        bl->cachable--;
+        bl->cacheable--;
     }
 
     bl->busy--;
 }
 
 
-static int ngx_http_busy_lock_look_cachable(ngx_http_busy_lock_t *bl,
-                                            ngx_http_busy_lock_ctx_t *bc,
-                                            int lock)
+static int ngx_http_busy_lock_look_cacheable(ngx_http_busy_lock_t *bl,
+                                             ngx_http_busy_lock_ctx_t *bc,
+                                             int lock)
 {
-    int    i, b, cachable, free;
+    int    i, b, cacheable, free;
     u_int  mask;
 
     b = 0;
-    cachable = 0;
+    cacheable = 0;
     free = -1;
 
 #if (NGX_SUPPRESS_WARN)
@@ -153,15 +153,15 @@ static int ngx_http_busy_lock_look_cacha
             if (ngx_memcmp(&bl->md5[i * 16], bc->md5, 16) == 0) {
                 return NGX_AGAIN;
             }
-            cachable++;
+            cacheable++;
 
         } else if (free == -1) {
             free = i;
         }
 
 #if 1
-        if (cachable == bl->cachable) {
-            if (free == -1 && cachable < bl->max_busy) {
+        if (cacheable == bl->cacheable) {
+            if (free == -1 && cacheable < bl->max_busy) {
                 free = i + 1;
             }
 
@@ -186,7 +186,7 @@ static int ngx_http_busy_lock_look_cacha
         bl->md5_mask[free / 8] |= 1 << (free & 7);
         bc->slot = free;
 
-        bl->cachable++;
+        bl->cacheable++;
         bl->busy++;
     }
 
--- a/src/http/ngx_http_busy_lock.h
+++ b/src/http/ngx_http_busy_lock.h
@@ -17,7 +17,7 @@
 typedef struct {
     u_char             *md5_mask;
     char               *md5;
-    int                 cachable;
+    int                 cacheable;
 
     int                 busy;
     int                 max_busy;
@@ -41,8 +41,8 @@ typedef struct {
 
 
 int ngx_http_busy_lock(ngx_http_busy_lock_t *bl, ngx_http_busy_lock_ctx_t *bc);
-int ngx_http_busy_lock_cachable(ngx_http_busy_lock_t *bl,
-                                ngx_http_busy_lock_ctx_t *bc, int lock);
+int ngx_http_busy_lock_cacheable(ngx_http_busy_lock_t *bl,
+                                 ngx_http_busy_lock_ctx_t *bc, int lock);
 void ngx_http_busy_unlock(ngx_http_busy_lock_t *bl,
                           ngx_http_busy_lock_ctx_t *bc);
 
--- a/src/http/ngx_http_core_module.c
+++ b/src/http/ngx_http_core_module.c
@@ -896,7 +896,7 @@ ngx_http_core_content_phase(ngx_http_req
 
         if (ngx_http_map_uri_to_path(r, &path, &root, 0) != NULL) {
             ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
-                          "directory index of \"%V\" is forbidden", &path);
+                          "directory index of \"%s\" is forbidden", path.data);
         }
 
         ngx_http_finalize_request(r, NGX_HTTP_FORBIDDEN);
@@ -2607,7 +2607,7 @@ ngx_http_core_listen(ngx_conf_t *cf, ngx
     u.listen = 1;
     u.default_port = 80;
 
-    if (ngx_parse_url(cf, &u) != NGX_OK) {
+    if (ngx_parse_url(cf->pool, &u) != NGX_OK) {
         if (u.err) {
             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                                "%s in \"%V\" of the \"listen\" directive",
--- a/src/http/ngx_http_request.c
+++ b/src/http/ngx_http_request.c
@@ -1204,10 +1204,10 @@ static ngx_int_t
 ngx_http_process_connection(ngx_http_request_t *r, ngx_table_elt_t *h,
     ngx_uint_t offset)
 {
-    if (ngx_strstr(h->value.data, "close")) {
+    if (ngx_strcasestrn(h->value.data, "close", 5 - 1)) {
         r->headers_in.connection_type = NGX_HTTP_CONNECTION_CLOSE;
 
-    } else if (ngx_strstr(h->value.data, "keep-alive")) {
+    } else if (ngx_strcasestrn(h->value.data, "keep-alive", 10 - 1)) {
         r->headers_in.connection_type = NGX_HTTP_CONNECTION_KEEP_ALIVE;
     }
 
@@ -1319,7 +1319,8 @@ ngx_http_process_request_header(ngx_http
     }
 
     if (r->headers_in.transfer_encoding
-        && ngx_strstr(r->headers_in.transfer_encoding->value.data, "chunked"))
+        && ngx_strcasestrn(r->headers_in.transfer_encoding->value.data,
+                           "chunked", 7 - 1))
     {
         ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
                       "client sent \"Transfer-Encoding: chunked\" header");
@@ -1351,7 +1352,7 @@ ngx_http_process_request_header(ngx_http
 
         user_agent = r->headers_in.user_agent->value.data;
 
-        ua = (u_char *) ngx_strstr(user_agent, "MSIE");
+        ua = ngx_strstrn(user_agent, "MSIE", 4 - 1);
 
         if (ua && ua + 8 < user_agent + r->headers_in.user_agent->value.len) {
 
@@ -1369,7 +1370,7 @@ ngx_http_process_request_header(ngx_http
 #endif
         }
 
-        if (ngx_strstr(user_agent, "Opera")) {
+        if (ngx_strstrn(user_agent, "Opera", 5 - 1)) {
             r->headers_in.opera = 1;
             r->headers_in.msie = 0;
             r->headers_in.msie4 = 0;
@@ -1377,10 +1378,10 @@ ngx_http_process_request_header(ngx_http
 
         if (!r->headers_in.msie && !r->headers_in.opera) {
 
-            if (ngx_strstr(user_agent, "Gecko/")) {
+            if (ngx_strstrn(user_agent, "Gecko/", 6 - 1)) {
                 r->headers_in.gecko = 1;
 
-            } else if (ngx_strstr(user_agent, "Konqueror")) {
+            } else if (ngx_strstrn(user_agent, "Konqueror", 9 - 1)) {
                 r->headers_in.konqueror = 1;
             }
         }
--- a/src/http/ngx_http_request.h
+++ b/src/http/ngx_http_request.h
@@ -449,7 +449,7 @@ struct ngx_http_request_s {
     unsigned                          limit_zone_set:1;
 
 #if 0
-    unsigned                          cachable:1;
+    unsigned                          cacheable:1;
 #endif
 
     unsigned                          pipeline:1;
--- a/src/http/ngx_http_script.c
+++ b/src/http/ngx_http_script.c
@@ -314,7 +314,7 @@ ngx_http_script_run(ngx_http_request_t *
     cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);
 
     for (i = 0; i < cmcf->variables.nelts; i++) {
-        if (r->variables[i].no_cachable) {
+        if (r->variables[i].no_cacheable) {
             r->variables[i].valid = 0;
             r->variables[i].not_found = 0;
         }
@@ -351,7 +351,7 @@ ngx_http_script_run(ngx_http_request_t *
 
 
 void
-ngx_http_script_flush_no_cachable_variables(ngx_http_request_t *r,
+ngx_http_script_flush_no_cacheable_variables(ngx_http_request_t *r,
     ngx_array_t *indices)
 {
     ngx_uint_t  n, *index;
@@ -359,7 +359,7 @@ ngx_http_script_flush_no_cachable_variab
     if (indices) {
         index = indices->elts;
         for (n = 0; n < indices->nelts; n++) {
-            if (r->variables[index[n]].no_cachable) {
+            if (r->variables[index[n]].no_cacheable) {
                 r->variables[index[n]].valid = 0;
                 r->variables[index[n]].not_found = 0;
             }
@@ -1127,7 +1127,7 @@ ngx_http_script_value_code(ngx_http_scri
     e->sp->data = (u_char *) code->text_data;
 
     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, e->request->connection->log, 0,
-                   "http script value: \"%V\"", e->sp);
+                   "http script value: \"%v\"", e->sp);
 
     e->sp++;
 }
@@ -1152,7 +1152,7 @@ ngx_http_script_set_var_code(ngx_http_sc
 
     r->variables[code->index].len = e->sp->len;
     r->variables[code->index].valid = 1;
-    r->variables[code->index].no_cachable = 0;
+    r->variables[code->index].no_cacheable = 0;
     r->variables[code->index].not_found = 0;
     r->variables[code->index].data = e->sp->data;
 }
--- a/src/http/ngx_http_script.h
+++ b/src/http/ngx_http_script.h
@@ -181,7 +181,7 @@ ngx_uint_t ngx_http_script_variables_cou
 ngx_int_t ngx_http_script_compile(ngx_http_script_compile_t *sc);
 u_char *ngx_http_script_run(ngx_http_request_t *r, ngx_str_t *value,
     void *code_lengths, size_t reserved, void *code_values);
-void ngx_http_script_flush_no_cachable_variables(ngx_http_request_t *r,
+void ngx_http_script_flush_no_cacheable_variables(ngx_http_request_t *r,
     ngx_array_t *indices);
 
 void *ngx_http_script_start_code(ngx_pool_t *pool, ngx_array_t **codes,
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -434,7 +434,7 @@ ngx_http_upstream_check_broken_connectio
             ev->error = 1;
         }
 
-        if (!u->cachable && !u->store && u->peer.connection) {
+        if (!u->cacheable && !u->store && u->peer.connection) {
             ngx_log_error(NGX_LOG_INFO, ev->log, ev->kq_errno,
                           "kevent() reported that client closed prematurely "
                           "connection, so upstream connection is closed too");
@@ -500,7 +500,7 @@ ngx_http_upstream_check_broken_connectio
     ev->eof = 1;
     c->error = 1;
 
-    if (!u->cachable && !u->store && u->peer.connection) {
+    if (!u->cacheable && !u->store && u->peer.connection) {
         ngx_log_error(NGX_LOG_INFO, ev->log, err,
                       "client closed prematurely connection, "
                       "so upstream connection is closed too");
@@ -980,8 +980,7 @@ ngx_http_upstream_process_header(ngx_eve
 #endif
     }
 
-    n = u->peer.connection->recv(u->peer.connection, u->buffer.last,
-                                 u->buffer.end - u->buffer.last);
+    n = c->recv(c, u->buffer.last, u->buffer.end - u->buffer.last);
 
     if (n == NGX_AGAIN) {
 #if 0
@@ -1514,7 +1513,7 @@ ngx_http_upstream_send_response(ngx_http
         }
     }
 
-    if (u->cachable) {
+    if (u->cacheable) {
         header = (ngx_http_cache_header_t *) u->buffer->start;
 
         header->expires = u->cache->ctx.expires;
@@ -1542,7 +1541,7 @@ ngx_http_upstream_send_response(ngx_http
     p->pool = r->pool;
     p->log = c->log;
 
-    p->cachable = u->cachable || u->store;
+    p->cacheable = u->cacheable || u->store;
 
     p->temp_file = ngx_pcalloc(r->pool, sizeof(ngx_temp_file_t));
     if (p->temp_file == NULL) {
@@ -1555,7 +1554,7 @@ ngx_http_upstream_send_response(ngx_http
     p->temp_file->path = u->conf->temp_path;
     p->temp_file->pool = r->pool;
 
-    if (u->cachable || u->store) {
+    if (u->cacheable || u->store) {
         p->temp_file->persistent = 1;
 
     } else {
@@ -1579,7 +1578,7 @@ ngx_http_upstream_send_response(ngx_http
 
     p->preread_size = u->buffer.last - u->buffer.pos;
 
-    if (u->cachable) {
+    if (u->cacheable) {
 
         p->buf_to_file = ngx_calloc_buf(r->pool);
         if (p->buf_to_file == NULL) {
@@ -1956,14 +1955,14 @@ ngx_http_upstream_process_body(ngx_event
 
 #if (NGX_HTTP_FILE_CACHE)
 
-        if (p->upstream_done && u->cachable) {
+        if (p->upstream_done && u->cacheable) {
             if (ngx_http_cache_update(r) == NGX_ERROR) {
                 ngx_http_busy_unlock(u->conf->busy_lock, &u->busy_lock);
                 ngx_http_upstream_finalize_request(r, u, 0);
                 return;
             }
 
-        } else if (p->upstream_eof && u->cachable) {
+        } else if (p->upstream_eof && u->cacheable) {
 
             /* TODO: check length & update cache */
 
@@ -1991,7 +1990,7 @@ ngx_http_upstream_process_body(ngx_event
         ngx_log_debug0(NGX_LOG_DEBUG_HTTP, c->log, 0,
                        "http upstream downstream error");
 
-        if (!u->cachable && u->peer.connection) {
+        if (!u->cacheable && u->peer.connection) {
             ngx_http_upstream_finalize_request(r, u, 0);
         }
     }
@@ -2636,7 +2635,7 @@ ngx_http_upstream_rewrite_refresh(ngx_ht
 
     if (r->upstream->rewrite_redirect) {
 
-        p = (u_char *) ngx_strstr(ho->value.data, "url=");
+        p = ngx_strcasestrn(ho->value.data, "url=", 4 - 1);
 
         if (p) {
             rc = r->upstream->rewrite_redirect(r, ho, p + 4 - ho->value.data);
@@ -2715,7 +2714,7 @@ ngx_http_upstream_addr_variable(ngx_http
     ngx_http_upstream_state_t  *state;
 
     v->valid = 1;
-    v->no_cachable = 0;
+    v->no_cacheable = 0;
     v->not_found = 0;
 
     if (r->upstream_states == NULL || r->upstream_states->nelts == 0) {
@@ -2786,7 +2785,7 @@ ngx_http_upstream_status_variable(ngx_ht
     ngx_http_upstream_state_t  *state;
 
     v->valid = 1;
-    v->no_cachable = 0;
+    v->no_cacheable = 0;
     v->not_found = 0;
 
     if (r->upstream_states == NULL || r->upstream_states->nelts == 0) {
@@ -2852,7 +2851,7 @@ ngx_http_upstream_response_time_variable
     ngx_http_upstream_state_t  *state;
 
     v->valid = 1;
-    v->no_cachable = 0;
+    v->no_cacheable = 0;
     v->not_found = 0;
 
     if (r->upstream_states == NULL || r->upstream_states->nelts == 0) {
@@ -3066,7 +3065,7 @@ ngx_http_upstream_server(ngx_conf_t *cf,
     u.url = value[1];
     u.default_port = 80;
 
-    if (ngx_parse_url(cf, &u) != NGX_OK) {
+    if (ngx_parse_url(cf->pool, &u) != NGX_OK) {
         if (u.err) {
             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                                "%s in upstream \"%V\"", u.err, &u.url);
@@ -3181,7 +3180,7 @@ ngx_http_upstream_add(ngx_conf_t *cf, ng
 
     if (!(flags & NGX_HTTP_UPSTREAM_CREATE)) {
 
-        if (ngx_parse_url(cf, u) != NGX_OK) {
+        if (ngx_parse_url(cf->pool, u) != NGX_OK) {
             if (u->err) {
                 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                                    "%s in upstream \"%V\"", u->err, &u->url);
--- a/src/http/ngx_http_upstream.h
+++ b/src/http/ngx_http_upstream.h
@@ -244,7 +244,7 @@ struct ngx_http_upstream_s {
     ngx_http_cleanup_pt            *cleanup;
 
     unsigned                        store:1;
-    unsigned                        cachable:1;
+    unsigned                        cacheable:1;
     unsigned                        accel:1;
 
     unsigned                        buffering:1;
--- a/src/http/ngx_http_upstream_round_robin.c
+++ b/src/http/ngx_http_upstream_round_robin.c
@@ -145,7 +145,7 @@ ngx_http_upstream_init_round_robin(ngx_c
     u.host = us->host;
     u.port = (in_port_t) (us->port ? us->port : us->default_port);
 
-    if (ngx_inet_resolve_host(cf, &u) != NGX_OK) {
+    if (ngx_inet_resolve_host(cf->pool, &u) != NGX_OK) {
         if (u.err) {
             ngx_log_error(NGX_LOG_EMERG, cf->log, 0,
                           "%s in upstream \"%V\" in %s:%ui",
@@ -167,17 +167,14 @@ ngx_http_upstream_init_round_robin(ngx_c
     peers->number = n;
     peers->name = &us->host;
 
-    n = 0;
-
     for (i = 0; i < u.naddrs; i++) {
-        peers->peer[n].sockaddr = u.addrs[i].sockaddr;
-        peers->peer[n].socklen = u.addrs[i].socklen;
-        peers->peer[n].name = u.addrs[i].name;
-        peers->peer[n].weight = 1;
-        peers->peer[n].current_weight = 1;
-        peers->peer[n].max_fails = 1;
-        peers->peer[n].fail_timeout = 10;
-        n++;
+        peers->peer[i].sockaddr = u.addrs[i].sockaddr;
+        peers->peer[i].socklen = u.addrs[i].socklen;
+        peers->peer[i].name = u.addrs[i].name;
+        peers->peer[i].weight = 1;
+        peers->peer[i].current_weight = 1;
+        peers->peer[i].max_fails = 1;
+        peers->peer[i].fail_timeout = 10;
     }
 
     us->peer.data = peers;
@@ -514,13 +511,7 @@ ngx_http_upstream_get_peer(ngx_http_upst
         }
 
         for (i = 0; i < peers->number; i++) {
-            if (peer->max_fails == 0 || peer->fails < peer->max_fails) {
-                peer[i].current_weight += peer[i].weight;
-
-            } else {
-                /* 1 allows to go to quick recovery when all peers failed */
-                peer[i].current_weight = 1;
-            }
+            peer[i].current_weight += peer[i].weight;
         }
     }
 }
--- a/src/http/ngx_http_variables.c
+++ b/src/http/ngx_http_variables.c
@@ -143,34 +143,34 @@ static ngx_http_variable_t  ngx_http_cor
 
     { ngx_string("uri"), NULL, ngx_http_variable_request,
       offsetof(ngx_http_request_t, uri),
-      NGX_HTTP_VAR_NOCACHABLE, 0 },
+      NGX_HTTP_VAR_NOCACHEABLE, 0 },
 
     { ngx_string("document_uri"), NULL, ngx_http_variable_request,
       offsetof(ngx_http_request_t, uri),
-      NGX_HTTP_VAR_NOCACHABLE, 0 },
+      NGX_HTTP_VAR_NOCACHEABLE, 0 },
 
     { ngx_string("request"), NULL, ngx_http_variable_request,
       offsetof(ngx_http_request_t, request_line), 0, 0 },
 
     { ngx_string("document_root"), NULL,
-      ngx_http_variable_document_root, 0, NGX_HTTP_VAR_NOCACHABLE, 0 },
+      ngx_http_variable_document_root, 0, NGX_HTTP_VAR_NOCACHEABLE, 0 },
 
     { ngx_string("query_string"), NULL, ngx_http_variable_request,
       offsetof(ngx_http_request_t, args),
-      NGX_HTTP_VAR_NOCACHABLE, 0 },
+      NGX_HTTP_VAR_NOCACHEABLE, 0 },
 
     { ngx_string("args"),
       ngx_http_variable_request_set,
       ngx_http_variable_request,
       offsetof(ngx_http_request_t, args),
-      NGX_HTTP_VAR_CHANGABLE|NGX_HTTP_VAR_NOCACHABLE, 0 },
+      NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOCACHEABLE, 0 },
 
     { ngx_string("is_args"), NULL, ngx_http_variable_is_args,
-      0, NGX_HTTP_VAR_NOCACHABLE, 0 },
+      0, NGX_HTTP_VAR_NOCACHEABLE, 0 },
 
     { ngx_string("request_filename"), NULL,
       ngx_http_variable_request_filename, 0,
-      NGX_HTTP_VAR_NOCACHABLE, 0 },
+      NGX_HTTP_VAR_NOCACHEABLE, 0 },
 
     { ngx_string("server_name"), NULL, ngx_http_variable_request,
       offsetof(ngx_http_request_t, server_name), 0, 0 },
@@ -215,7 +215,7 @@ static ngx_http_variable_t  ngx_http_cor
     { ngx_string("limit_rate"), ngx_http_variable_request_set_size,
       ngx_http_variable_request,
       offsetof(ngx_http_request_t, limit_rate),
-      NGX_HTTP_VAR_CHANGABLE|NGX_HTTP_VAR_NOCACHABLE, 0 },
+      NGX_HTTP_VAR_CHANGEABLE|NGX_HTTP_VAR_NOCACHEABLE, 0 },
 
     { ngx_string("nginx_version"), NULL, ngx_http_variable_nginx_version,
       0, 0, 0 },
@@ -251,7 +251,7 @@ ngx_http_add_variable(ngx_conf_t *cf, ng
 
         v = key[i].value;
 
-        if (!(v->flags & NGX_HTTP_VAR_CHANGABLE)) {
+        if (!(v->flags & NGX_HTTP_VAR_CHANGEABLE)) {
             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                                "the duplicate \"%V\" variable", name);
             return NULL;
@@ -375,8 +375,8 @@ ngx_http_get_indexed_variable(ngx_http_r
     if (v[index].get_handler(r, &r->variables[index], v[index].data)
         == NGX_OK)
     {
-        if (v[index].flags & NGX_HTTP_VAR_NOCACHABLE) {
-            r->variables[index].no_cachable = 1;
+        if (v[index].flags & NGX_HTTP_VAR_NOCACHEABLE) {
+            r->variables[index].no_cacheable = 1;
         }
 
         return &r->variables[index];
@@ -397,7 +397,7 @@ ngx_http_get_flushed_variable(ngx_http_r
     v = &r->variables[index];
 
     if (v->valid) {
-        if (!v->no_cachable) {
+        if (!v->no_cacheable) {
             return v;
         }
 
@@ -497,7 +497,7 @@ ngx_http_variable_request(ngx_http_reque
     if (s->data) {
         v->len = s->len;
         v->valid = 1;
-        v->no_cachable = 0;
+        v->no_cacheable = 0;
         v->not_found = 0;
         v->data = s->data;
 
@@ -559,7 +559,7 @@ ngx_http_variable_header(ngx_http_reques
     if (h) {
         v->len = h->value.len;
         v->valid = 1;
-        v->no_cachable = 0;
+        v->no_cacheable = 0;
         v->not_found = 0;
         v->data = h->value.data;
 
@@ -591,7 +591,7 @@ ngx_http_variable_headers(ngx_http_reque
     }
 
     v->valid = 1;
-    v->no_cachable = 0;
+    v->no_cacheable = 0;
     v->not_found = 0;
 
     h = a->elts;
@@ -691,7 +691,7 @@ ngx_http_variable_unknown_header(ngx_htt
         if (n + prefix == var->len && n == header[i].key.len) {
             v->len = header[i].value.len;
             v->valid = 1;
-            v->no_cachable = 0;
+            v->no_cacheable = 0;
             v->not_found = 0;
             v->data = header[i].value.data;
 
@@ -730,7 +730,7 @@ ngx_http_variable_host(ngx_http_request_
     }
 
     v->valid = 1;
-    v->no_cachable = 0;
+    v->no_cacheable = 0;
     v->not_found = 0;
 
     return NGX_OK;
@@ -749,7 +749,7 @@ ngx_http_variable_binary_remote_addr(ngx
 
     v->len = sizeof(in_addr_t);
     v->valid = 1;
-    v->no_cachable = 0;
+    v->no_cacheable = 0;
     v->not_found = 0;
     v->data = (u_char *) &sin->sin_addr.s_addr;
 
@@ -763,7 +763,7 @@ ngx_http_variable_remote_addr(ngx_http_r
 {
     v->len = r->connection->addr_text.len;
     v->valid = 1;
-    v->no_cachable = 0;
+    v->no_cacheable = 0;
     v->not_found = 0;
     v->data = r->connection->addr_text.data;
 
@@ -780,7 +780,7 @@ ngx_http_variable_remote_port(ngx_http_r
 
     v->len = 0;
     v->valid = 1;
-    v->no_cachable = 0;
+    v->no_cacheable = 0;
     v->not_found = 0;
 
     v->data = ngx_palloc(r->pool, sizeof("65535") - 1);
@@ -832,7 +832,7 @@ ngx_http_variable_server_addr(ngx_http_r
     v->len = ngx_inet_ntop(c->listening->family, &r->in_addr,
                            v->data, INET_ADDRSTRLEN);
     v->valid = 1;
-    v->no_cachable = 0;
+    v->no_cacheable = 0;
     v->not_found = 0;
 
     return NGX_OK;
@@ -845,7 +845,7 @@ ngx_http_variable_server_port(ngx_http_r
 {
     v->len = r->port_text->len - 1;
     v->valid = 1;
-    v->no_cachable = 0;
+    v->no_cacheable = 0;
     v->not_found = 0;
     v->data = r->port_text->data + 1;
 
@@ -862,7 +862,7 @@ ngx_http_variable_scheme(ngx_http_reques
     if (r->connection->ssl) {
         v->len = sizeof("https") - 1;
         v->valid = 1;
-        v->no_cachable = 0;
+        v->no_cacheable = 0;
         v->not_found = 0;
         v->data = (u_char *) "https";
 
@@ -873,7 +873,7 @@ ngx_http_variable_scheme(ngx_http_reques
 
     v->len = sizeof("http") - 1;
     v->valid = 1;
-    v->no_cachable = 0;
+    v->no_cacheable = 0;
     v->not_found = 0;
     v->data = (u_char *) "http";
 
@@ -886,7 +886,7 @@ ngx_http_variable_is_args(ngx_http_reque
     ngx_http_variable_value_t *v, uintptr_t data)
 {
     v->valid = 1;
-    v->no_cachable = 0;
+    v->no_cacheable = 0;
     v->not_found = 0;
 
     if (r->args.len == 0) {
@@ -914,7 +914,7 @@ ngx_http_variable_document_root(ngx_http
     if (clcf->root_lengths == NULL) {
         v->len = clcf->root.len;
         v->valid = 1;
-        v->no_cachable = 0;
+        v->no_cacheable = 0;
         v->not_found = 0;
         v->data = clcf->root.data;
 
@@ -934,7 +934,7 @@ ngx_http_variable_document_root(ngx_http
 
         v->len = path.len;
         v->valid = 1;
-        v->no_cachable = 0;
+        v->no_cacheable = 0;
         v->not_found = 0;
         v->data = path.data;
     }
@@ -958,7 +958,7 @@ ngx_http_variable_request_filename(ngx_h
 
     v->len = path.len - 1;
     v->valid = 1;
-    v->no_cachable = 0;
+    v->no_cacheable = 0;
     v->not_found = 0;
     v->data = path.data;
 
@@ -973,7 +973,7 @@ ngx_http_variable_request_method(ngx_htt
     if (r->main->method_name.data) {
         v->len = r->main->method_name.len;
         v->valid = 1;
-        v->no_cachable = 0;
+        v->no_cacheable = 0;
         v->not_found = 0;
         v->data = r->main->method_name.data;
 
@@ -1004,7 +1004,7 @@ ngx_http_variable_remote_user(ngx_http_r
 
     v->len = r->headers_in.user.len;
     v->valid = 1;
-    v->no_cachable = 0;
+    v->no_cacheable = 0;
     v->not_found = 0;
     v->data = r->headers_in.user.data;
 
@@ -1032,7 +1032,7 @@ ngx_http_variable_body_bytes_sent(ngx_ht
 
     v->len = ngx_sprintf(p, "%O", sent) - p;
     v->valid = 1;
-    v->no_cachable = 0;
+    v->no_cacheable = 0;
     v->not_found = 0;
     v->data = p;
 
@@ -1047,7 +1047,7 @@ ngx_http_variable_sent_content_type(ngx_
     if (r->headers_out.content_type.len) {
         v->len = r->headers_out.content_type.len;
         v->valid = 1;
-        v->no_cachable = 0;
+        v->no_cacheable = 0;
         v->not_found = 0;
         v->data = r->headers_out.content_type.data;
 
@@ -1068,7 +1068,7 @@ ngx_http_variable_sent_content_length(ng
     if (r->headers_out.content_length) {
         v->len = r->headers_out.content_length->value.len;
         v->valid = 1;
-        v->no_cachable = 0;
+        v->no_cacheable = 0;
         v->not_found = 0;
         v->data = r->headers_out.content_length->value.data;
 
@@ -1083,7 +1083,7 @@ ngx_http_variable_sent_content_length(ng
 
         v->len = ngx_sprintf(p, "%O", r->headers_out.content_length_n) - p;
         v->valid = 1;
-        v->no_cachable = 0;
+        v->no_cacheable = 0;
         v->not_found = 0;
         v->data = p;
 
@@ -1105,7 +1105,7 @@ ngx_http_variable_sent_last_modified(ngx
     if (r->headers_out.last_modified) {
         v->len = r->headers_out.last_modified->value.len;
         v->valid = 1;
-        v->no_cachable = 0;
+        v->no_cacheable = 0;
         v->not_found = 0;
         v->data = r->headers_out.last_modified->value.data;
 
@@ -1121,7 +1121,7 @@ ngx_http_variable_sent_last_modified(ngx
 
         v->len = ngx_http_time(p, r->headers_out.last_modified_time) - p;
         v->valid = 1;
-        v->no_cachable = 0;
+        v->no_cacheable = 0;
         v->not_found = 0;
         v->data = p;
 
@@ -1152,7 +1152,7 @@ ngx_http_variable_sent_connection(ngx_ht
 
     v->len = len;
     v->valid = 1;
-    v->no_cachable = 0;
+    v->no_cacheable = 0;
     v->not_found = 0;
     v->data = (u_char *) p;
 
@@ -1179,7 +1179,7 @@ ngx_http_variable_sent_keep_alive(ngx_ht
 
             v->len = ngx_sprintf(p, "timeout=%T", clcf->keepalive_header) - p;
             v->valid = 1;
-            v->no_cachable = 0;
+            v->no_cacheable = 0;
             v->not_found = 0;
             v->data = p;
 
@@ -1200,7 +1200,7 @@ ngx_http_variable_sent_transfer_encoding
     if (r->chunked) {
         v->len = sizeof("chunked") - 1;
         v->valid = 1;
-        v->no_cachable = 0;
+        v->no_cacheable = 0;
         v->not_found = 0;
         v->data = (u_char *) "chunked";
 
@@ -1219,7 +1219,7 @@ ngx_http_variable_request_completion(ngx
     if (r->request_complete) {
         v->len = 2;
         v->valid = 1;
-        v->no_cachable = 0;
+        v->no_cacheable = 0;
         v->not_found = 0;
         v->data = (u_char *) "OK";
 
@@ -1228,7 +1228,7 @@ ngx_http_variable_request_completion(ngx
 
     v->len = 0;
     v->valid = 1;
-    v->no_cachable = 0;
+    v->no_cacheable = 0;
     v->not_found = 0;
     v->data = (u_char *) "";
 
@@ -1248,7 +1248,7 @@ ngx_http_variable_request_body_file(ngx_
 
     v->len = r->request_body->temp_file->file.name.len;
     v->valid = 1;
-    v->no_cachable = 0;
+    v->no_cacheable = 0;
     v->not_found = 0;
     v->data = r->request_body->temp_file->file.name.data;
 
@@ -1262,7 +1262,7 @@ ngx_http_variable_nginx_version(ngx_http
 {
     v->len = sizeof(NGINX_VERSION) - 1;
     v->valid = 1;
-    v->no_cachable = 0;
+    v->no_cacheable = 0;
     v->not_found = 0;
     v->data = (u_char *) NGINX_VERSION;
 
@@ -1370,7 +1370,7 @@ ngx_http_variables_init_vars(ngx_conf_t 
         if (ngx_strncmp(v[i].name.data, "upstream_http_", 14) == 0) {
             v[i].get_handler = ngx_http_upstream_header_variable;
             v[i].data = (uintptr_t) &v[i].name;
-            v[i].flags = NGX_HTTP_VAR_NOCACHABLE;
+            v[i].flags = NGX_HTTP_VAR_NOCACHEABLE;
 
             continue;
         }
--- a/src/http/ngx_http_variables.h
+++ b/src/http/ngx_http_variables.h
@@ -26,10 +26,10 @@ typedef ngx_int_t (*ngx_http_get_variabl
     ngx_http_variable_value_t *v, uintptr_t data);
 
 
-#define NGX_HTTP_VAR_CHANGABLE   1
-#define NGX_HTTP_VAR_NOCACHABLE  2
-#define NGX_HTTP_VAR_INDEXED     4
-#define NGX_HTTP_VAR_NOHASH      8
+#define NGX_HTTP_VAR_CHANGEABLE   1
+#define NGX_HTTP_VAR_NOCACHEABLE  2
+#define NGX_HTTP_VAR_INDEXED      4
+#define NGX_HTTP_VAR_NOHASH       8
 
 
 struct ngx_http_variable_s {
--- a/src/mail/ngx_mail_auth_http_module.c
+++ b/src/mail/ngx_mail_auth_http_module.c
@@ -1368,7 +1368,7 @@ ngx_mail_auth_http(ngx_conf_t *cf, ngx_c
         u.url.data += 7;
     }
 
-    if (ngx_parse_url(cf, &u) != NGX_OK) {
+    if (ngx_parse_url(cf->pool, &u) != NGX_OK) {
         if (u.err) {
             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                                "%s in auth_http \"%V\"", u.err, &u.url);
--- a/src/mail/ngx_mail_core_module.c
+++ b/src/mail/ngx_mail_core_module.c
@@ -285,7 +285,7 @@ ngx_mail_core_listen(ngx_conf_t *cf, ngx
     u.url = value[1];
     u.listen = 1;
 
-    if (ngx_parse_url(cf, &u) != NGX_OK) {
+    if (ngx_parse_url(cf->pool, &u) != NGX_OK) {
         if (u.err) {
             ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
                                "%s in \"%V\" of the \"listen\" directive",
--- a/src/os/unix/ngx_process_cycle.c
+++ b/src/os/unix/ngx_process_cycle.c
@@ -14,7 +14,7 @@ static void ngx_start_worker_processes(n
     ngx_int_t type);
 static void ngx_start_garbage_collector(ngx_cycle_t *cycle, ngx_int_t type);
 static void ngx_signal_worker_processes(ngx_cycle_t *cycle, int signo);
-static ngx_uint_t ngx_reap_childs(ngx_cycle_t *cycle);
+static ngx_uint_t ngx_reap_children(ngx_cycle_t *cycle);
 static void ngx_master_process_exit(ngx_cycle_t *cycle);
 static void ngx_worker_process_cycle(ngx_cycle_t *cycle, void *data);
 static void ngx_worker_process_init(ngx_cycle_t *cycle, ngx_uint_t priority);
@@ -157,9 +157,9 @@ ngx_master_process_cycle(ngx_cycle_t *cy
 
         if (ngx_reap) {
             ngx_reap = 0;
-            ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "reap childs");
+            ngx_log_debug0(NGX_LOG_DEBUG_EVENT, cycle->log, 0, "reap children");
 
-            live = ngx_reap_childs(cycle);
+            live = ngx_reap_children(cycle);
         }
 
         if (!live && (ngx_terminate || ngx_quit)) {
@@ -496,7 +496,7 @@ ngx_signal_worker_processes(ngx_cycle_t 
 
 
 static ngx_uint_t
-ngx_reap_childs(ngx_cycle_t *cycle)
+ngx_reap_children(ngx_cycle_t *cycle)
 {
     ngx_int_t         i, n;
     ngx_uint_t        live;
--- a/src/os/unix/ngx_solaris_init.c
+++ b/src/os/unix/ngx_solaris_init.c
@@ -57,7 +57,7 @@ ngx_os_specific_init(ngx_log_t *log)
 
     ngx_os_io = ngx_solaris_io;
 
-    return NGX_OK;;
+    return NGX_OK;
 }