http2: handle MaxUploadBufferPerConnection of 65535
Fix a fencepost error causing us to ignore a
Server.MaxUploadBufferPerConnection value of 65535 (the minimum).
Change-Id: Ibca0347576c360cfa4fe841c05b23afe165b96e0
Reviewed-on: https://go-review.googlesource.com/c/net/+/434913
Run-TryBot: Damien Neil <dneil@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@google.com>
diff --git a/http2/server.go b/http2/server.go
index a894e69..43cc2a3 100644
--- a/http2/server.go
+++ b/http2/server.go
@@ -143,7 +143,7 @@
}
func (s *Server) initialConnRecvWindowSize() int32 {
- if s.MaxUploadBufferPerConnection > initialWindowSize {
+ if s.MaxUploadBufferPerConnection >= initialWindowSize {
return s.MaxUploadBufferPerConnection
}
return 1 << 20
diff --git a/http2/server_test.go b/http2/server_test.go
index 50ea4b7..808b3d1 100644
--- a/http2/server_test.go
+++ b/http2/server_test.go
@@ -4436,3 +4436,57 @@
}
}
}
+
+func TestServerInitialFlowControlWindow(t *testing.T) {
+ for _, want := range []int32{
+ 65535,
+ 1 << 19,
+ 1 << 21,
+ // For MaxUploadBufferPerConnection values in the range
+ // (65535, 65535*2), we don't send an initial WINDOW_UPDATE
+ // because we only send flow control when the window drops
+ // below half of the maximum. Perhaps it would be nice to
+ // test this case, but we currently do not.
+ 65535 * 2,
+ } {
+ t.Run(fmt.Sprint(want), func(t *testing.T) {
+
+ st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
+ }, func(s *Server) {
+ s.MaxUploadBufferPerConnection = want
+ })
+ defer st.Close()
+ st.writePreface()
+ st.writeInitialSettings()
+ st.writeSettingsAck()
+ st.writeHeaders(HeadersFrameParam{
+ StreamID: 1,
+ BlockFragment: st.encodeHeader(),
+ EndStream: true,
+ EndHeaders: true,
+ })
+ window := 65535
+ Frames:
+ for {
+ f, err := st.readFrame()
+ if err != nil {
+ st.t.Fatal(err)
+ }
+ switch f := f.(type) {
+ case *WindowUpdateFrame:
+ if f.FrameHeader.StreamID != 0 {
+ t.Errorf("WindowUpdate StreamID = %d; want 0", f.FrameHeader.StreamID)
+ return
+ }
+ window += int(f.Increment)
+ case *HeadersFrame:
+ break Frames
+ default:
+ }
+ }
+ if window != int(want) {
+ t.Errorf("got initial flow control window = %v, want %v", window, want)
+ }
+ })
+ }
+}