1.9.14 - http2 protocol violations

Валентин Бартенев vbart at nginx.com
Wed Apr 13 17:36:44 UTC 2016


On Wednesday 13 April 2016 19:35:25 Валентин Бартенев wrote:
> On Wednesday 13 April 2016 18:00:26 Валентин Бартенев wrote:
> > On Wednesday 13 April 2016 15:08:29 Otto van der Schaaf wrote:
> > > I'm sorry to say that the patch does not make a difference.
> > > 
> > > I collected Chrome's http/2 trace for a post to a non-existant url:
> > > https://gist.github.com/oschaaf/da273f96fad5e22890981fcd4a1a4376
> > > 
> > > I'm wondering about that last HTTP2_SESSION_RST_STREAM entry.. it looks
> > > like
> > > the httpv2 mod wants to cancel the incoming post data stream at an odd
> > > point in time?
> > > But I'm no expert, so I'm not sure at all.
> > > 
> > [..]
> > 
> > I was able to capture quite the same Chrome trace with the actual bytes 
> > sent/received and this last RST_STREAM entry with status 6 (which is 
> > FRAME_SIZE_ERROR) looks really strange.
> > 
> > 
> > It isn't presented in nginx debug log (nginx hasn't sent, nor has received 
> > it).  Moreover, the actual bytes sent/received trace, that you can get from 
> > Chrome if you set the "Include the actual bytes sent/received." flag in 
> > chrome://net-internals/#capture), doesn't contain it either.
> > 
> > The trace (and nginx log) contains RST_STREAM sent by nginx with status 0 
> > (NO_ERROR), which is correct:
> > 
> > t= 94141 [st= 6088]        SSL_SOCKET_BYTES_RECEIVED
> >                            --> byte_count = 13
> >                            --> hex_encoded_bytes =
> >                              00 00 04 03 00 00 00 00  03 00 00 00 00      
> > 
> > As you can see it has 4 bytes length, type 3, flags 0, stream id 3
> > and error code 0.
> > 
> >     +-----------------------------------------------+
> >     |                 Length (24)                   |
> >     +---------------+---------------+---------------+
> >     |   Type (8)    |   Flags (8)   |
> >     +-+-------------+---------------+-------------------------------+
> >     |R|                 Stream Identifier (31)                      |
> >     +=+=============================================================+
> >     |                   Frame Payload (0...)                      ...
> >     +---------------------------------------------------------------+
> > 
> >                           Figure 1: Frame Layout
> > 
> > 
> > https://tools.ietf.org/html/rfc7540#section-4.1
> > 
> > 
> >     +---------------------------------------------------------------+
> >     |                        Error Code (32)                        |
> >     +---------------------------------------------------------------+
> > 
> >                     Figure 9: RST_STREAM Frame Payload
> > 
> > https://tools.ietf.org/html/rfc7540#section-6.4
> > 
> > I've attached the full trace.  
> > 
> > Maybe I missed something, but after manual decoding bytes I don't see any 
> > problems with the frame sizes received from nginx.
> > 
> > However, that can be a result of this change:
> > http://hg.nginx.org/nginx/rev/92464ebace8e
> > 
> > Firefox perfectly fine with it.  It looks like the problem in Chrome.
> > 
> 
> Well, I've found the key how to interpret these statuses in Chromium sources:
> 
> // Status codes for RST_STREAM frames.
> enum SpdyRstStreamStatus {
>   RST_STREAM_INVALID = 0,
>   RST_STREAM_PROTOCOL_ERROR = 1,
>   RST_STREAM_INVALID_STREAM = 2,
>   RST_STREAM_STREAM_CLOSED = 2,  // Equivalent to INVALID_STREAM
>   RST_STREAM_REFUSED_STREAM = 3,
>   RST_STREAM_UNSUPPORTED_VERSION = 4,
>   RST_STREAM_CANCEL = 5,
>   RST_STREAM_INTERNAL_ERROR = 6,
>   RST_STREAM_FLOW_CONTROL_ERROR = 7,
>   RST_STREAM_STREAM_IN_USE = 8,
>   RST_STREAM_STREAM_ALREADY_CLOSED = 9,
>   RST_STREAM_INVALID_CREDENTIALS = 10,
>   // FRAME_TOO_LARGE (defined by SPDY versions 3.1 and below), and
>   // FRAME_SIZE_ERROR (defined by HTTP/2) are mapped to the same internal
>   // reset status.
>   RST_STREAM_FRAME_TOO_LARGE = 11,
>   RST_STREAM_FRAME_SIZE_ERROR = 11,
>   RST_STREAM_SETTINGS_TIMEOUT = 12,
>   RST_STREAM_CONNECT_ERROR = 13,
>   RST_STREAM_ENHANCE_YOUR_CALM = 14,
>   RST_STREAM_NUM_STATUS_CODES = 15
> };
> 
> looks like NO_ERROR is handled as internal error, which is obviously wrong.
> 

I've opened a ticket for this:
https://bugs.chromium.org/p/chromium/issues/detail?id=603182

  wbr, Valentin V. Bartenev



More information about the nginx-devel mailing list