aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorViktor Söderqvist <[email protected]>2021-10-28 16:02:58 +0200
committerLoïc Hoguin <[email protected]>2025-02-11 17:32:20 +0100
commit133ac59000afde558b2d8f630d865c2f7f39565f (patch)
tree825755de05a537f33d20578eb631b842f0dd904c
parenta277d9160cf792fa74b70108d376e6fb65d42056 (diff)
downloadcowlib-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.erl21
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().