http2: don't crash when writing RST_STREAM on idle or closed streams

https://go-review.googlesource.com/33238 fixed scheduling of RST_STREAMs so
they are added to the appropriate stream queue. However, RST_STREAM may be
sent before OpenStream or after CloseStream in certain error cases, such as:

https://github.com/golang/net/blob/00ed5e97ea3a5ac46658b98e50259941947cec04/http2/server.go#L1395
https://github.com/golang/net/blob/00ed5e97ea3a5ac46658b98e50259941947cec04/http2/frame.go#L866
https://github.com/golang/net/blob/00ed5e97ea3a5ac46658b98e50259941947cec04/http2/frame.go#L947

In these cases, the failing stream has no queue and in priorityWriteScheduler.Push
will panic. A simple fix is to add RST_STREAMs to the root queue when the stream
queue doesn't exist. This is correct because:

- RST_STREAM is tiny and doesn't use flow control bytes, so prioritization is
  not important.

- The server should not send any frames on a stream after sending RST_STREAM,
  but even if that happens, the RST_STREAM will be ordered before those other
  frames because the control queue has the highest priority.

Fixes golang/go#17919

Change-Id: I2e8101f015822ef975303a1fe87634b36afbdc6b
Reviewed-on: https://go-review.googlesource.com/33248
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
3 files changed