1.9.14 - http2 protocol violations

Валентин Бартенев vbart at nginx.com
Wed Apr 13 12:30:39 UTC 2016


On Wednesday 13 April 2016 13:54:24 Otto van der Schaaf wrote:
> Sure.
> 
> - This sample contains to or three requests, the last request is where rate
> limiting kicks in and the protocol error happens (the earlier requests are
> problem-free):
>  https://gist.github.com/oschaaf/281b7a0fed9954dd960adac55e96f2cd
> 
> - This is from a post to a non-existant url:
> https://gist.github.com/oschaaf/6396a614ce599d5003e50bb8e7106bed
> 
[..]

Are you sure that you saw this problem while were collecting the logs? 
There's nothing suspicious in them, and no errors are reported by nginx
and by the client.

The only problem that I could see should be fixed by the patch below.
Please try it and let me know if it will help.

  wbr, Valentin V. Bartenev


# HG changeset patch
# User Valentin Bartenev <vbart at nginx.com>
# Date 1460529455 -10800
#      Wed Apr 13 09:37:35 2016 +0300
# Node ID 80d0c9e314f62b594e634cd9318fe84afc50bb2c
# Parent  640288d0e1bc449a54ac1c85905e6fce780fac7d
HTTP/2: refuse streams with data until SETTINGS is acknowledged.

A client can start sending data before receiving and acknowledging
the SETTINGS frame, thus having a wrong idea about the stream's
initial window.  This can violate flow control.

diff -r 640288d0e1bc -r 80d0c9e314f6 src/http/v2/ngx_http_v2.c
--- a/src/http/v2/ngx_http_v2.c Tue Apr 12 19:01:56 2016 +0300
+++ b/src/http/v2/ngx_http_v2.c Wed Apr 13 09:37:35 2016 +0300
@@ -1071,6 +1071,19 @@ ngx_http_v2_state_headers(ngx_http_v2_co
         return ngx_http_v2_state_header_block(h2c, pos, end);
     }
 
+    if (!h2c->settings_ack && !(h2c->state.flags & 
NGX_HTTP_V2_END_STREAM_FLAG))
+    {
+        if (ngx_http_v2_send_rst_stream(h2c, h2c->state.sid,
+                                        NGX_HTTP_V2_REFUSED_STREAM)
+            != NGX_OK)
+        {
+            return ngx_http_v2_connection_error(h2c,
+                                                NGX_HTTP_V2_INTERNAL_ERROR);
+        }
+
+        return ngx_http_v2_state_header_block(h2c, pos, end);
+    }
+
     node = ngx_http_v2_get_node_by_id(h2c, h2c->state.sid, 1);
 
     if (node == NULL) {
@@ -1883,7 +1896,7 @@ ngx_http_v2_state_settings(ngx_http_v2_c
             return ngx_http_v2_connection_error(h2c, NGX_HTTP_V2_SIZE_ERROR);
         }
 
-        /* TODO settings acknowledged */
+        h2c->settings_ack = 1;
 
         return ngx_http_v2_state_complete(h2c, pos, end);
     }
diff -r 640288d0e1bc -r 80d0c9e314f6 src/http/v2/ngx_http_v2.h
--- a/src/http/v2/ngx_http_v2.h Tue Apr 12 19:01:56 2016 +0300
+++ b/src/http/v2/ngx_http_v2.h Wed Apr 13 09:37:35 2016 +0300
@@ -141,6 +141,7 @@ struct ngx_http_v2_connection_s {
     ngx_uint_t                       last_sid;
 
     unsigned                         closed_nodes:8;
+    unsigned                         settings_ack:1;
     unsigned                         blocked:1;
 };
 



More information about the nginx-devel mailing list