1.9.14 - http2 protocol violations

Валентин Бартенев vbart at nginx.com
Wed Apr 13 16:35:25 UTC 2016


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.

  wbr, Valentin V. Bartenev



More information about the nginx-devel mailing list