@@ -655,6 +655,16 @@ inline Http2Stream* Http2Session::FindStream(int32_t id) {
655655 return s != streams_.end () ? s->second : nullptr ;
656656}
657657
658+ inline bool Http2Session::CanAddStream () {
659+ uint32_t maxConcurrentStreams =
660+ nghttp2_session_get_local_settings (
661+ session_, NGHTTP2_SETTINGS_MAX_CONCURRENT_STREAMS );
662+ size_t maxSize =
663+ std::min (streams_.max_size (), static_cast <size_t >(maxConcurrentStreams));
664+ // We can add a new stream so long as we are less than the current
665+ // maximum on concurrent streams
666+ return streams_.size () < maxSize;
667+ }
658668
659669inline void Http2Session::AddStream (Http2Stream* stream) {
660670 CHECK_GE (++statistics_.stream_count , 0 );
@@ -765,7 +775,14 @@ inline int Http2Session::OnBeginHeadersCallback(nghttp2_session* handle,
765775
766776 Http2Stream* stream = session->FindStream (id);
767777 if (stream == nullptr ) {
768- new Http2Stream (session, id, frame->headers .cat );
778+ if (session->CanAddStream ()) {
779+ new Http2Stream (session, id, frame->headers .cat );
780+ } else {
781+ // Too many concurrent streams being opened
782+ nghttp2_submit_rst_stream (**session, NGHTTP2_FLAG_NONE , id,
783+ NGHTTP2_ENHANCE_YOUR_CALM );
784+ return NGHTTP2_ERR_TEMPORAL_CALLBACK_FAILURE ;
785+ }
769786 } else {
770787 // If the stream has already been destroyed, ignore.
771788 if (stream->IsDestroyed ())
0 commit comments