http2: fix off-by-one error in client check for max concurrent streams

Fixes golang/go#48358.

Change-Id: Ib4eb93702b32ae7d03cad17ca0b997d5e6a58ad7
Reviewed-on: https://go-review.googlesource.com/c/net/+/349490
Trust: Damien Neil <dneil@google.com>
Run-TryBot: Damien Neil <dneil@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org>
diff --git a/http2/transport.go b/http2/transport.go
index 7c2c013..74c76da 100644
--- a/http2/transport.go
+++ b/http2/transport.go
@@ -800,7 +800,7 @@
 		// writing it.
 		maxConcurrentOkay = true
 	} else {
-		maxConcurrentOkay = int64(len(cc.streams)+1) < int64(cc.maxConcurrentStreams)
+		maxConcurrentOkay = int64(len(cc.streams)+1) <= int64(cc.maxConcurrentStreams)
 	}
 
 	st.canTakeNewRequest = cc.goAway == nil && !cc.closed && !cc.closing && maxConcurrentOkay &&
@@ -1207,7 +1207,7 @@
 			return errClientConnUnusable
 		}
 		cc.lastIdle = time.Time{}
-		if int64(len(cc.streams))+1 <= int64(cc.maxConcurrentStreams) {
+		if int64(len(cc.streams)) < int64(cc.maxConcurrentStreams) {
 			if waitingForConn != nil {
 				close(waitingForConn)
 			}
diff --git a/http2/transport_test.go b/http2/transport_test.go
index efc2695..97735fe 100644
--- a/http2/transport_test.go
+++ b/http2/transport_test.go
@@ -3824,6 +3824,51 @@
 	ct.run()
 }
 
+func TestTransportRequestsLowServerLimit(t *testing.T) {
+	st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
+	}, optOnlyServer, func(s *Server) {
+		s.MaxConcurrentStreams = 1
+	})
+	defer st.Close()
+
+	var (
+		connCountMu sync.Mutex
+		connCount   int
+	)
+	tr := &Transport{
+		TLSClientConfig: tlsConfigInsecure,
+		DialTLS: func(network, addr string, cfg *tls.Config) (net.Conn, error) {
+			connCountMu.Lock()
+			defer connCountMu.Unlock()
+			connCount++
+			return tls.Dial(network, addr, cfg)
+		},
+	}
+	defer tr.CloseIdleConnections()
+
+	const reqCount = 3
+	for i := 0; i < reqCount; i++ {
+		req, err := http.NewRequest("GET", st.ts.URL, nil)
+		if err != nil {
+			t.Fatal(err)
+		}
+		res, err := tr.RoundTrip(req)
+		if err != nil {
+			t.Fatal(err)
+		}
+		if got, want := res.StatusCode, 200; got != want {
+			t.Errorf("StatusCode = %v; want %v", got, want)
+		}
+		if res != nil && res.Body != nil {
+			res.Body.Close()
+		}
+	}
+
+	if connCount != 1 {
+		t.Errorf("created %v connections for %v requests, want 1", connCount, reqCount)
+	}
+}
+
 // tests Transport.StrictMaxConcurrentStreams
 func TestTransportRequestsStallAtServerLimit(t *testing.T) {
 	const maxConcurrent = 2