diff options
author | Viktor Söderqvist <[email protected]> | 2021-10-28 16:02:58 +0200 |
---|---|---|
committer | Loïc Hoguin <[email protected]> | 2025-02-11 17:32:20 +0100 |
commit | 133ac59000afde558b2d8f630d865c2f7f39565f (patch) | |
tree | 825755de05a537f33d20578eb631b842f0dd904c | |
parent | a277d9160cf792fa74b70108d376e6fb65d42056 (diff) | |
download | cowlib-133ac59000afde558b2d8f630d865c2f7f39565f.tar.gz cowlib-133ac59000afde558b2d8f630d865c2f7f39565f.tar.bz2 cowlib-133ac59000afde558b2d8f630d865c2f7f39565f.zip |
Add a function to check remote HTTP/2 setting MAX_CONCURRENT_STREAMS
This is to be used primarily by a client before initiating a new stream
so that it can respect the setting from the server.
-rw-r--r-- | src/cow_http2_machine.erl | 21 |
1 files changed, 21 insertions, 0 deletions
diff --git a/src/cow_http2_machine.erl b/src/cow_http2_machine.erl index b08538b..70b920d 100644 --- a/src/cow_http2_machine.erl +++ b/src/cow_http2_machine.erl @@ -37,6 +37,7 @@ -export([get_stream_local_buffer_size/2]). -export([get_stream_local_state/2]). -export([get_stream_remote_state/2]). +-export([is_remote_concurrency_limit_reached/1]). -export([is_lingering_stream/2]). -type opts() :: #{ @@ -1484,6 +1485,26 @@ get_stream_remote_state(StreamID, State=#http2_machine{mode=Mode, {error, not_found} end. +%% Check if we are allowed to initiate a new stream according to the remote +%% setting MAX_CONCURRENT_STREAMS. + +-spec is_remote_concurrency_limit_reached(http2_machine()) -> boolean(). +is_remote_concurrency_limit_reached(State=#http2_machine{ + remote_settings=RemoteSettings, streams=Streams}) -> + MaxConcurrentStreams = maps:get(max_concurrent_streams, RemoteSettings, infinity), + %% We care about local streams, but first check the total number of + %% streams because it's cheaper. + MaxConcurrentStreams =/= infinity andalso + map_size(Streams) >= MaxConcurrentStreams andalso + count_local_streams(State) >= MaxConcurrentStreams. + +count_local_streams(#http2_machine{mode=Mode, streams=Streams}) -> + maps:fold(fun(StreamId, _Stream, Sum) when ?IS_LOCAL(Mode, StreamId) -> + Sum + 1; + (_, _, Sum) -> + Sum + end, 0, Streams). + %% Query whether the stream was reset recently by the remote endpoint. -spec is_lingering_stream(cow_http2:streamid(), http2_machine()) -> boolean(). |