Hello community,

here is the log from the commit of package nginx for openSUSE:Factory checked 
in at 2017-04-19 18:11:16
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/nginx (Old)
 and      /work/SRC/openSUSE:Factory/.nginx.new (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "nginx"

Wed Apr 19 18:11:16 2017 rev:12 rq:489116 version:1.12.0

Changes:
--------
--- /work/SRC/openSUSE:Factory/nginx/nginx.changes      2017-03-31 
15:10:28.651986194 +0200
+++ /work/SRC/openSUSE:Factory/.nginx.new/nginx.changes 2017-04-19 
18:11:17.625869756 +0200
@@ -1,0 +2,22 @@
+Sun Apr  9 13:15:49 UTC 2017 - mich...@stroeder.com
+
+- update to 1.12.0
+  - Feature: the "http_429" parameter of the "proxy_next_upstream",
+    "fastcgi_next_upstream", "scgi_next_upstream", and
+    "uwsgi_next_upstream" directives.
+    Thanks to Piotr Sikora.
+  - Bugfix: in memory allocation error handling.
+  - Bugfix: requests might hang when using the "sendfile" and
+    "timer_resolution" directives on Linux.
+  - Bugfix: requests might hang when using the "sendfile" and "aio_write"
+    directives with subrequests.
+  - Bugfix: in the ngx_http_v2_module.
+    Thanks to Piotr Sikora.
+  - Bugfix: a segmentation fault might occur in a worker process when
+    using HTTP/2.
+  - Bugfix: requests might hang when using the "limit_rate",
+    "sendfile_max_chunk", "limit_req" directives, or the $r->sleep()
+    embedded perl method with subrequests.
+  - Bugfix: in the ngx_http_slice_module.
+
+-------------------------------------------------------------------

Old:
----
  nginx-1.11.12.tar.gz

New:
----
  nginx-1.12.0.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ nginx.spec ++++++
--- /var/tmp/diff_new_pack.XQSNmT/_old  2017-04-19 18:11:18.841697770 +0200
+++ /var/tmp/diff_new_pack.XQSNmT/_new  2017-04-19 18:11:18.845697204 +0200
@@ -64,7 +64,7 @@
 %define ngx_doc_dir    %{_datadir}/doc/packages/%{name}
 #
 Name:           nginx
-Version:        1.11.12
+Version:        1.12.0
 Release:        0
 %define ngx_fancyindex_version 0.4.1
 %define ngx_fancyindex_module_path ngx-fancyindex-%{ngx_fancyindex_version}

++++++ nginx-1.11.12.tar.gz -> nginx-1.12.0.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nginx-1.11.12/CHANGES new/nginx-1.12.0/CHANGES
--- old/nginx-1.11.12/CHANGES   2017-03-24 16:05:15.000000000 +0100
+++ new/nginx-1.12.0/CHANGES    2017-04-12 16:46:09.000000000 +0200
@@ -1,4 +1,37 @@
 
+Changes with nginx 1.12.0                                        12 Apr 2017
+
+    *) 1.12.x stable branch.
+
+
+Changes with nginx 1.11.13                                       04 Apr 2017
+
+    *) Feature: the "http_429" parameter of the "proxy_next_upstream",
+       "fastcgi_next_upstream", "scgi_next_upstream", and
+       "uwsgi_next_upstream" directives.
+       Thanks to Piotr Sikora.
+
+    *) Bugfix: in memory allocation error handling.
+
+    *) Bugfix: requests might hang when using the "sendfile" and
+       "timer_resolution" directives on Linux.
+
+    *) Bugfix: requests might hang when using the "sendfile" and "aio_write"
+       directives with subrequests.
+
+    *) Bugfix: in the ngx_http_v2_module.
+       Thanks to Piotr Sikora.
+
+    *) Bugfix: a segmentation fault might occur in a worker process when
+       using HTTP/2.
+
+    *) Bugfix: requests might hang when using the "limit_rate",
+       "sendfile_max_chunk", "limit_req" directives, or the $r->sleep()
+       embedded perl method with subrequests.
+
+    *) Bugfix: in the ngx_http_slice_module.
+
+
 Changes with nginx 1.11.12                                       24 Mar 2017
 
     *) Bugfix: nginx might hog CPU; the bug had appeared in 1.11.11.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nginx-1.11.12/CHANGES.ru new/nginx-1.12.0/CHANGES.ru
--- old/nginx-1.11.12/CHANGES.ru        2017-03-24 16:05:12.000000000 +0100
+++ new/nginx-1.12.0/CHANGES.ru 2017-04-12 16:46:06.000000000 +0200
@@ -1,4 +1,36 @@
 
+Изменения в nginx 1.12.0                                          12.04.2017
+
+    *) Стабильная ветка 1.12.x.
+
+
+Изменения в nginx 1.11.13                                         04.04.2017
+
+    *) Добавление: параметр http_429 в директивах proxy_next_upstream,
+       fastcgi_next_upstream, scgi_next_upstream и uwsgi_next_upstream.
+       Спасибо Piotr Sikora.
+
+    *) Исправление: в обработке ошибок выделения памяти.
+
+    *) Исправление: при использовании директив sendfile и timer_resolution
+       на Linux запросы могли зависать.
+
+    *) Исправление: при использовании с подзапросами директив sendfile и
+       aio_write запросы могли зависать.
+
+    *) Исправление: в модуле ngx_http_v2_module.
+       Спасибо Piotr Sikora.
+
+    *) Исправление: при использовании HTTP/2 в рабочем процессе мог
+       произойти segmentation fault.
+
+    *) Исправление: запросы могли зависать при использовании с подзапросами
+       директив limit_rate, sendfile_max_chunk, limit_req или метода
+       $r->sleep() встроенного перла.
+
+    *) Исправление: в модуле ngx_http_slice_module.
+
+
 Изменения в nginx 1.11.12                                         24.03.2017
 
     *) Исправление: nginx мог нагружать процессор; ошибка появилась в
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nginx-1.11.12/src/core/nginx.h 
new/nginx-1.12.0/src/core/nginx.h
--- old/nginx-1.11.12/src/core/nginx.h  2017-03-24 16:05:07.000000000 +0100
+++ new/nginx-1.12.0/src/core/nginx.h   2017-04-12 16:46:01.000000000 +0200
@@ -9,8 +9,8 @@
 #define _NGINX_H_INCLUDED_
 
 
-#define nginx_version      1011012
-#define NGINX_VERSION      "1.11.12"
+#define nginx_version      1012000
+#define NGINX_VERSION      "1.12.0"
 #define NGINX_VER          "nginx/" NGINX_VERSION
 
 #ifdef NGX_BUILD
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nginx-1.11.12/src/core/ngx_cycle.c 
new/nginx-1.12.0/src/core/ngx_cycle.c
--- old/nginx-1.11.12/src/core/ngx_cycle.c      2017-03-24 16:05:07.000000000 
+0100
+++ new/nginx-1.12.0/src/core/ngx_cycle.c       2017-04-12 16:46:01.000000000 
+0200
@@ -115,16 +115,14 @@
 
     n = old_cycle->paths.nelts ? old_cycle->paths.nelts : 10;
 
-    cycle->paths.elts = ngx_pcalloc(pool, n * sizeof(ngx_path_t *));
-    if (cycle->paths.elts == NULL) {
+    if (ngx_array_init(&cycle->paths, pool, n, sizeof(ngx_path_t *))
+        != NGX_OK)
+    {
         ngx_destroy_pool(pool);
         return NULL;
     }
 
-    cycle->paths.nelts = 0;
-    cycle->paths.size = sizeof(ngx_path_t *);
-    cycle->paths.nalloc = n;
-    cycle->paths.pool = pool;
+    ngx_memzero(cycle->paths.elts, n * sizeof(ngx_path_t *));
 
 
     if (ngx_array_init(&cycle->config_dump, pool, 1, sizeof(ngx_conf_dump_t))
@@ -175,16 +173,14 @@
 
     n = old_cycle->listening.nelts ? old_cycle->listening.nelts : 10;
 
-    cycle->listening.elts = ngx_pcalloc(pool, n * sizeof(ngx_listening_t));
-    if (cycle->listening.elts == NULL) {
+    if (ngx_array_init(&cycle->listening, pool, n, sizeof(ngx_listening_t))
+        != NGX_OK)
+    {
         ngx_destroy_pool(pool);
         return NULL;
     }
 
-    cycle->listening.nelts = 0;
-    cycle->listening.size = sizeof(ngx_listening_t);
-    cycle->listening.nalloc = n;
-    cycle->listening.pool = pool;
+    ngx_memzero(cycle->listening.elts, n * sizeof(ngx_listening_t));
 
 
     ngx_queue_init(&cycle->reusable_connections_queue);
@@ -768,15 +764,15 @@
         }
 
         n = 10;
-        ngx_old_cycles.elts = ngx_pcalloc(ngx_temp_pool,
-                                          n * sizeof(ngx_cycle_t *));
-        if (ngx_old_cycles.elts == NULL) {
+
+        if (ngx_array_init(&ngx_old_cycles, ngx_temp_pool, n,
+                           sizeof(ngx_cycle_t *))
+            != NGX_OK)
+        {
             exit(1);
         }
-        ngx_old_cycles.nelts = 0;
-        ngx_old_cycles.size = sizeof(ngx_cycle_t *);
-        ngx_old_cycles.nalloc = n;
-        ngx_old_cycles.pool = ngx_temp_pool;
+
+        ngx_memzero(ngx_old_cycles.elts, n * sizeof(ngx_cycle_t *));
 
         ngx_cleaner_event.handler = ngx_clean_old_cycles;
         ngx_cleaner_event.log = cycle->log;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nginx-1.11.12/src/event/ngx_event.c 
new/nginx-1.12.0/src/event/ngx_event.c
--- old/nginx-1.11.12/src/event/ngx_event.c     2017-03-24 16:05:07.000000000 
+0100
+++ new/nginx-1.12.0/src/event/ngx_event.c      2017-04-12 16:46:01.000000000 
+0200
@@ -500,8 +500,7 @@
 #endif
 
     shm.size = size;
-    shm.name.len = sizeof("nginx_shared_zone") - 1;
-    shm.name.data = (u_char *) "nginx_shared_zone";
+    ngx_str_set(&shm.name, "nginx_shared_zone");
     shm.log = cycle->log;
 
     if (ngx_shm_alloc(&shm) != NGX_OK) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/nginx-1.11.12/src/http/modules/ngx_http_fastcgi_module.c 
new/nginx-1.12.0/src/http/modules/ngx_http_fastcgi_module.c
--- old/nginx-1.11.12/src/http/modules/ngx_http_fastcgi_module.c        
2017-03-24 16:05:07.000000000 +0100
+++ new/nginx-1.12.0/src/http/modules/ngx_http_fastcgi_module.c 2017-04-12 
16:46:02.000000000 +0200
@@ -211,6 +211,7 @@
     { ngx_string("http_503"), NGX_HTTP_UPSTREAM_FT_HTTP_503 },
     { ngx_string("http_403"), NGX_HTTP_UPSTREAM_FT_HTTP_403 },
     { ngx_string("http_404"), NGX_HTTP_UPSTREAM_FT_HTTP_404 },
+    { ngx_string("http_429"), NGX_HTTP_UPSTREAM_FT_HTTP_429 },
     { ngx_string("updating"), NGX_HTTP_UPSTREAM_FT_UPDATING },
     { ngx_string("off"), NGX_HTTP_UPSTREAM_FT_OFF },
     { ngx_null_string, 0 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/nginx-1.11.12/src/http/modules/ngx_http_index_module.c 
new/nginx-1.12.0/src/http/modules/ngx_http_index_module.c
--- old/nginx-1.11.12/src/http/modules/ngx_http_index_module.c  2017-03-24 
16:05:07.000000000 +0100
+++ new/nginx-1.12.0/src/http/modules/ngx_http_index_module.c   2017-04-12 
16:46:02.000000000 +0200
@@ -217,13 +217,13 @@
         if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool)
             != NGX_OK)
         {
-            ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, of.err,
-                           "%s \"%s\" failed", of.failed, path.data);
-
             if (of.err == 0) {
                 return NGX_HTTP_INTERNAL_SERVER_ERROR;
             }
 
+            ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, of.err,
+                           "%s \"%s\" failed", of.failed, path.data);
+
 #if (NGX_HAVE_OPENAT)
             if (of.err == NGX_EMLINK
                 || of.err == NGX_ELOOP)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/nginx-1.11.12/src/http/modules/ngx_http_limit_req_module.c 
new/nginx-1.12.0/src/http/modules/ngx_http_limit_req_module.c
--- old/nginx-1.11.12/src/http/modules/ngx_http_limit_req_module.c      
2017-03-24 16:05:07.000000000 +0100
+++ new/nginx-1.12.0/src/http/modules/ngx_http_limit_req_module.c       
2017-04-12 16:46:02.000000000 +0200
@@ -276,6 +276,8 @@
 
     r->read_event_handler = ngx_http_test_reading;
     r->write_event_handler = ngx_http_limit_req_delay;
+
+    r->connection->write->delayed = 1;
     ngx_add_timer(r->connection->write, delay);
 
     return NGX_AGAIN;
@@ -292,7 +294,7 @@
 
     wev = r->connection->write;
 
-    if (!wev->timedout) {
+    if (wev->delayed) {
 
         if (ngx_handle_write_event(wev, 0) != NGX_OK) {
             ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
@@ -301,8 +303,6 @@
         return;
     }
 
-    wev->timedout = 0;
-
     if (ngx_handle_read_event(r->connection->read, 0) != NGX_OK) {
         ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
         return;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nginx-1.11.12/src/http/modules/ngx_http_log_module.c 
new/nginx-1.12.0/src/http/modules/ngx_http_log_module.c
--- old/nginx-1.11.12/src/http/modules/ngx_http_log_module.c    2017-03-24 
16:05:07.000000000 +0100
+++ new/nginx-1.12.0/src/http/modules/ngx_http_log_module.c     2017-04-12 
16:46:02.000000000 +0200
@@ -552,6 +552,11 @@
     if (ngx_open_cached_file(llcf->open_file_cache, &log, &of, r->pool)
         != NGX_OK)
     {
+        if (of.err == 0) {
+            /* simulate successful logging */
+            return len;
+        }
+
         ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno,
                       "%s \"%s\" failed", of.failed, log.data);
         /* simulate successful logging */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/nginx-1.11.12/src/http/modules/ngx_http_proxy_module.c 
new/nginx-1.12.0/src/http/modules/ngx_http_proxy_module.c
--- old/nginx-1.11.12/src/http/modules/ngx_http_proxy_module.c  2017-03-24 
16:05:07.000000000 +0100
+++ new/nginx-1.12.0/src/http/modules/ngx_http_proxy_module.c   2017-04-12 
16:46:02.000000000 +0200
@@ -220,6 +220,7 @@
     { ngx_string("http_504"), NGX_HTTP_UPSTREAM_FT_HTTP_504 },
     { ngx_string("http_403"), NGX_HTTP_UPSTREAM_FT_HTTP_403 },
     { ngx_string("http_404"), NGX_HTTP_UPSTREAM_FT_HTTP_404 },
+    { ngx_string("http_429"), NGX_HTTP_UPSTREAM_FT_HTTP_429 },
     { ngx_string("updating"), NGX_HTTP_UPSTREAM_FT_UPDATING },
     { ngx_string("off"), NGX_HTTP_UPSTREAM_FT_OFF },
     { ngx_null_string, 0 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/nginx-1.11.12/src/http/modules/ngx_http_scgi_module.c 
new/nginx-1.12.0/src/http/modules/ngx_http_scgi_module.c
--- old/nginx-1.11.12/src/http/modules/ngx_http_scgi_module.c   2017-03-24 
16:05:07.000000000 +0100
+++ new/nginx-1.12.0/src/http/modules/ngx_http_scgi_module.c    2017-04-12 
16:46:02.000000000 +0200
@@ -82,6 +82,7 @@
     { ngx_string("http_503"), NGX_HTTP_UPSTREAM_FT_HTTP_503 },
     { ngx_string("http_403"), NGX_HTTP_UPSTREAM_FT_HTTP_403 },
     { ngx_string("http_404"), NGX_HTTP_UPSTREAM_FT_HTTP_404 },
+    { ngx_string("http_429"), NGX_HTTP_UPSTREAM_FT_HTTP_429 },
     { ngx_string("updating"), NGX_HTTP_UPSTREAM_FT_UPDATING },
     { ngx_string("off"), NGX_HTTP_UPSTREAM_FT_OFF },
     { ngx_null_string, 0 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/nginx-1.11.12/src/http/modules/ngx_http_slice_filter_module.c 
new/nginx-1.12.0/src/http/modules/ngx_http_slice_filter_module.c
--- old/nginx-1.11.12/src/http/modules/ngx_http_slice_filter_module.c   
2017-03-24 16:05:07.000000000 +0100
+++ new/nginx-1.12.0/src/http/modules/ngx_http_slice_filter_module.c    
2017-04-12 16:46:02.000000000 +0200
@@ -11,23 +11,25 @@
 
 
 typedef struct {
-    size_t      size;
+    size_t               size;
 } ngx_http_slice_loc_conf_t;
 
 
 typedef struct {
-    off_t       start;
-    off_t       end;
-    ngx_str_t   range;
-    ngx_str_t   etag;
-    ngx_uint_t  last;  /* unsigned  last:1; */
+    off_t                start;
+    off_t                end;
+    ngx_str_t            range;
+    ngx_str_t            etag;
+    unsigned             last:1;
+    unsigned             active:1;
+    ngx_http_request_t  *sr;
 } ngx_http_slice_ctx_t;
 
 
 typedef struct {
-    off_t       start;
-    off_t       end;
-    off_t       complete_length;
+    off_t                start;
+    off_t                end;
+    off_t                complete_length;
 } ngx_http_slice_content_range_t;
 
 
@@ -169,6 +171,7 @@
     }
 
     ctx->start = end;
+    ctx->active = 1;
 
     r->headers_out.status = NGX_HTTP_OK;
     r->headers_out.status_line.len = 0;
@@ -209,7 +212,6 @@
 {
     ngx_int_t                   rc;
     ngx_chain_t                *cl;
-    ngx_http_request_t         *sr;
     ngx_http_slice_ctx_t       *ctx;
     ngx_http_slice_loc_conf_t  *slcf;
 
@@ -234,6 +236,16 @@
         return rc;
     }
 
+    if (ctx->sr && !ctx->sr->done) {
+        return rc;
+    }
+
+    if (!ctx->active) {
+        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
+                      "missing slice response");
+        return NGX_ERROR;
+    }
+
     if (ctx->start >= ctx->end) {
         ngx_http_set_ctx(r, NULL, ngx_http_slice_filter_module);
         ngx_http_send_special(r, NGX_HTTP_LAST);
@@ -244,14 +256,14 @@
         return rc;
     }
 
-    if (ngx_http_subrequest(r, &r->uri, &r->args, &sr, NULL,
+    if (ngx_http_subrequest(r, &r->uri, &r->args, &ctx->sr, NULL,
                             NGX_HTTP_SUBREQUEST_CLONE)
         != NGX_OK)
     {
         return NGX_ERROR;
     }
 
-    ngx_http_set_ctx(sr, ctx, ngx_http_slice_filter_module);
+    ngx_http_set_ctx(ctx->sr, ctx, ngx_http_slice_filter_module);
 
     slcf = ngx_http_get_module_loc_conf(r, ngx_http_slice_filter_module);
 
@@ -259,6 +271,8 @@
                                  ctx->start + (off_t) slcf->size - 1)
                      - ctx->range.data;
 
+    ctx->active = 0;
+
     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
                    "http slice subrequest: \"%V\"", &ctx->range);
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/nginx-1.11.12/src/http/modules/ngx_http_uwsgi_module.c 
new/nginx-1.12.0/src/http/modules/ngx_http_uwsgi_module.c
--- old/nginx-1.11.12/src/http/modules/ngx_http_uwsgi_module.c  2017-03-24 
16:05:08.000000000 +0100
+++ new/nginx-1.12.0/src/http/modules/ngx_http_uwsgi_module.c   2017-04-12 
16:46:02.000000000 +0200
@@ -114,6 +114,7 @@
     { ngx_string("http_503"), NGX_HTTP_UPSTREAM_FT_HTTP_503 },
     { ngx_string("http_403"), NGX_HTTP_UPSTREAM_FT_HTTP_403 },
     { ngx_string("http_404"), NGX_HTTP_UPSTREAM_FT_HTTP_404 },
+    { ngx_string("http_429"), NGX_HTTP_UPSTREAM_FT_HTTP_429 },
     { ngx_string("updating"), NGX_HTTP_UPSTREAM_FT_UPDATING },
     { ngx_string("off"), NGX_HTTP_UPSTREAM_FT_OFF },
     { ngx_null_string, 0 }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nginx-1.11.12/src/http/modules/perl/nginx.xs 
new/nginx-1.12.0/src/http/modules/perl/nginx.xs
--- old/nginx-1.11.12/src/http/modules/perl/nginx.xs    2017-03-24 
16:05:08.000000000 +0100
+++ new/nginx-1.12.0/src/http/modules/perl/nginx.xs     2017-04-12 
16:46:02.000000000 +0200
@@ -1001,6 +1001,7 @@
 
     ctx->next = SvRV(ST(2));
 
+    r->connection->write->delayed = 1;
     ngx_add_timer(r->connection->write, sleep);
 
     r->write_event_handler = ngx_http_perl_sleep_handler;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/nginx-1.11.12/src/http/modules/perl/ngx_http_perl_module.c 
new/nginx-1.12.0/src/http/modules/perl/ngx_http_perl_module.c
--- old/nginx-1.11.12/src/http/modules/perl/ngx_http_perl_module.c      
2017-03-24 16:05:08.000000000 +0100
+++ new/nginx-1.12.0/src/http/modules/perl/ngx_http_perl_module.c       
2017-04-12 16:46:02.000000000 +0200
@@ -278,15 +278,16 @@
 
     wev = r->connection->write;
 
-    if (wev->timedout) {
-        wev->timedout = 0;
-        ngx_http_perl_handle_request(r);
+    if (wev->delayed) {
+
+        if (ngx_handle_write_event(wev, 0) != NGX_OK) {
+            ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+        }
+
         return;
     }
 
-    if (ngx_handle_write_event(wev, 0) != NGX_OK) {
-        ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
-    }
+    ngx_http_perl_handle_request(r);
 }
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nginx-1.11.12/src/http/ngx_http_copy_filter_module.c 
new/nginx-1.12.0/src/http/ngx_http_copy_filter_module.c
--- old/nginx-1.11.12/src/http/ngx_http_copy_filter_module.c    2017-03-24 
16:05:08.000000000 +0100
+++ new/nginx-1.12.0/src/http/ngx_http_copy_filter_module.c     2017-04-12 
16:46:02.000000000 +0200
@@ -187,15 +187,24 @@
 ngx_http_copy_aio_event_handler(ngx_event_t *ev)
 {
     ngx_event_aio_t     *aio;
+    ngx_connection_t    *c;
     ngx_http_request_t  *r;
 
     aio = ev->data;
     r = aio->data;
+    c = r->connection;
+
+    ngx_http_set_log_request(c->log, r);
+
+    ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
+                   "http aio: \"%V?%V\"", &r->uri, &r->args);
 
     r->main->blocked--;
     r->aio = 0;
 
-    r->connection->write->handler(r->connection->write);
+    r->write_event_handler(r);
+
+    ngx_http_run_posted_requests(c);
 }
 
 
@@ -300,14 +309,33 @@
 static void
 ngx_http_copy_thread_event_handler(ngx_event_t *ev)
 {
+    ngx_connection_t    *c;
     ngx_http_request_t  *r;
 
     r = ev->data;
+    c = r->connection;
+
+    ngx_http_set_log_request(c->log, r);
+
+    ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
+                   "http thread: \"%V?%V\"", &r->uri, &r->args);
 
     r->main->blocked--;
     r->aio = 0;
 
-    r->connection->write->handler(r->connection->write);
+    if (r->done) {
+        /*
+         * trigger connection event handler if the subrequest was
+         * already finalized; this can happen if the handler is used
+         * for sendfile() in threads
+         */
+
+        c->write->handler(c->write);
+
+    } else {
+        r->write_event_handler(r);
+        ngx_http_run_posted_requests(c);
+    }
 }
 
 #endif
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nginx-1.11.12/src/http/ngx_http_core_module.c 
new/nginx-1.12.0/src/http/ngx_http_core_module.c
--- old/nginx-1.11.12/src/http/ngx_http_core_module.c   2017-03-24 
16:05:08.000000000 +0100
+++ new/nginx-1.12.0/src/http/ngx_http_core_module.c    2017-04-12 
16:46:02.000000000 +0200
@@ -1314,6 +1314,11 @@
         if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool)
             != NGX_OK)
         {
+            if (of.err == 0) {
+                ngx_http_finalize_request(r, NGX_HTTP_INTERNAL_SERVER_ERROR);
+                return NGX_OK;
+            }
+
             if (of.err != NGX_ENOENT
                 && of.err != NGX_ENOTDIR
                 && of.err != NGX_ENAMETOOLONG)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/nginx-1.11.12/src/http/ngx_http_header_filter_module.c 
new/nginx-1.12.0/src/http/ngx_http_header_filter_module.c
--- old/nginx-1.11.12/src/http/ngx_http_header_filter_module.c  2017-03-24 
16:05:08.000000000 +0100
+++ new/nginx-1.12.0/src/http/ngx_http_header_filter_module.c   2017-04-12 
16:46:02.000000000 +0200
@@ -101,12 +101,16 @@
     ngx_null_string,  /* "419 unused" */
     ngx_null_string,  /* "420 unused" */
     ngx_string("421 Misdirected Request"),
+    ngx_null_string,  /* "422 Unprocessable Entity" */
+    ngx_null_string,  /* "423 Locked" */
+    ngx_null_string,  /* "424 Failed Dependency" */
+    ngx_null_string,  /* "425 unused" */
+    ngx_null_string,  /* "426 Upgrade Required" */
+    ngx_null_string,  /* "427 unused" */
+    ngx_null_string,  /* "428 Precondition Required" */
+    ngx_string("429 Too Many Requests"),
 
-    /* ngx_null_string, */  /* "422 Unprocessable Entity" */
-    /* ngx_null_string, */  /* "423 Locked" */
-    /* ngx_null_string, */  /* "424 Failed Dependency" */
-
-#define NGX_HTTP_LAST_4XX  422
+#define NGX_HTTP_LAST_4XX  430
 #define NGX_HTTP_OFF_5XX   (NGX_HTTP_LAST_4XX - 400 + NGX_HTTP_OFF_4XX)
 
     ngx_string("500 Internal Server Error"),
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nginx-1.11.12/src/http/ngx_http_request.c 
new/nginx-1.12.0/src/http/ngx_http_request.c
--- old/nginx-1.11.12/src/http/ngx_http_request.c       2017-03-24 
16:05:08.000000000 +0100
+++ new/nginx-1.12.0/src/http/ngx_http_request.c        2017-04-12 
16:46:02.000000000 +0200
@@ -2198,6 +2198,11 @@
     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
                    "http run request: \"%V?%V\"", &r->uri, &r->args);
 
+    if (ev->delayed && ev->timedout) {
+        ev->delayed = 0;
+        ev->timedout = 0;
+    }
+
     if (ev->write) {
         r->write_event_handler(r);
 
@@ -2607,7 +2612,7 @@
 static void
 ngx_http_writer(ngx_http_request_t *r)
 {
-    int                        rc;
+    ngx_int_t                  rc;
     ngx_event_t               *wev;
     ngx_connection_t          *c;
     ngx_http_core_loc_conf_t  *clcf;
@@ -2621,34 +2626,22 @@
     clcf = ngx_http_get_module_loc_conf(r->main, ngx_http_core_module);
 
     if (wev->timedout) {
-        if (!wev->delayed) {
-            ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT,
-                          "client timed out");
-            c->timedout = 1;
-
-            ngx_http_finalize_request(r, NGX_HTTP_REQUEST_TIME_OUT);
-            return;
-        }
-
-        wev->timedout = 0;
-        wev->delayed = 0;
-
-        if (!wev->ready) {
-            ngx_add_timer(wev, clcf->send_timeout);
-
-            if (ngx_handle_write_event(wev, clcf->send_lowat) != NGX_OK) {
-                ngx_http_close_request(r, 0);
-            }
-
-            return;
-        }
+        ngx_log_error(NGX_LOG_INFO, c->log, NGX_ETIMEDOUT,
+                      "client timed out");
+        c->timedout = 1;
 
+        ngx_http_finalize_request(r, NGX_HTTP_REQUEST_TIME_OUT);
+        return;
     }
 
     if (wev->delayed || r->aio) {
         ngx_log_debug0(NGX_LOG_DEBUG_HTTP, wev->log, 0,
                        "http writer delayed");
 
+        if (!wev->delayed) {
+            ngx_add_timer(wev, clcf->send_timeout);
+        }
+
         if (ngx_handle_write_event(wev, clcf->send_lowat) != NGX_OK) {
             ngx_http_close_request(r, 0);
         }
@@ -2659,7 +2652,7 @@
     rc = ngx_http_output_filter(r, NULL);
 
     ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0,
-                   "http writer output filter: %d, \"%V?%V\"",
+                   "http writer output filter: %i, \"%V?%V\"",
                    rc, &r->uri, &r->args);
 
     if (rc == NGX_ERROR) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nginx-1.11.12/src/http/ngx_http_request.h 
new/nginx-1.12.0/src/http/ngx_http_request.h
--- old/nginx-1.11.12/src/http/ngx_http_request.h       2017-03-24 
16:05:08.000000000 +0100
+++ new/nginx-1.12.0/src/http/ngx_http_request.h        2017-04-12 
16:46:02.000000000 +0200
@@ -98,6 +98,7 @@
 #define NGX_HTTP_UNSUPPORTED_MEDIA_TYPE    415
 #define NGX_HTTP_RANGE_NOT_SATISFIABLE     416
 #define NGX_HTTP_MISDIRECTED_REQUEST       421
+#define NGX_HTTP_TOO_MANY_REQUESTS         429
 
 
 /* Our own HTTP codes */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nginx-1.11.12/src/http/ngx_http_script.c 
new/nginx-1.12.0/src/http/ngx_http_script.c
--- old/nginx-1.11.12/src/http/ngx_http_script.c        2017-03-24 
16:05:08.000000000 +0100
+++ new/nginx-1.12.0/src/http/ngx_http_script.c 2017-04-12 16:46:02.000000000 
+0200
@@ -1513,6 +1513,12 @@
     if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool)
         != NGX_OK)
     {
+        if (of.err == 0) {
+            e->ip = ngx_http_script_exit;
+            e->status = NGX_HTTP_INTERNAL_SERVER_ERROR;
+            return;
+        }
+
         if (of.err != NGX_ENOENT
             && of.err != NGX_ENOTDIR
             && of.err != NGX_ENAMETOOLONG)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nginx-1.11.12/src/http/ngx_http_special_response.c 
new/nginx-1.12.0/src/http/ngx_http_special_response.c
--- old/nginx-1.11.12/src/http/ngx_http_special_response.c      2017-03-24 
16:05:08.000000000 +0100
+++ new/nginx-1.12.0/src/http/ngx_http_special_response.c       2017-04-12 
16:46:02.000000000 +0200
@@ -225,6 +225,14 @@
 ;
 
 
+static char ngx_http_error_429_page[] =
+"<html>" CRLF
+"<head><title>429 Too Many Requests</title></head>" CRLF
+"<body bgcolor=\"white\">" CRLF
+"<center><h1>429 Too Many Requests</h1></center>" CRLF
+;
+
+
 static char ngx_http_error_494_page[] =
 "<html>" CRLF
 "<head><title>400 Request Header Or Cookie Too Large</title></head>"
@@ -354,8 +362,16 @@
     ngx_null_string,                     /* 419 */
     ngx_null_string,                     /* 420 */
     ngx_string(ngx_http_error_421_page),
+    ngx_null_string,                     /* 422 */
+    ngx_null_string,                     /* 423 */
+    ngx_null_string,                     /* 424 */
+    ngx_null_string,                     /* 425 */
+    ngx_null_string,                     /* 426 */
+    ngx_null_string,                     /* 427 */
+    ngx_null_string,                     /* 428 */
+    ngx_string(ngx_http_error_429_page),
 
-#define NGX_HTTP_LAST_4XX  422
+#define NGX_HTTP_LAST_4XX  430
 #define NGX_HTTP_OFF_5XX   (NGX_HTTP_LAST_4XX - 400 + NGX_HTTP_OFF_4XX)
 
     ngx_string(ngx_http_error_494_page), /* 494, request header too large */
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nginx-1.11.12/src/http/ngx_http_upstream.c 
new/nginx-1.12.0/src/http/ngx_http_upstream.c
--- old/nginx-1.11.12/src/http/ngx_http_upstream.c      2017-03-24 
16:05:08.000000000 +0100
+++ new/nginx-1.12.0/src/http/ngx_http_upstream.c       2017-04-12 
16:46:02.000000000 +0200
@@ -436,6 +436,7 @@
     { 504, NGX_HTTP_UPSTREAM_FT_HTTP_504 },
     { 403, NGX_HTTP_UPSTREAM_FT_HTTP_403 },
     { 404, NGX_HTTP_UPSTREAM_FT_HTTP_404 },
+    { 429, NGX_HTTP_UPSTREAM_FT_HTTP_429 },
     { 0, 0 }
 };
 
@@ -1232,6 +1233,11 @@
     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
                    "http upstream request: \"%V?%V\"", &r->uri, &r->args);
 
+    if (ev->delayed && ev->timedout) {
+        ev->delayed = 0;
+        ev->timedout = 0;
+    }
+
     if (ev->write) {
         u->write_event_handler(r, u);
 
@@ -3736,9 +3742,19 @@
     r->main->blocked--;
     r->aio = 0;
 
-    r->write_event_handler(r);
+    if (r->done) {
+        /*
+         * trigger connection event handler if the subrequest was
+         * already finalized; this can happen if the handler is used
+         * for sendfile() in threads
+         */
+
+        c->write->handler(c->write);
 
-    ngx_http_run_posted_requests(c);
+    } else {
+        r->write_event_handler(r);
+        ngx_http_run_posted_requests(c);
+    }
 }
 
 #endif
@@ -3786,31 +3802,9 @@
 
     if (wev->timedout) {
 
-        if (wev->delayed) {
-
-            wev->timedout = 0;
-            wev->delayed = 0;
-
-            if (!wev->ready) {
-                ngx_add_timer(wev, p->send_timeout);
-
-                if (ngx_handle_write_event(wev, p->send_lowat) != NGX_OK) {
-                    ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
-                }
-
-                return;
-            }
-
-            if (ngx_event_pipe(p, wev->write) == NGX_ABORT) {
-                ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
-                return;
-            }
-
-        } else {
-            p->downstream_error = 1;
-            c->timedout = 1;
-            ngx_connection_error(c, NGX_ETIMEDOUT, "client timed out");
-        }
+        p->downstream_error = 1;
+        c->timedout = 1;
+        ngx_connection_error(c, NGX_ETIMEDOUT, "client timed out");
 
     } else {
 
@@ -3855,30 +3849,8 @@
 
     if (rev->timedout) {
 
-        if (rev->delayed) {
-
-            rev->timedout = 0;
-            rev->delayed = 0;
-
-            if (!rev->ready) {
-                ngx_add_timer(rev, p->read_timeout);
-
-                if (ngx_handle_read_event(rev, 0) != NGX_OK) {
-                    ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
-                }
-
-                return;
-            }
-
-            if (ngx_event_pipe(p, 0) == NGX_ABORT) {
-                ngx_http_upstream_finalize_request(r, u, NGX_ERROR);
-                return;
-            }
-
-        } else {
-            p->upstream_error = 1;
-            ngx_connection_error(c, NGX_ETIMEDOUT, "upstream timed out");
-        }
+        p->upstream_error = 1;
+        ngx_connection_error(c, NGX_ETIMEDOUT, "upstream timed out");
 
     } else {
 
@@ -4155,6 +4127,10 @@
         status = NGX_HTTP_NOT_FOUND;
         break;
 
+    case NGX_HTTP_UPSTREAM_FT_HTTP_429:
+        status = NGX_HTTP_TOO_MANY_REQUESTS;
+        break;
+
     /*
      * NGX_HTTP_UPSTREAM_FT_BUSY_LOCK and NGX_HTTP_UPSTREAM_FT_MAX_WAITING
      * never reach here
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nginx-1.11.12/src/http/ngx_http_upstream.h 
new/nginx-1.12.0/src/http/ngx_http_upstream.h
--- old/nginx-1.11.12/src/http/ngx_http_upstream.h      2017-03-24 
16:05:08.000000000 +0100
+++ new/nginx-1.12.0/src/http/ngx_http_upstream.h       2017-04-12 
16:46:02.000000000 +0200
@@ -26,10 +26,11 @@
 #define NGX_HTTP_UPSTREAM_FT_HTTP_504        0x00000080
 #define NGX_HTTP_UPSTREAM_FT_HTTP_403        0x00000100
 #define NGX_HTTP_UPSTREAM_FT_HTTP_404        0x00000200
-#define NGX_HTTP_UPSTREAM_FT_UPDATING        0x00000400
-#define NGX_HTTP_UPSTREAM_FT_BUSY_LOCK       0x00000800
-#define NGX_HTTP_UPSTREAM_FT_MAX_WAITING     0x00001000
-#define NGX_HTTP_UPSTREAM_FT_NON_IDEMPOTENT  0x00002000
+#define NGX_HTTP_UPSTREAM_FT_HTTP_429        0x00000400
+#define NGX_HTTP_UPSTREAM_FT_UPDATING        0x00000800
+#define NGX_HTTP_UPSTREAM_FT_BUSY_LOCK       0x00001000
+#define NGX_HTTP_UPSTREAM_FT_MAX_WAITING     0x00002000
+#define NGX_HTTP_UPSTREAM_FT_NON_IDEMPOTENT  0x00004000
 #define NGX_HTTP_UPSTREAM_FT_NOLIVE          0x40000000
 #define NGX_HTTP_UPSTREAM_FT_OFF             0x80000000
 
@@ -38,7 +39,8 @@
                                              |NGX_HTTP_UPSTREAM_FT_HTTP_503  \
                                              |NGX_HTTP_UPSTREAM_FT_HTTP_504  \
                                              |NGX_HTTP_UPSTREAM_FT_HTTP_403  \
-                                             |NGX_HTTP_UPSTREAM_FT_HTTP_404)
+                                             |NGX_HTTP_UPSTREAM_FT_HTTP_404  \
+                                             |NGX_HTTP_UPSTREAM_FT_HTTP_429)
 
 #define NGX_HTTP_UPSTREAM_INVALID_HEADER     40
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nginx-1.11.12/src/http/v2/ngx_http_v2.c 
new/nginx-1.12.0/src/http/v2/ngx_http_v2.c
--- old/nginx-1.11.12/src/http/v2/ngx_http_v2.c 2017-03-24 16:05:08.000000000 
+0100
+++ new/nginx-1.12.0/src/http/v2/ngx_http_v2.c  2017-04-12 16:46:02.000000000 
+0200
@@ -783,9 +783,12 @@
 static u_char *
 ngx_http_v2_state_data(ngx_http_v2_connection_t *h2c, u_char *pos, u_char *end)
 {
+    size_t                 size;
     ngx_http_v2_node_t    *node;
     ngx_http_v2_stream_t  *stream;
 
+    size = h2c->state.length;
+
     if (h2c->state.flags & NGX_HTTP_V2_PADDED_FLAG) {
 
         if (h2c->state.length == 0) {
@@ -802,33 +805,33 @@
         }
 
         h2c->state.padding = *pos++;
-        h2c->state.length--;
 
-        if (h2c->state.padding > h2c->state.length) {
+        if (h2c->state.padding >= size) {
             ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
                           "client sent padded DATA frame "
                           "with incorrect length: %uz, padding: %uz",
-                          h2c->state.length, h2c->state.padding);
+                          size, h2c->state.padding);
 
-            return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_SIZE_ERROR);
+            return ngx_http_v2_connection_error(h2c,
+                                                NGX_HTTP_V2_PROTOCOL_ERROR);
         }
 
-        h2c->state.length -= h2c->state.padding;
+        h2c->state.length -= 1 + h2c->state.padding;
     }
 
     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
                    "http2 DATA frame");
 
-    if (h2c->state.length > h2c->recv_window) {
+    if (size > h2c->recv_window) {
         ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
                       "client violated connection flow control: "
                       "received DATA frame length %uz, available window %uz",
-                      h2c->state.length, h2c->recv_window);
+                      size, h2c->recv_window);
 
         return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_FLOW_CTRL_ERROR);
     }
 
-    h2c->recv_window -= h2c->state.length;
+    h2c->recv_window -= size;
 
     if (h2c->recv_window < NGX_HTTP_V2_MAX_WINDOW / 4) {
 
@@ -854,11 +857,11 @@
 
     stream = node->stream;
 
-    if (h2c->state.length > stream->recv_window) {
+    if (size > stream->recv_window) {
         ngx_log_error(NGX_LOG_INFO, h2c->connection->log, 0,
                       "client violated flow control for stream %ui: "
                       "received DATA frame length %uz, available window %uz",
-                      node->id, h2c->state.length, stream->recv_window);
+                      node->id, size, stream->recv_window);
 
         if (ngx_http_v2_terminate_stream(h2c, stream,
                                          NGX_HTTP_V2_FLOW_CTRL_ERROR)
@@ -871,7 +874,7 @@
         return ngx_http_v2_state_skip_padded(h2c, pos, end);
     }
 
-    stream->recv_window -= h2c->state.length;
+    stream->recv_window -= size;
 
     if (stream->no_flow_control
         && stream->recv_window < NGX_HTTP_V2_MAX_WINDOW / 4)
@@ -938,7 +941,7 @@
 
     if (size >= h2c->state.length) {
         size = h2c->state.length;
-        stream->in_closed  = h2c->state.flags & NGX_HTTP_V2_END_STREAM_FLAG;
+        stream->in_closed = h2c->state.flags & NGX_HTTP_V2_END_STREAM_FLAG;
     }
 
     r = stream->request;
@@ -1053,7 +1056,8 @@
                           "with incorrect length: %uz, padding: %uz",
                           h2c->state.length, h2c->state.padding);
 
-            return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_SIZE_ERROR);
+            return ngx_http_v2_connection_error(h2c,
+                                                NGX_HTTP_V2_PROTOCOL_ERROR);
         }
 
         h2c->state.length -= h2c->state.padding;
@@ -1901,7 +1905,7 @@
 
     if (node == NULL || node->stream == NULL) {
         ngx_log_debug0(NGX_LOG_DEBUG_HTTP, h2c->connection->log, 0,
-                        "unknown http2 stream");
+                       "unknown http2 stream");
 
         return ngx_http_v2_state_complete(h2c, pos, end);
     }
@@ -2015,6 +2019,7 @@
             break;
 
         case NGX_HTTP_V2_MAX_FRAME_SIZE_SETTING:
+
             if (value > NGX_HTTP_V2_MAX_FRAME_SIZE
                 || value < NGX_HTTP_V2_DEFAULT_FRAME_SIZE)
             {
@@ -3072,7 +3077,7 @@
     }
 
     ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
-                  "client sent unknown pseudo header \"%V\"",
+                  "client sent unknown pseudo-header \":%V\"",
                   &header->name);
 
     return NGX_DECLINED;
@@ -3219,14 +3224,14 @@
 {
     if (r->schema_start) {
         ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
-                      "client sent duplicate :schema header");
+                      "client sent duplicate :scheme header");
 
         return NGX_DECLINED;
     }
 
     if (header->value.len == 0) {
         ngx_log_error(NGX_LOG_INFO, r->connection->log, 0,
-                      "client sent empty :schema header");
+                      "client sent empty :scheme header");
 
         return NGX_DECLINED;
     }
@@ -4130,6 +4135,14 @@
     ngx_log_debug0(NGX_LOG_DEBUG_HTTP, rev->log, 0,
                    "http2 handle connection handler");
 
+    c = rev->data;
+    h2c = c->data;
+
+    if (c->error) {
+        ngx_http_v2_finalize_connection(h2c, 0);
+        return;
+    }
+
     rev->handler = ngx_http_v2_read_handler;
 
     if (rev->ready) {
@@ -4137,9 +4150,6 @@
         return;
     }
 
-    c = rev->data;
-    h2c = c->data;
-
     if (h2c->last_out && ngx_http_v2_send_output_queue(h2c) == NGX_ERROR) {
         ngx_http_v2_finalize_connection(h2c, 0);
         return;
@@ -4262,7 +4272,10 @@
 
             if (stream->queued) {
                 stream->queued = 0;
+
                 ev = fc->write;
+                ev->active = 0;
+                ev->ready = 1;
 
             } else {
                 ev = fc->read;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nginx-1.11.12/src/http/v2/ngx_http_v2.h 
new/nginx-1.12.0/src/http/v2/ngx_http_v2.h
--- old/nginx-1.11.12/src/http/v2/ngx_http_v2.h 2017-03-24 16:05:08.000000000 
+0100
+++ new/nginx-1.12.0/src/http/v2/ngx_http_v2.h  2017-04-12 16:46:02.000000000 
+0200
@@ -249,8 +249,8 @@
 {
     ngx_http_v2_out_frame_t  **out;
 
-    for (out = &h2c->last_out; *out; out = &(*out)->next)
-    {
+    for (out = &h2c->last_out; *out; out = &(*out)->next) {
+
         if ((*out)->blocked || (*out)->stream == NULL) {
             break;
         }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' 
old/nginx-1.11.12/src/http/v2/ngx_http_v2_filter_module.c 
new/nginx-1.12.0/src/http/v2/ngx_http_v2_filter_module.c
--- old/nginx-1.11.12/src/http/v2/ngx_http_v2_filter_module.c   2017-03-24 
16:05:08.000000000 +0100
+++ new/nginx-1.12.0/src/http/v2/ngx_http_v2_filter_module.c    2017-04-12 
16:46:02.000000000 +0200
@@ -769,6 +769,8 @@
         rest -= frame_size;
 
         if (rest) {
+            frame->length += NGX_HTTP_V2_FRAME_HEADER_SIZE;
+
             type = NGX_HTTP_V2_CONTINUATION_FRAME;
             flags = NGX_HTTP_V2_NO_FLAG;
             continue;
@@ -1209,6 +1211,9 @@
                    "http2:%ui HEADERS frame %p was sent",
                    stream->node->id, frame);
 
+    stream->request->header_size += NGX_HTTP_V2_FRAME_HEADER_SIZE
+                                    + frame->length;
+
     ngx_http_v2_handle_frame(stream, frame);
 
     ngx_http_v2_handle_stream(h2c, stream);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nginx-1.11.12/src/os/unix/ngx_linux_sendfile_chain.c 
new/nginx-1.12.0/src/os/unix/ngx_linux_sendfile_chain.c
--- old/nginx-1.11.12/src/os/unix/ngx_linux_sendfile_chain.c    2017-03-24 
16:05:08.000000000 +0100
+++ new/nginx-1.12.0/src/os/unix/ngx_linux_sendfile_chain.c     2017-04-12 
16:46:02.000000000 +0200
@@ -20,8 +20,8 @@
 #error sendfile64() is required!
 #endif
 
-static ngx_int_t ngx_linux_sendfile_thread(ngx_connection_t *c, ngx_buf_t 
*file,
-    size_t size, size_t *sent);
+static ssize_t ngx_linux_sendfile_thread(ngx_connection_t *c, ngx_buf_t *file,
+    size_t size);
 static void ngx_linux_sendfile_thread_handler(void *data, ngx_log_t *log);
 #endif
 
@@ -56,10 +56,6 @@
     ngx_chain_t   *cl;
     ngx_iovec_t    header;
     struct iovec   headers[NGX_IOVS_PREALLOCATE];
-#if (NGX_THREADS)
-    ngx_int_t      rc;
-    ngx_uint_t     thread_handled, thread_complete;
-#endif
 
     wev = c->write;
 
@@ -82,10 +78,6 @@
 
     for ( ;; ) {
         prev_send = send;
-#if (NGX_THREADS)
-        thread_handled = 0;
-        thread_complete = 0;
-#endif
 
         /* create the iovec and coalesce the neighbouring bufs */
 
@@ -179,38 +171,19 @@
             }
 #endif
 
-#if (NGX_THREADS)
-            if (file->file->thread_handler) {
-                rc = ngx_linux_sendfile_thread(c, file, file_size, &sent);
-
-                switch (rc) {
-                case NGX_OK:
-                    thread_handled = 1;
-                    break;
-
-                case NGX_DONE:
-                    thread_complete = 1;
-                    break;
+            n = ngx_linux_sendfile(c, file, file_size);
 
-                case NGX_AGAIN:
-                    break;
-
-                default: /* NGX_ERROR */
-                    return NGX_CHAIN_ERROR;
-                }
-
-            } else
-#endif
-            {
-                n = ngx_linux_sendfile(c, file, file_size);
-
-                if (n == NGX_ERROR) {
-                    return NGX_CHAIN_ERROR;
-                }
+            if (n == NGX_ERROR) {
+                return NGX_CHAIN_ERROR;
+            }
 
-                sent = (n == NGX_AGAIN) ? 0 : n;
+            if (n == NGX_DONE) {
+                /* thread task posted */
+                return in;
             }
 
+            sent = (n == NGX_AGAIN) ? 0 : n;
+
         } else {
             n = ngx_writev(c, &header);
 
@@ -225,21 +198,27 @@
 
         in = ngx_chain_update_sent(in, sent);
 
-        if ((size_t) (send - prev_send) != sent) {
-#if (NGX_THREADS)
-            if (thread_handled) {
-                return in;
-            }
-
-            if (thread_complete) {
-                send = prev_send + sent;
-                continue;
-            }
-#endif
+        if (n == NGX_AGAIN) {
             wev->ready = 0;
             return in;
         }
 
+        if ((size_t) (send - prev_send) != sent) {
+
+            /*
+             * sendfile() on Linux 4.3+ might be interrupted at any time,
+             * and provides no indication if it was interrupted or not,
+             * so we have to retry till an explicit EAGAIN
+             *
+             * sendfile() in threads can also report less bytes written
+             * than we are prepared to send now, since it was started in
+             * some point in the past, so we again have to retry
+             */
+
+            send = prev_send + sent;
+            continue;
+        }
+
         if (send >= limit || in == NULL) {
             return in;
         }
@@ -258,6 +237,14 @@
     ssize_t    n;
     ngx_err_t  err;
 
+#if (NGX_THREADS)
+
+    if (file->file->thread_handler) {
+        return ngx_linux_sendfile_thread(c, file, size);
+    }
+
+#endif
+
 #if (NGX_HAVE_SENDFILE64)
     offset = file->file_pos;
 #else
@@ -324,9 +311,8 @@
 } ngx_linux_sendfile_ctx_t;
 
 
-static ngx_int_t
-ngx_linux_sendfile_thread(ngx_connection_t *c, ngx_buf_t *file, size_t size,
-    size_t *sent)
+static ssize_t
+ngx_linux_sendfile_thread(ngx_connection_t *c, ngx_buf_t *file, size_t size)
 {
     ngx_event_t               *wev;
     ngx_thread_task_t         *task;
@@ -356,10 +342,14 @@
         task->event.complete = 0;
 
         if (ctx->err == NGX_EAGAIN) {
-            *sent = 0;
+            /*
+             * if wev->complete is set, this means that a write event
+             * happened while we were waiting for the thread task, so
+             * we have to retry sending even on EAGAIN
+             */
 
             if (wev->complete) {
-                return NGX_DONE;
+                return 0;
             }
 
             return NGX_AGAIN;
@@ -384,13 +374,7 @@
             return NGX_ERROR;
         }
 
-        *sent = ctx->sent;
-
-        if (ctx->sent == ctx->size || wev->complete) {
-            return NGX_DONE;
-        }
-
-        return NGX_AGAIN;
+        return ctx->sent;
     }
 
     if (task->event.active && ctx->file == file) {
@@ -399,9 +383,7 @@
          * or multiple calls of the next body filter from a filter
          */
 
-        *sent = 0;
-
-        return NGX_OK;
+        return NGX_DONE;
     }
 
     ctx->file = file;
@@ -414,9 +396,7 @@
         return NGX_ERROR;
     }
 
-    *sent = 0;
-
-    return NGX_OK;
+    return NGX_DONE;
 }
 
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/nginx-1.11.12/src/stream/ngx_stream_log_module.c 
new/nginx-1.12.0/src/stream/ngx_stream_log_module.c
--- old/nginx-1.11.12/src/stream/ngx_stream_log_module.c        2017-03-24 
16:05:08.000000000 +0100
+++ new/nginx-1.12.0/src/stream/ngx_stream_log_module.c 2017-04-12 
16:46:02.000000000 +0200
@@ -443,6 +443,11 @@
                              s->connection->pool)
         != NGX_OK)
     {
+        if (of.err == 0) {
+            /* simulate successful logging */
+            return len;
+        }
+
         ngx_log_error(NGX_LOG_CRIT, s->connection->log, ngx_errno,
                       "%s \"%s\" failed", of.failed, log.data);
         /* simulate successful logging */


Reply via email to