Go's http2.Server doesn't respect the client's flow control.
It accounts for it partly, and enforces the other direction (that the client can't send too much to the server), but does not ever deduct its own credit when sending DATA frames, and doesn't wait for flow control when doing so.
In the process of fixing #16481 I had expected a test like this to hang:
body := strings.Repeat("a", 16<<10)
st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
println(r.RemoteAddr)
// Write out a 16KB body which the client won't ever read.
io.WriteString(w, body)
}, optOnlyServer)
defer st.Close()
tr := &Transport{TLSClientConfig: tlsConfigInsecure}
defer tr.CloseIdleConnections()
// Verify we can do this over 4 times without hanging:
for i := 0; i < 10; i++ {
println(i)
req, _ := http.NewRequest("GET", st.ts.URL, nil)
res, err := tr.RoundTrip(req)
if err != nil {
t.Fatal(err)
}
res.Body.Close()
println(i, "done")
}
But it didn't.
Add a test like that back once the http2.Server respects flow control.
Go's http2.Server doesn't respect the client's flow control.
It accounts for it partly, and enforces the other direction (that the client can't send too much to the server), but does not ever deduct its own credit when sending DATA frames, and doesn't wait for flow control when doing so.
In the process of fixing #16481 I had expected a test like this to hang:
But it didn't.
Add a test like that back once the http2.Server respects flow control.