diff --git a/lib/protocol/http2/connection.rb b/lib/protocol/http2/connection.rb index 8506eda..8e78284 100644 --- a/lib/protocol/http2/connection.rb +++ b/lib/protocol/http2/connection.rb @@ -62,8 +62,9 @@ def maximum_frame_size @remote_settings.maximum_frame_size end + # The maximum number of concurrent streams that this connection can initiate: def maximum_concurrent_streams - @local_settings.maximum_concurrent_streams + @remote_settings.maximum_concurrent_streams end attr :framer @@ -389,7 +390,8 @@ def receive_headers(frame) raise ProtocolError, "Invalid stream id: #{stream_id} <= #{@remote_stream_id}!" end - if @streams.size < self.maximum_concurrent_streams + # We need to validate that we have less streams than the specified maximum: + if @streams.size < @local_settings.maximum_concurrent_streams stream = accept_stream(stream_id) @remote_stream_id = stream_id diff --git a/test/protocol/http2/connection.rb b/test/protocol/http2/connection.rb index fe0fbe8..4de8fd8 100644 --- a/test/protocol/http2/connection.rb +++ b/test/protocol/http2/connection.rb @@ -11,6 +11,29 @@ let(:framer) {Protocol::HTTP2::Framer.new(stream)} let(:connection) {subject.new(framer, 1)} + with "#maximum_concurrent_streams" do + it "is the remote peer's maximum concurrent streams" do + connection.remote_settings.maximum_concurrent_streams = 10 + connection.local_settings.current.maximum_concurrent_streams = 5 + + expect(connection.maximum_concurrent_streams).to be == 10 + end + end + + with '#receive_headers' do + it "fails with protocol error if exceeding the maximum concurrent connections" do + connection.local_settings.current.maximum_concurrent_streams = 1 + # Create a stream to + connection.streams[1] = Protocol::HTTP2::Stream.new(connection, 1) + + frame = Protocol::HTTP2::HeadersFrame.new(3) + + expect do + connection.receive_headers(frame) + end.to raise_exception(Protocol::HTTP2::ProtocolError, message: be =~ /Exceeded maximum concurrent streams/) + end + end + it "reports the connection id 0 is not closed" do expect(connection).not.to be(:closed_stream_id?, 0) end