Merge branch 'nginx' (nginx-1.13.6).

Change-Id: I6ed1ac615bf9f55a7af73d70ff56f762c7079f21
Signed-off-by: Piotr Sikora <piotrsikora@google.com>
diff --git a/.hgtags b/.hgtags
index 34afa6e..2fb896b 100644
--- a/.hgtags
+++ b/.hgtags
@@ -418,3 +418,4 @@
 8457ce87640f9bfe6221c4ac4466ced20e03bebe release-1.13.3
 bbc642c813c829963ce8197c0ca237ab7601f3d4 release-1.13.4
 0d45b4cf7c2e4e626a5a16e1fe604402ace1cea5 release-1.13.5
+f87da7d9ca02b8ced4caa6c5eb9013ccd47b0117 release-1.13.6
diff --git a/BUILD b/BUILD
index d854521..e755c70 100644
--- a/BUILD
+++ b/BUILD
@@ -1485,5 +1485,5 @@
     preinst = "@nginx_pkgoss//:debian_preinst",
     prerm = "@nginx_pkgoss//:debian_prerm",
     section = "httpd",
-    version = "1.13.5",
+    version = "1.13.6",
 )
diff --git a/build.bzl b/build.bzl
index d5b7bc3..392d757 100644
--- a/build.bzl
+++ b/build.bzl
@@ -663,7 +663,7 @@
         name = "nginx_pkgoss",
         build_file_content = _PKGOSS_BUILD_FILE.format(nginx = nginx) +
                              _PKGOSS_BUILD_FILE_TAIL,
-        commit = "ecc0c4d87d10115ccd2797700fbfd8a82ca3c8c2",  # nginx-1.13.5
+        commit = "dbf0142dca592d4ba0c47c7837bbc473a043f19b",  # nginx-1.13.6
         remote = "https://nginx.googlesource.com/nginx-pkgoss",
     )
 
diff --git a/conf/mime.types b/conf/mime.types
index 89be9a4..8a2348a 100644
--- a/conf/mime.types
+++ b/conf/mime.types
@@ -1,89 +1,95 @@
 
 types {
-    text/html                             html htm shtml;
-    text/css                              css;
-    text/xml                              xml;
-    image/gif                             gif;
-    image/jpeg                            jpeg jpg;
-    application/javascript                js;
-    application/atom+xml                  atom;
-    application/rss+xml                   rss;
+    text/html                                        html htm shtml;
+    text/css                                         css;
+    text/xml                                         xml;
+    image/gif                                        gif;
+    image/jpeg                                       jpeg jpg;
+    application/javascript                           js;
+    application/atom+xml                             atom;
+    application/rss+xml                              rss;
 
-    text/mathml                           mml;
-    text/plain                            txt;
-    text/vnd.sun.j2me.app-descriptor      jad;
-    text/vnd.wap.wml                      wml;
-    text/x-component                      htc;
+    text/mathml                                      mml;
+    text/plain                                       txt;
+    text/vnd.sun.j2me.app-descriptor                 jad;
+    text/vnd.wap.wml                                 wml;
+    text/x-component                                 htc;
 
-    image/png                             png;
-    image/tiff                            tif tiff;
-    image/vnd.wap.wbmp                    wbmp;
-    image/x-icon                          ico;
-    image/x-jng                           jng;
-    image/x-ms-bmp                        bmp;
-    image/svg+xml                         svg svgz;
-    image/webp                            webp;
+    image/png                                        png;
+    image/svg+xml                                    svg svgz;
+    image/tiff                                       tif tiff;
+    image/vnd.wap.wbmp                               wbmp;
+    image/webp                                       webp;
+    image/x-icon                                     ico;
+    image/x-jng                                      jng;
+    image/x-ms-bmp                                   bmp;
 
-    application/font-woff                 woff;
-    application/java-archive              jar war ear;
-    application/json                      json;
-    application/mac-binhex40              hqx;
-    application/msword                    doc;
-    application/pdf                       pdf;
-    application/postscript                ps eps ai;
-    application/rtf                       rtf;
-    application/vnd.apple.mpegurl         m3u8;
-    application/vnd.ms-excel              xls;
-    application/vnd.ms-fontobject         eot;
-    application/vnd.ms-powerpoint         ppt;
-    application/vnd.wap.wmlc              wmlc;
-    application/vnd.google-earth.kml+xml  kml;
-    application/vnd.google-earth.kmz      kmz;
-    application/x-7z-compressed           7z;
-    application/x-cocoa                   cco;
-    application/x-java-archive-diff       jardiff;
-    application/x-java-jnlp-file          jnlp;
-    application/x-makeself                run;
-    application/x-perl                    pl pm;
-    application/x-pilot                   prc pdb;
-    application/x-rar-compressed          rar;
-    application/x-redhat-package-manager  rpm;
-    application/x-sea                     sea;
-    application/x-shockwave-flash         swf;
-    application/x-stuffit                 sit;
-    application/x-tcl                     tcl tk;
-    application/x-x509-ca-cert            der pem crt;
-    application/x-xpinstall               xpi;
-    application/xhtml+xml                 xhtml;
-    application/xspf+xml                  xspf;
-    application/zip                       zip;
+    application/font-woff                            woff;
+    application/java-archive                         jar war ear;
+    application/json                                 json;
+    application/mac-binhex40                         hqx;
+    application/msword                               doc;
+    application/pdf                                  pdf;
+    application/postscript                           ps eps ai;
+    application/rtf                                  rtf;
+    application/vnd.apple.mpegurl                    m3u8;
+    application/vnd.google-earth.kml+xml             kml;
+    application/vnd.google-earth.kmz                 kmz;
+    application/vnd.ms-excel                         xls;
+    application/vnd.ms-fontobject                    eot;
+    application/vnd.ms-powerpoint                    ppt;
+    application/vnd.oasis.opendocument.graphics      odg;
+    application/vnd.oasis.opendocument.presentation  odp;
+    application/vnd.oasis.opendocument.spreadsheet   ods;
+    application/vnd.oasis.opendocument.text          odt;
+    application/vnd.openxmlformats-officedocument.presentationml.presentation
+                                                     pptx;
+    application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
+                                                     xlsx;
+    application/vnd.openxmlformats-officedocument.wordprocessingml.document
+                                                     docx;
+    application/vnd.wap.wmlc                         wmlc;
+    application/x-7z-compressed                      7z;
+    application/x-cocoa                              cco;
+    application/x-java-archive-diff                  jardiff;
+    application/x-java-jnlp-file                     jnlp;
+    application/x-makeself                           run;
+    application/x-perl                               pl pm;
+    application/x-pilot                              prc pdb;
+    application/x-rar-compressed                     rar;
+    application/x-redhat-package-manager             rpm;
+    application/x-sea                                sea;
+    application/x-shockwave-flash                    swf;
+    application/x-stuffit                            sit;
+    application/x-tcl                                tcl tk;
+    application/x-x509-ca-cert                       der pem crt;
+    application/x-xpinstall                          xpi;
+    application/xhtml+xml                            xhtml;
+    application/xspf+xml                             xspf;
+    application/zip                                  zip;
 
-    application/octet-stream              bin exe dll;
-    application/octet-stream              deb;
-    application/octet-stream              dmg;
-    application/octet-stream              iso img;
-    application/octet-stream              msi msp msm;
+    application/octet-stream                         bin exe dll;
+    application/octet-stream                         deb;
+    application/octet-stream                         dmg;
+    application/octet-stream                         iso img;
+    application/octet-stream                         msi msp msm;
 
-    application/vnd.openxmlformats-officedocument.wordprocessingml.document    docx;
-    application/vnd.openxmlformats-officedocument.spreadsheetml.sheet          xlsx;
-    application/vnd.openxmlformats-officedocument.presentationml.presentation  pptx;
+    audio/midi                                       mid midi kar;
+    audio/mpeg                                       mp3;
+    audio/ogg                                        ogg;
+    audio/x-m4a                                      m4a;
+    audio/x-realaudio                                ra;
 
-    audio/midi                            mid midi kar;
-    audio/mpeg                            mp3;
-    audio/ogg                             ogg;
-    audio/x-m4a                           m4a;
-    audio/x-realaudio                     ra;
-
-    video/3gpp                            3gpp 3gp;
-    video/mp2t                            ts;
-    video/mp4                             mp4;
-    video/mpeg                            mpeg mpg;
-    video/quicktime                       mov;
-    video/webm                            webm;
-    video/x-flv                           flv;
-    video/x-m4v                           m4v;
-    video/x-mng                           mng;
-    video/x-ms-asf                        asx asf;
-    video/x-ms-wmv                        wmv;
-    video/x-msvideo                       avi;
+    video/3gpp                                       3gpp 3gp;
+    video/mp2t                                       ts;
+    video/mp4                                        mp4;
+    video/mpeg                                       mpeg mpg;
+    video/quicktime                                  mov;
+    video/webm                                       webm;
+    video/x-flv                                      flv;
+    video/x-m4v                                      m4v;
+    video/x-mng                                      mng;
+    video/x-ms-asf                                   asx asf;
+    video/x-ms-wmv                                   wmv;
+    video/x-msvideo                                  avi;
 }
diff --git a/docs/xml/nginx/changes.xml b/docs/xml/nginx/changes.xml
index 2898814..3058462 100644
--- a/docs/xml/nginx/changes.xml
+++ b/docs/xml/nginx/changes.xml
@@ -5,6 +5,126 @@
 <change_log title="nginx">
 
 
+<changes ver="1.13.6" date="2017-10-10">
+
+<change type="bugfix">
+<para lang="ru">
+при использовании директивы ssl_preread
+в модуле stream не работало переключение на следующий бэкенд.
+</para>
+<para lang="en">
+switching to the next upstream server in the stream module did not work
+when using the "ssl_preread" directive.
+</para>
+</change>
+
+<change type="bugfix">
+<para lang="ru">
+в модуле ngx_http_v2_module.<br/>
+Спасибо Piotr Sikora.
+</para>
+<para lang="en">
+in the ngx_http_v2_module.<br/>
+Thanks to Piotr Sikora.
+</para>
+</change>
+
+<change type="bugfix">
+<para lang="ru">
+nginx не поддерживал даты после 2038 года
+на 32-битных платформах с 64-битным time_t.
+</para>
+<para lang="en">
+nginx did not support dates after the year 2038
+on 32-bit platforms with 64-bit time_t.
+</para>
+</change>
+
+<change type="bugfix">
+<para lang="ru">
+в обработке дат до 1970 года и после 10000 года.
+</para>
+<para lang="en">
+in handling of dates prior to the year 1970 and after the year 10000.
+</para>
+</change>
+
+<change type="bugfix">
+<para lang="ru">
+в модуле stream таймауты ожидания UDP-пакетов от бэкендов
+не логгировались или логгировались на уровне info вместо error.
+</para>
+<para lang="en">
+in the stream module timeouts waiting for UDP datagrams from upstream servers
+were not logged or logged at the "info" level instead of "error".
+</para>
+</change>
+
+<change type="bugfix">
+<para lang="ru">
+при использовании HTTP/2 nginx мог вернуть ошибку 400,
+не указав в логе причину.
+</para>
+<para lang="en">
+when using HTTP/2 nginx might return the 400 response
+without logging the reason.
+</para>
+</change>
+
+<change type="bugfix">
+<para lang="ru">
+в обработке повреждённых файлов кэша.
+</para>
+<para lang="en">
+in processing of corrupted cache files.
+</para>
+</change>
+
+<change type="bugfix">
+<para lang="ru">
+при кэшировании ошибок, перехваченных error_page,
+не учитывались заголовки управления кэшированием.
+</para>
+<para lang="en">
+cache control headers were ignored
+when caching errors intercepted by error_page.
+</para>
+</change>
+
+<change type="bugfix">
+<para lang="ru">
+при использовании HTTP/2 тело запроса могло быть повреждено.
+</para>
+<para lang="en">
+when using HTTP/2 client request body might be corrupted.
+</para>
+</change>
+
+<change type="bugfix">
+<para lang="ru">
+в обработке адресов клиентов при использовании unix domain сокетов.
+</para>
+<para lang="en">
+in handling of client addresses when using unix domain sockets.
+</para>
+</change>
+
+<change type="bugfix">
+<para lang="ru">
+при использовании директивы "hash ... consistent" в блоке upstream
+nginx нагружал процессор, если использовались большие веса
+и все или почти все бэкенды были недоступны.
+</para>
+<para lang="en">
+nginx hogged CPU
+when using the "hash ... consistent" directive in the upstream block
+if large weights were used and all or most of the servers were unavailable.
+</para>
+</change>
+
+</changes>
+
+
 <changes ver="1.13.5" date="2017-09-05">
 
 <change type="feature">
@@ -50,7 +170,7 @@
 <para lang="en">
 the "expires modified" directive and
 processing of the "If-Range" request header line
-did not use the response last modification time 
+did not use the response last modification time
 if proxying without caching was used.
 </para>
 </change>
diff --git a/src/core/nginx.h b/src/core/nginx.h
index a1d2838..a53f5a8 100644
--- a/src/core/nginx.h
+++ b/src/core/nginx.h
@@ -13,8 +13,8 @@
 #define NGINX_NAME         "nginx"
 #endif
 
-#define nginx_version      1013005
-#define NGINX_VERSION      "1.13.5"
+#define nginx_version      1013006
+#define NGINX_VERSION      "1.13.6"
 #define NGINX_VER          NGINX_NAME "/" NGINX_VERSION
 
 #ifdef NGX_BUILD
diff --git a/src/core/ngx_connection.c b/src/core/ngx_connection.c
index 392fc35..9a74758 100644
--- a/src/core/ngx_connection.c
+++ b/src/core/ngx_connection.c
@@ -165,6 +165,10 @@
             continue;
         }
 
+        if (ls[i].socklen > (socklen_t) sizeof(ngx_sockaddr_t)) {
+            ls[i].socklen = sizeof(ngx_sockaddr_t);
+        }
+
         switch (ls[i].sockaddr->sa_family) {
 
 #if (NGX_HAVE_INET6)
diff --git a/src/core/ngx_inet.c b/src/core/ngx_inet.c
index 3bcd3e7..db48b93 100644
--- a/src/core/ngx_inet.c
+++ b/src/core/ngx_inet.c
@@ -182,9 +182,11 @@
     ngx_uint_t port)
 {
     u_char               *p;
+#if (NGX_HAVE_INET6 || NGX_HAVE_UNIX_DOMAIN)
+    size_t                n;
+#endif
     struct sockaddr_in   *sin;
 #if (NGX_HAVE_INET6)
-    size_t                n;
     struct sockaddr_in6  *sin6;
 #endif
 #if (NGX_HAVE_UNIX_DOMAIN)
@@ -241,7 +243,9 @@
             p = ngx_snprintf(text, len, "unix:%Z");
 
         } else {
-            p = ngx_snprintf(text, len, "unix:%s%Z", saun->sun_path);
+            n = ngx_strnlen((u_char *) saun->sun_path,
+                            socklen - offsetof(struct sockaddr_un, sun_path));
+            p = ngx_snprintf(text, len, "unix:%*s%Z", n, saun->sun_path);
         }
 
         /* we do not include trailing zero in address length */
diff --git a/src/core/ngx_inet.h b/src/core/ngx_inet.h
index 538771e..a3b392e 100644
--- a/src/core/ngx_inet.h
+++ b/src/core/ngx_inet.h
@@ -17,10 +17,11 @@
 #define NGX_INET6_ADDRSTRLEN                                                 \
     (sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255") - 1)
 #define NGX_UNIX_ADDRSTRLEN                                                  \
-    (sizeof(struct sockaddr_un) - offsetof(struct sockaddr_un, sun_path))
+    (sizeof("unix:") - 1 +                                                   \
+     sizeof(struct sockaddr_un) - offsetof(struct sockaddr_un, sun_path))
 
 #if (NGX_HAVE_UNIX_DOMAIN)
-#define NGX_SOCKADDR_STRLEN   (sizeof("unix:") - 1 + NGX_UNIX_ADDRSTRLEN)
+#define NGX_SOCKADDR_STRLEN   NGX_UNIX_ADDRSTRLEN
 #elif (NGX_HAVE_INET6)
 #define NGX_SOCKADDR_STRLEN   (NGX_INET6_ADDRSTRLEN + sizeof("[]:65535") - 1)
 #else
diff --git a/src/core/ngx_parse_time.c b/src/core/ngx_parse_time.c
index a5c5034..232ac91 100644
--- a/src/core/ngx_parse_time.c
+++ b/src/core/ngx_parse_time.c
@@ -44,14 +44,15 @@
         }
     }
 
-    for (p++; p < end; p++)
+    for (p++; p < end; p++) {
         if (*p != ' ') {
             break;
         }
+    }
 
     if (end - p < 18) {
         return NGX_ERROR;
-        }
+    }
 
     if (fmt != isoc) {
         if (*p < '0' || *p > '9' || *(p + 1) < '0' || *(p + 1) > '9') {
diff --git a/src/core/ngx_string.c b/src/core/ngx_string.c
index de10a06..2ee07bf 100644
--- a/src/core/ngx_string.c
+++ b/src/core/ngx_string.c
@@ -29,6 +29,22 @@
 }
 
 
+size_t
+ngx_strnlen(u_char *p, size_t n)
+{
+    size_t  i;
+
+    for (i = 0; i < n; i++) {
+
+        if (p[i] == '\0') {
+            return i;
+        }
+    }
+
+    return n;
+}
+
+
 u_char *
 ngx_cpystrn(u_char *dst, u_char *src, size_t n)
 {
diff --git a/src/core/ngx_string.h b/src/core/ngx_string.h
index 7363bd2..882ae7c 100644
--- a/src/core/ngx_string.h
+++ b/src/core/ngx_string.h
@@ -60,6 +60,8 @@
 #define ngx_strstr(s1, s2)  strstr((const char *) s1, (const char *) s2)
 #define ngx_strlen(s)       strlen((const char *) s)
 
+size_t ngx_strnlen(u_char *p, size_t n);
+
 #define ngx_strchr(s1, c)   strchr((const char *) s1, (int) c)
 
 static ngx_inline u_char *
diff --git a/src/core/ngx_times.c b/src/core/ngx_times.c
index 558804e..d8818ab 100644
--- a/src/core/ngx_times.c
+++ b/src/core/ngx_times.c
@@ -300,27 +300,39 @@
 ngx_gmtime(time_t t, ngx_tm_t *tp)
 {
     ngx_int_t   yday;
-    ngx_uint_t  n, sec, min, hour, mday, mon, year, wday, days, leap;
+    ngx_uint_t  sec, min, hour, mday, mon, year, wday, days, leap;
 
     /* the calculation is valid for positive time_t only */
 
-    n = (ngx_uint_t) t;
+    if (t < 0) {
+        t = 0;
+    }
 
-    days = n / 86400;
+    days = t / 86400;
+    sec = t % 86400;
+
+    /*
+     * no more than 4 year digits supported,
+     * truncate to December 31, 9999, 23:59:59
+     */
+
+    if (days > 2932896) {
+        days = 2932896;
+        sec = 86399;
+    }
 
     /* January 1, 1970 was Thursday */
 
     wday = (4 + days) % 7;
 
-    n %= 86400;
-    hour = n / 3600;
-    n %= 3600;
-    min = n / 60;
-    sec = n % 60;
+    hour = sec / 3600;
+    sec %= 3600;
+    min = sec / 60;
+    sec %= 60;
 
     /*
      * the algorithm based on Gauss' formula,
-     * see src/http/ngx_http_parse_time.c
+     * see src/core/ngx_parse_time.c
      */
 
     /* days since March 1, 1 BC */
diff --git a/src/event/ngx_event_accept.c b/src/event/ngx_event_accept.c
index 87447d0..7756370 100644
--- a/src/event/ngx_event_accept.c
+++ b/src/event/ngx_event_accept.c
@@ -164,6 +164,10 @@
             return;
         }
 
+        if (socklen > (socklen_t) sizeof(ngx_sockaddr_t)) {
+            socklen = sizeof(ngx_sockaddr_t);
+        }
+
         c->sockaddr = ngx_palloc(c->pool, socklen);
         if (c->sockaddr == NULL) {
             ngx_close_accepted_connection(c);
@@ -440,6 +444,10 @@
         c->type = SOCK_DGRAM;
         c->socklen = msg.msg_namelen;
 
+        if (c->socklen > (socklen_t) sizeof(ngx_sockaddr_t)) {
+            c->socklen = sizeof(ngx_sockaddr_t);
+        }
+
 #if (NGX_STAT_STUB)
         (void) ngx_atomic_fetch_add(ngx_stat_active, 1);
 #endif
diff --git a/src/http/modules/ngx_http_auth_basic_module.c b/src/http/modules/ngx_http_auth_basic_module.c
index 4aa684f..2f345b6 100644
--- a/src/http/modules/ngx_http_auth_basic_module.c
+++ b/src/http/modules/ngx_http_auth_basic_module.c
@@ -15,11 +15,6 @@
 
 
 typedef struct {
-    ngx_str_t                 passwd;
-} ngx_http_auth_basic_ctx_t;
-
-
-typedef struct {
     ngx_http_complex_value_t  *realm;
     ngx_http_complex_value_t   user_file;
 } ngx_http_auth_basic_loc_conf_t;
@@ -27,7 +22,7 @@
 
 static ngx_int_t ngx_http_auth_basic_handler(ngx_http_request_t *r);
 static ngx_int_t ngx_http_auth_basic_crypt_handler(ngx_http_request_t *r,
-    ngx_http_auth_basic_ctx_t *ctx, ngx_str_t *passwd, ngx_str_t *realm);
+    ngx_str_t *passwd, ngx_str_t *realm);
 static ngx_int_t ngx_http_auth_basic_set_realm(ngx_http_request_t *r,
     ngx_str_t *realm);
 static void ngx_http_auth_basic_close(ngx_file_t *file);
@@ -103,7 +98,6 @@
     ngx_str_t                        pwd, realm, user_file;
     ngx_uint_t                       i, level, login, left, passwd;
     ngx_file_t                       file;
-    ngx_http_auth_basic_ctx_t       *ctx;
     ngx_http_auth_basic_loc_conf_t  *alcf;
     u_char                           buf[NGX_HTTP_AUTH_BUF_SIZE];
     enum {
@@ -126,13 +120,6 @@
         return NGX_DECLINED;
     }
 
-    ctx = ngx_http_get_module_ctx(r, ngx_http_auth_basic_module);
-
-    if (ctx) {
-        return ngx_http_auth_basic_crypt_handler(r, ctx, &ctx->passwd,
-                                                 &realm);
-    }
-
     rc = ngx_http_auth_basic_user(r);
 
     if (rc == NGX_DECLINED) {
@@ -237,8 +224,7 @@
                     pwd.len = i - passwd;
                     pwd.data = &buf[passwd];
 
-                    return ngx_http_auth_basic_crypt_handler(r, NULL, &pwd,
-                                                             &realm);
+                    return ngx_http_auth_basic_crypt_handler(r, &pwd, &realm);
                 }
 
                 break;
@@ -276,7 +262,7 @@
 
         ngx_cpystrn(pwd.data, &buf[passwd], pwd.len + 1);
 
-        return ngx_http_auth_basic_crypt_handler(r, NULL, &pwd, &realm);
+        return ngx_http_auth_basic_crypt_handler(r, &pwd, &realm);
     }
 
     ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
@@ -288,8 +274,8 @@
 
 
 static ngx_int_t
-ngx_http_auth_basic_crypt_handler(ngx_http_request_t *r,
-    ngx_http_auth_basic_ctx_t *ctx, ngx_str_t *passwd, ngx_str_t *realm)
+ngx_http_auth_basic_crypt_handler(ngx_http_request_t *r, ngx_str_t *passwd,
+    ngx_str_t *realm)
 {
     ngx_int_t   rc;
     u_char     *encrypted;
@@ -301,48 +287,22 @@
                    "rc: %i user: \"%V\" salt: \"%s\"",
                    rc, &r->headers_in.user, passwd->data);
 
-    if (rc == NGX_OK) {
-        if (ngx_strcmp(encrypted, passwd->data) == 0) {
-            return NGX_OK;
-        }
-
-        ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
-                       "encrypted: \"%s\"", encrypted);
-
-        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
-                      "user \"%V\": password mismatch",
-                      &r->headers_in.user);
-
-        return ngx_http_auth_basic_set_realm(r, realm);
-    }
-
-    if (rc == NGX_ERROR) {
+    if (rc != NGX_OK) {
         return NGX_HTTP_INTERNAL_SERVER_ERROR;
     }
 
-    /* rc == NGX_AGAIN */
-
-    if (ctx == NULL) {
-        ctx = ngx_palloc(r->pool, sizeof(ngx_http_auth_basic_ctx_t));
-        if (ctx == NULL) {
-            return NGX_HTTP_INTERNAL_SERVER_ERROR;
-        }
-
-        ngx_http_set_ctx(r, ctx, ngx_http_auth_basic_module);
-
-        ctx->passwd.len = passwd->len;
-        passwd->len++;
-
-        ctx->passwd.data = ngx_pstrdup(r->pool, passwd);
-        if (ctx->passwd.data == NULL) {
-            return NGX_HTTP_INTERNAL_SERVER_ERROR;
-        }
-
+    if (ngx_strcmp(encrypted, passwd->data) == 0) {
+        return NGX_OK;
     }
 
-    /* TODO: add mutex event */
+    ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
+                   "encrypted: \"%s\"", encrypted);
 
-    return rc;
+    ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+                  "user \"%V\": password mismatch",
+                  &r->headers_in.user);
+
+    return ngx_http_auth_basic_set_realm(r, realm);
 }
 
 
diff --git a/src/http/modules/ngx_http_upstream_hash_module.c b/src/http/modules/ngx_http_upstream_hash_module.c
index 6c28c64..d67f34d 100644
--- a/src/http/modules/ngx_http_upstream_hash_module.c
+++ b/src/http/modules/ngx_http_upstream_hash_module.c
@@ -503,6 +503,11 @@
 
     ngx_http_upstream_rr_peers_wlock(hp->rrp.peers);
 
+    if (hp->tries > 20 || hp->rrp.peers->single) {
+        ngx_http_upstream_rr_peers_unlock(hp->rrp.peers);
+        return hp->get_rr_peer(pc, &hp->rrp);
+    }
+
     pc->cached = 0;
     pc->connection = NULL;
 
@@ -538,13 +543,6 @@
                 continue;
             }
 
-            if (peer->server.len != server->len
-                || ngx_strncmp(peer->server.data, server->data, server->len)
-                   != 0)
-            {
-                continue;
-            }
-
             if (peer->max_fails
                 && peer->fails >= peer->max_fails
                 && now - peer->checked <= peer->fail_timeout)
@@ -556,6 +554,13 @@
                 continue;
             }
 
+            if (peer->server.len != server->len
+                || ngx_strncmp(peer->server.data, server->data, server->len)
+                   != 0)
+            {
+                continue;
+            }
+
             peer->current_weight += peer->effective_weight;
             total += peer->effective_weight;
 
@@ -577,10 +582,9 @@
         hp->hash++;
         hp->tries++;
 
-        if (hp->tries >= points->number) {
-            pc->name = hp->rrp.peers->name;
+        if (hp->tries > 20) {
             ngx_http_upstream_rr_peers_unlock(hp->rrp.peers);
-            return NGX_BUSY;
+            return hp->get_rr_peer(pc, &hp->rrp);
         }
     }
 
diff --git a/src/http/modules/ngx_http_upstream_zone_module.c b/src/http/modules/ngx_http_upstream_zone_module.c
index d340b48..3229cfe 100644
--- a/src/http/modules/ngx_http_upstream_zone_module.c
+++ b/src/http/modules/ngx_http_upstream_zone_module.c
@@ -281,7 +281,7 @@
         dst->server.data = NULL;
     }
 
-    dst->sockaddr = ngx_slab_calloc_locked(pool, NGX_SOCKADDRLEN);
+    dst->sockaddr = ngx_slab_calloc_locked(pool, sizeof(ngx_sockaddr_t));
     if (dst->sockaddr == NULL) {
         goto failed;
     }
diff --git a/src/http/ngx_http_upstream.c b/src/http/ngx_http_upstream.c
index 88142c9..f4bd6dc 100644
--- a/src/http/ngx_http_upstream.c
+++ b/src/http/ngx_http_upstream.c
@@ -599,6 +599,9 @@
             if (rc == NGX_HTTP_UPSTREAM_INVALID_HEADER) {
                 rc = NGX_DECLINED;
                 r->cached = 0;
+                u->buffer.start = NULL;
+                u->cache_status = NGX_HTTP_CACHE_MISS;
+                u->request_sent = 1;
             }
 
             if (ngx_http_upstream_cache_background_update(r, u) != NGX_OK) {
@@ -1083,8 +1086,16 @@
         return NGX_ERROR;
     }
 
+    if (rc == NGX_AGAIN) {
+        rc = NGX_HTTP_UPSTREAM_INVALID_HEADER;
+    }
+
     /* rc == NGX_HTTP_UPSTREAM_INVALID_HEADER */
 
+    ngx_log_error(NGX_LOG_CRIT, r->connection->log, 0,
+                  "cache file \"%s\" contains invalid header",
+                  c->file.name.data);
+
     /* TODO: delete file */
 
     return rc;
@@ -2437,9 +2448,20 @@
 
             rc = u->reinit_request(r);
 
-            if (rc == NGX_OK) {
-                u->cache_status = NGX_HTTP_CACHE_STALE;
-                rc = ngx_http_upstream_cache_send(r, u);
+            if (rc != NGX_OK) {
+                ngx_http_upstream_finalize_request(r, u, rc);
+                return NGX_OK;
+            }
+
+            u->cache_status = NGX_HTTP_CACHE_STALE;
+            rc = ngx_http_upstream_cache_send(r, u);
+
+            if (rc == NGX_DONE) {
+                return NGX_OK;
+            }
+
+            if (rc == NGX_HTTP_UPSTREAM_INVALID_HEADER) {
+                rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
             }
 
             ngx_http_upstream_finalize_request(r, u, rc);
@@ -2477,6 +2499,14 @@
         u->cache_status = NGX_HTTP_CACHE_REVALIDATED;
         rc = ngx_http_upstream_cache_send(r, u);
 
+        if (rc == NGX_DONE) {
+            return NGX_OK;
+        }
+
+        if (rc == NGX_HTTP_UPSTREAM_INVALID_HEADER) {
+            rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
+        }
+
         if (valid == 0) {
             valid = r->cache->valid_sec;
             updating = r->cache->updating_sec;
@@ -2562,13 +2592,23 @@
 #if (NGX_HTTP_CACHE)
 
             if (r->cache) {
-                time_t  valid;
 
-                valid = ngx_http_file_cache_valid(u->conf->cache_valid, status);
+                if (u->cacheable) {
+                    time_t  valid;
 
-                if (valid) {
-                    r->cache->valid_sec = ngx_time() + valid;
-                    r->cache->error = status;
+                    valid = r->cache->valid_sec;
+
+                    if (valid == 0) {
+                        valid = ngx_http_file_cache_valid(u->conf->cache_valid,
+                                                          status);
+                        if (valid) {
+                            r->cache->valid_sec = ngx_time() + valid;
+                        }
+                    }
+
+                    if (valid) {
+                        r->cache->error = status;
+                    }
                 }
 
                 ngx_http_file_cache_free(r->cache, u->pipe->temp_file);
@@ -4215,9 +4255,20 @@
 
             rc = u->reinit_request(r);
 
-            if (rc == NGX_OK) {
-                u->cache_status = NGX_HTTP_CACHE_STALE;
-                rc = ngx_http_upstream_cache_send(r, u);
+            if (rc != NGX_OK) {
+                ngx_http_upstream_finalize_request(r, u, rc);
+                return;
+            }
+
+            u->cache_status = NGX_HTTP_CACHE_STALE;
+            rc = ngx_http_upstream_cache_send(r, u);
+
+            if (rc == NGX_DONE) {
+                return;
+            }
+
+            if (rc == NGX_HTTP_UPSTREAM_INVALID_HEADER) {
+                rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
             }
 
             ngx_http_upstream_finalize_request(r, u, rc);
diff --git a/src/http/ngx_http_upstream.h b/src/http/ngx_http_upstream.h
index ec4cb97..89b5fde 100644
--- a/src/http/ngx_http_upstream.h
+++ b/src/http/ngx_http_upstream.h
@@ -99,8 +99,8 @@
     ngx_uint_t                       max_fails;
     time_t                           fail_timeout;
     ngx_msec_t                       slow_start;
+    ngx_uint_t                       down;
 
-    unsigned                         down:1;
     unsigned                         backup:1;
 
     NGX_COMPAT_BEGIN(6)
diff --git a/src/http/ngx_http_variables.c b/src/http/ngx_http_variables.c
index ae1e509..4d6a667 100644
--- a/src/http/ngx_http_variables.c
+++ b/src/http/ngx_http_variables.c
@@ -1240,6 +1240,18 @@
         break;
 #endif
 
+#if (NGX_HAVE_UNIX_DOMAIN)
+    case AF_UNIX:
+
+        v->len = r->connection->addr_text.len;
+        v->valid = 1;
+        v->no_cacheable = 0;
+        v->not_found = 0;
+        v->data = r->connection->addr_text.data;
+
+        break;
+#endif
+
     default: /* AF_INET */
         sin = (struct sockaddr_in *) r->connection->sockaddr;
 
diff --git a/src/http/v2/ngx_http_v2.c b/src/http/v2/ngx_http_v2.c
index 0701ee4..e72279d 100644
--- a/src/http/v2/ngx_http_v2.c
+++ b/src/http/v2/ngx_http_v2.c
@@ -750,7 +750,7 @@
     type = ngx_http_v2_parse_type(head);
 
     ngx_log_debug4(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
-                   "process http2 frame type:%ui f:%Xd l:%uz sid:%ui",
+                   "http2 frame type:%ui f:%Xd l:%uz sid:%ui",
                    type, h2c->state.flags, h2c->state.length, h2c->state.sid);
 
     if (type >= NGX_HTTP_V2_FRAME_STATES) {
@@ -1318,7 +1318,7 @@
     }
 
     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
-                   "http2 hpack %s string length: %i",
+                   "http2 %s string, len:%i",
                    huff ? "encoded" : "raw", len);
 
     h2scf = ngx_http_get_module_srv_conf(h2c->http_connection->conf_ctx,
@@ -1573,7 +1573,7 @@
 
         if (rc == NGX_OK) {
             ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
-                           "http2 pseudo-header: \":%V: %V\"",
+                           "http2 header: \":%V: %V\"",
                            &header->name, &header->value);
 
             return ngx_http_v2_state_header_complete(h2c, pos, end);
@@ -1649,7 +1649,7 @@
     }
 
     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
-                   "http2 http header: \"%V: %V\"",
+                   "http2 header: \"%V: %V\"",
                    &header->name, &header->value);
 
     return ngx_http_v2_state_header_complete(h2c, pos, end);
@@ -3420,6 +3420,19 @@
         || r->schema_start == NULL
         || r->unparsed_uri.len == 0)
     {
+        if (r->method_name.len == 0) {
+            ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
+                          "client sent no :method header");
+
+        } else if (r->schema_start == NULL) {
+            ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
+                          "client sent no :schema header");
+
+        } else {
+            ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
+                          "client sent no :path header");
+        }
+
         ngx_http_finalize_request(r, NGX_HTTP_BAD_REQUEST);
         return NGX_ERROR;
     }
@@ -3445,7 +3458,7 @@
     ngx_memcpy(p, ending, sizeof(ending));
 
     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
-                   "http2 http request line: \"%V\"", &r->request_line);
+                   "http2 request line: \"%V\"", &r->request_line);
 
     return NGX_OK;
 }
@@ -3659,11 +3672,6 @@
         rb->buf = ngx_create_temp_buf(r->pool, (size_t) len);
 
     } else {
-        if (stream->preread) {
-            /* enforce writing preread buffer to file */
-            r->request_body_in_file_only = 1;
-        }
-
         rb->buf = ngx_calloc_buf(r->pool);
 
         if (rb->buf != NULL) {
@@ -3764,6 +3772,8 @@
             buf->pos = buf->start = pos;
             buf->last = buf->end = pos + size;
 
+            r->request_body_in_file_only = 1;
+
         } else {
             if (size > (size_t) (buf->end - buf->last)) {
                 ngx_log_error(NGX_LOG_INFO, fc->log, 0,
diff --git a/src/http/v2/ngx_http_v2_filter_module.c b/src/http/v2/ngx_http_v2_filter_module.c
index 30f8833..4ece089 100644
--- a/src/http/v2/ngx_http_v2_filter_module.c
+++ b/src/http/v2/ngx_http_v2_filter_module.c
@@ -1278,7 +1278,7 @@
     ngx_http_v2_stream_t *stream)
 {
     ngx_log_debug3(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
-                   "http2:%ui available windows: conn:%uz stream:%z",
+                   "http2:%ui windows: conn:%uz stream:%z",
                    stream->node->id, h2c->send_window, stream->send_window);
 
     if (stream->send_window <= 0) {
diff --git a/src/http/v2/ngx_http_v2_table.c b/src/http/v2/ngx_http_v2_table.c
index a73748a..62025c4 100644
--- a/src/http/v2/ngx_http_v2_table.c
+++ b/src/http/v2/ngx_http_v2_table.c
@@ -102,7 +102,7 @@
 
     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
                    "http2 get indexed %s: %ui",
-                   name_only ? "header" : "header name", index);
+                   name_only ? "name" : "header", index);
 
     index--;
 
@@ -180,7 +180,7 @@
     ngx_http_v2_header_t  *entry, **entries;
 
     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
-                   "http2 add header to hpack table: \"%V: %V\"",
+                   "http2 table add: \"%V: %V\"",
                    &header->name, &header->value);
 
     if (h2c->hpack.entries == NULL) {
@@ -293,7 +293,7 @@
     size += 32;
 
     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
-                   "http2 hpack table account: %uz free:%uz",
+                   "http2 table account: %uz free:%uz",
                    size, h2c->hpack.free);
 
     if (size <= h2c->hpack.free) {
diff --git a/src/os/unix/ngx_user.c b/src/os/unix/ngx_user.c
index 27c76ef..7ebe2b5 100644
--- a/src/os/unix/ngx_user.c
+++ b/src/os/unix/ngx_user.c
@@ -9,16 +9,6 @@
 #include <ngx_core.h>
 
 
-/*
- * Solaris has thread-safe crypt()
- * Linux has crypt_r(); "struct crypt_data" is more than 128K
- * FreeBSD needs the mutex to protect crypt()
- *
- * TODO:
- *     ngx_crypt_init() to init mutex
- */
-
-
 #if (NGX_CRYPT)
 
 #if (NGX_HAVE_GNU_CRYPT_R)
diff --git a/src/stream/ngx_stream_proxy_module.c b/src/stream/ngx_stream_proxy_module.c
index 0afde1c..9d4b075 100644
--- a/src/stream/ngx_stream_proxy_module.c
+++ b/src/stream/ngx_stream_proxy_module.c
@@ -1331,13 +1331,17 @@
                     return;
                 }
 
+                ngx_connection_error(pc, NGX_ETIMEDOUT, "upstream timed out");
+
                 if (u->received == 0) {
                     ngx_stream_proxy_next_upstream(s);
                     return;
                 }
+
+            } else {
+                ngx_connection_error(c, NGX_ETIMEDOUT, "connection timed out");
             }
 
-            ngx_connection_error(c, NGX_ETIMEDOUT, "connection timed out");
             ngx_stream_proxy_finalize(s, NGX_STREAM_OK);
             return;
         }
@@ -1665,13 +1669,17 @@
     u = s->upstream;
     pc = u->peer.connection;
 
-    if (u->upstream_out || u->upstream_busy || (pc && pc->buffered)) {
+    if (pc && pc->buffered) {
         ngx_log_error(NGX_LOG_ERR, s->connection->log, 0,
-                      "pending buffers on next upstream");
+                      "buffered data on next upstream");
         ngx_stream_proxy_finalize(s, NGX_STREAM_INTERNAL_SERVER_ERROR);
         return;
     }
 
+    if (s->connection->type == SOCK_DGRAM) {
+        u->upstream_out = NULL;
+    }
+
     if (u->peer.sockaddr) {
         u->peer.free(&u->peer, u->peer.data, NGX_PEER_FAILED);
         u->peer.sockaddr = NULL;
diff --git a/src/stream/ngx_stream_upstream.h b/src/stream/ngx_stream_upstream.h
index 283ffd8..af1ed04 100644
--- a/src/stream/ngx_stream_upstream.h
+++ b/src/stream/ngx_stream_upstream.h
@@ -58,8 +58,8 @@
     ngx_uint_t                         max_fails;
     time_t                             fail_timeout;
     ngx_msec_t                         slow_start;
+    ngx_uint_t                         down;
 
-    unsigned                           down:1;
     unsigned                           backup:1;
 
     NGX_COMPAT_BEGIN(4)
diff --git a/src/stream/ngx_stream_upstream_hash_module.c b/src/stream/ngx_stream_upstream_hash_module.c
index cb44fcd..79ad742 100644
--- a/src/stream/ngx_stream_upstream_hash_module.c
+++ b/src/stream/ngx_stream_upstream_hash_module.c
@@ -505,6 +505,11 @@
 
     ngx_stream_upstream_rr_peers_wlock(hp->rrp.peers);
 
+    if (hp->tries > 20 || hp->rrp.peers->single) {
+        ngx_stream_upstream_rr_peers_unlock(hp->rrp.peers);
+        return hp->get_rr_peer(pc, &hp->rrp);
+    }
+
     pc->connection = NULL;
 
     now = ngx_time();
@@ -539,13 +544,6 @@
                 continue;
             }
 
-            if (peer->server.len != server->len
-                || ngx_strncmp(peer->server.data, server->data, server->len)
-                   != 0)
-            {
-                continue;
-            }
-
             if (peer->max_fails
                 && peer->fails >= peer->max_fails
                 && now - peer->checked <= peer->fail_timeout)
@@ -557,6 +555,13 @@
                 continue;
             }
 
+            if (peer->server.len != server->len
+                || ngx_strncmp(peer->server.data, server->data, server->len)
+                   != 0)
+            {
+                continue;
+            }
+
             peer->current_weight += peer->effective_weight;
             total += peer->effective_weight;
 
@@ -578,10 +583,9 @@
         hp->hash++;
         hp->tries++;
 
-        if (hp->tries >= points->number) {
-            pc->name = hp->rrp.peers->name;
+        if (hp->tries > 20) {
             ngx_stream_upstream_rr_peers_unlock(hp->rrp.peers);
-            return NGX_BUSY;
+            return hp->get_rr_peer(pc, &hp->rrp);
         }
     }
 
diff --git a/src/stream/ngx_stream_upstream_zone_module.c b/src/stream/ngx_stream_upstream_zone_module.c
index 4f72188..80d42fa 100644
--- a/src/stream/ngx_stream_upstream_zone_module.c
+++ b/src/stream/ngx_stream_upstream_zone_module.c
@@ -278,7 +278,7 @@
         dst->server.data = NULL;
     }
 
-    dst->sockaddr = ngx_slab_calloc_locked(pool, NGX_SOCKADDRLEN);
+    dst->sockaddr = ngx_slab_calloc_locked(pool, sizeof(ngx_sockaddr_t));
     if (dst->sockaddr == NULL) {
         goto failed;
     }
diff --git a/src/stream/ngx_stream_variables.c b/src/stream/ngx_stream_variables.c
index 45d6e60..95ae12b 100644
--- a/src/stream/ngx_stream_variables.c
+++ b/src/stream/ngx_stream_variables.c
@@ -460,7 +460,7 @@
 static ngx_int_t
 ngx_stream_variable_binary_remote_addr(ngx_stream_session_t *s,
      ngx_stream_variable_value_t *v, uintptr_t data)
- {
+{
     struct sockaddr_in   *sin;
 #if (NGX_HAVE_INET6)
     struct sockaddr_in6  *sin6;
@@ -481,6 +481,18 @@
         break;
 #endif
 
+#if (NGX_HAVE_UNIX_DOMAIN)
+    case AF_UNIX:
+
+        v->len = s->connection->addr_text.len;
+        v->valid = 1;
+        v->no_cacheable = 0;
+        v->not_found = 0;
+        v->data = s->connection->addr_text.data;
+
+        break;
+#endif
+
     default: /* AF_INET */
         sin = (struct sockaddr_in *) s->connection->sockaddr;