HTTP/2: emit new frames only after applying all SETTINGS params.

Previously, new frames could be emitted in the middle of applying
new (and already acknowledged) SETTINGS params, which is illegal.

Change-Id: I5e8fabe2fbe2d8a98c65de8f77e3507e0f18413c
Signed-off-by: Piotr Sikora <piotrsikora@google.com>
Reviewed-on: https://nginx-review.googlesource.com/2940
Reviewed-by: Lizan Zhou <zlizan@google.com>
diff --git a/src/http/v2/ngx_http_v2.c b/src/http/v2/ngx_http_v2.c
index e1b864e..d5f187b 100644
--- a/src/http/v2/ngx_http_v2.c
+++ b/src/http/v2/ngx_http_v2.c
@@ -2012,7 +2012,9 @@
 ngx_http_v2_state_settings_params(ngx_http_v2_connection_t *h2c, u_char *pos,
     u_char *end)
 {
-    ngx_uint_t  id, value;
+    ngx_uint_t  id, value, adjustment;
+
+    adjustment = 0;
 
     while (h2c->state.length) {
         if (end - pos < NGX_HTTP_V2_SETTINGS_PARAM_SIZE) {
@@ -2072,13 +2074,7 @@
                            "http2 SETTINGS frame INITIAL_WINDOW_SIZE:%ui",
                            value);
 
-            if (ngx_http_v2_adjust_windows(h2c, value - h2c->init_window)
-                != NGX_OK)
-            {
-                return ngx_http_v2_connection_error(h2c,
-                                                    NGX_HTTP_V2_INTERNAL_ERROR);
-            }
-
+            adjustment = value - h2c->init_window;
             h2c->init_window = value;
             break;
 
@@ -2120,6 +2116,13 @@
         pos += NGX_HTTP_V2_SETTINGS_PARAM_SIZE;
     }
 
+    if (adjustment) {
+        if (ngx_http_v2_adjust_windows(h2c, adjustment) != NGX_OK) {
+            return ngx_http_v2_connection_error(h2c,
+                                                NGX_HTTP_V2_INTERNAL_ERROR);
+        }
+    }
+
     return ngx_http_v2_state_complete(h2c, pos, end);
 }