# HG changeset patch
# User Roman Arutyunyan <arut@nginx.com>
# Date 1442578460 -10800
#      Fri Sep 18 15:14:20 2015 +0300
# Node ID de3b5bc41b8623e6f3fd9f670e5a92fc1a84701e
# Parent  257b51c37c5a76559d50c2a44011a7d3f45bd4b9
Prevented posted requests from running recursively (ticket #788).

When ngx_http_run_posted_requests() is called from a resolve handler after
a cached result is found, it runs the next posted request.  That request,
in turn, can follow the same code path and make the next recursive call of
ngx_http_run_posted_requests().  If a big number of requests was posted,
this can finally lead to stack overflow and nginx crash.

diff -r 257b51c37c5a -r de3b5bc41b86 src/http/ngx_http_request.c
--- a/src/http/ngx_http_request.c	Fri Sep 11 20:13:06 2015 +0300
+++ b/src/http/ngx_http_request.c	Fri Sep 18 15:14:20 2015 +0300
@@ -2195,29 +2195,42 @@ ngx_http_run_posted_requests(ngx_connect
     ngx_http_request_t         *r;
     ngx_http_posted_request_t  *pr;
 
+    if (c->destroyed) {
+        return;
+    }
+
+    r = c->data;
+
+    if (r->main->running_posted) {
+        return;
+    }
+
+    r->main->running_posted = 1;
+
     for ( ;; ) {
 
+        r = c->data;
+        pr = r->main->posted_requests;
+
+        if (pr == NULL) {
+            r->main->running_posted = 0;
+            return;
+        }
+
+        r->main->posted_requests = pr->next;
+
+        r = pr->request;
+
+        ngx_http_set_log_request(c->log, r);
+
+        ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
+                       "http posted request: \"%V?%V\"", &r->uri, &r->args);
+
+        r->write_event_handler(r);
+
         if (c->destroyed) {
             return;
         }
-
-        r = c->data;
-        pr = r->main->posted_requests;
-
-        if (pr == NULL) {
-            return;
-        }
-
-        r->main->posted_requests = pr->next;
-
-        r = pr->request;
-
-        ngx_http_set_log_request(c->log, r);
-
-        ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
-                       "http posted request: \"%V?%V\"", &r->uri, &r->args);
-
-        r->write_event_handler(r);
     }
 }
 
diff -r 257b51c37c5a -r de3b5bc41b86 src/http/ngx_http_request.h
--- a/src/http/ngx_http_request.h	Fri Sep 11 20:13:06 2015 +0300
+++ b/src/http/ngx_http_request.h	Fri Sep 18 15:14:20 2015 +0300
@@ -523,6 +523,7 @@ struct ngx_http_request_s {
     unsigned                          root_tested:1;
     unsigned                          done:1;
     unsigned                          logged:1;
+    unsigned                          running_posted:1;
 
     unsigned                          buffered:4;
 
