Subject: Connection fatal HTTP/2 stream errors

From: Greg Wilkins <[email-masked]>
Date: Wed, 18 Jun 2014 11:32:16 +0200

We are currently working on improving Jetty's handing of stream errors and
I'm wondering what other server implementations are doing about stream
errors.

The issue is that there are many errors that can be detected during hpack
decoding, or soon after that could be handled with a RST_STREAM.  However
because of either the difficult and/or expense of needing to continue with
decoding the headers (to keep the hpack table state correct), we are
currently leaning towards treating all stream errors as fatal to the
connection.

Such errors that I have identified include are:

   - headers too large
   - upper case in header name
   - non US-ASCII character in header name or value
   - unknown scheme
   - non token bad method (spaces etc)
   - badly formatted authority and/or bad port number
   - bad path (eg non hex % encoded or bad character encoded)
   - bad status

Note that some of these checks could be done after hpack decoding, however
if we are storing fields in the Hpack table, we try to store the decoded
version of them rather than just the string.

We are looking setting an error state and continuing decoding, but in the
case of too large that is a bit counter productive.  So currently we are
thinking that any of these kinds of errors are going to result in a GO_AWAY
message as it is just too difficult to handle such errors deep inside hpack
decoding and continue.

But the down side of this is that you can easily send poison pills that
will kill a connection, which is pain if you are aggregating
connections.

Anyway, just wondering what other server implementations are trying to do.
If others are going to make efforts to keep connections open and just
ignore the bad streams, then I guess we will follow peer pressure and do
the same.

cheers

-- 
Greg Wilkins <[email-masked]>
http://eclipse.org/jetty HTTP, SPDY, Websocket server and client that scales
http://www.webtide.com  advice and support for jetty and cometd.

---

From: Tatsuhiro Tsujikawa <[email-masked]>
Date: Wed, 18 Jun 2014 18:55:33 +0900

Hi,

> ​​In nghttp2, we don't make them error except for headers too large case.
This can be easily accomplished just to store byte string to header table,
which is perfectly compliant to HPACK specification.
For large headers, the only limitation in nghttp2 is we limit the one
header name and value  ​must be less than 8KiB buffers.  The 8KiB is just a
magic and we are planning to add API to tweak its size.  If this limit
breaches, we treat it as connection error.  We may be able to do better
though.  Other than that, total number of header pairs are unlimited in
nghttp2 since we just buffer one header name/value pair only and we pass it
to application layer one by one.  The application layer can send back 413
(if it is server) or RST_STREAM if it thinks total number of headers or
size are too much to handle.

​Best regards,
Tatsuhiro Tsujikawa​

> ​

---

From: Martin Thomson <[email-masked]>
Date: Wed, 18 Jun 2014 12:12:59 -0700

On 18 June 2014 02:32, Greg Wilkins <[email-masked]> wrote:
> we are currently leaning towards treating all stream errors as fatal to the
> connection.

This fits with our current error handling philosophy.

The general sense here has been that failing hard is preferred at this
stage.  Postel's principle leads to the sorts of sloppiness that
HTTP/1.1 suffers from in excess, and the more we can do to expose
errors now, the less we will have to deal with corner cases later.

All of the errors you cite can, and probably should, be fatal to the
extent that is reasonable.  Obviously, you can't catch everything, and
things like bad paths might simply be forwarded on from HTTP/1.1,
where that sort of crap appears all the time.

On the other hand, if you are operating a server, you are free to be
more strict.  Don't abuse it, but you can enforce a fairly arbitrary
dress code.