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)
+			}
+		})
+	}
+}