go x/net/http2:服务器拒绝传输,错误代码为协议流错误,

y3bcpkx1  于 6个月前  发布在  Go
关注(0)|答案(6)|浏览(47)

我们在Go 1.17rc2版本的httputil.ReverseProxy前面运行了一个Go go1.17rc2版本的net/http.Server。我们遇到了奇怪的ErrCodeProtocol流错误,所以我们停止使用捆绑的x/net/http2,并将其切换为显式使用x/net/http2(通过http2.ConfigureTransports和http2.ConfigureServer,因此不会使用捆绑的版本)。
我们的x/net git版本是golang/net@aaa1db6,这是今天的主分支。
我们最初收到的日志不足以告诉我们问题出在哪里:

2021/08/10 14:07:20 http: proxy error: stream error: stream ID 1293155; PROTOCOL_ERROR
2021/08/10 14:07:20 http: proxy error: stream error: stream ID 1293157; PROTOCOL_ERROR

但是在本地修改它,添加一些http2.Server中返回协议错误的路径上的expvar计数器后,我们发现问题出在这里:
https://github.com/golang/net/blob/aaa1db679c0d7765d2b1cb1f92cac8ebf4d94c53/http2/server.go#L1835

// http://tools.ietf.org/html/rfc7540#section-5.1.2
// [...] Endpoints MUST NOT exceed the limit set by their peer. An
// endpoint that receives a HEADERS frame that causes their
// advertised concurrent stream limit to be exceeded MUST treat
// this as a stream error (Section 5.4.2) of type PROTOCOL_ERROR
// or REFUSED_STREAM.
if sc.curClientStreams+1 > sc.advMaxStreams {
        if sc.unackedSettings == 0 {
                // They should know better.
                return streamError(id, ErrCodeProtocol)
        }

因此,Go http2客户端(Transport)和/或服务器在其并发/最大流计算上出现了错误。
可能有趣的是:后端(ReverseProxy的Transport所击中的http2.Server)有非常长的运行时间的http.Handlers(例如:几天或几周长)。这也许可以解释为什么这个bug没有被更多人报告。
我没有看到最近的提交表明这是一个回归。这个服务器是新的,所以我也不能说它以前是否工作过。
cc @neild@bcmills@fraenkel@dmitshur@dsnet@josharian

o4tp2gmn

o4tp2gmn2#

啊,是的。这可能是我们遇到的问题。

ecr0jaav

ecr0jaav4#

https://golang.org/cl/347033提到了这个问题:http2: make Transport not reuse conns after a stream protocol error

nafvub8i

nafvub8i5#

https://golang.org/cl/356978提到了这个问题:[internal-branch.go1.16-vendor] http2: make Transport not reuse conns after a stream protocol error

myss37ts

myss37ts6#

https://golang.org/cl/357673提到了这个问题:[internal-branch.go1.17-vendor] http2: make Transport not reuse conns after a stream protocol error

相关问题