aboutsummaryrefslogtreecommitdiffstats
path: root/test/rfc7540_SUITE.erl
diff options
context:
space:
mode:
authorLoïc Hoguin <[email protected]>2019-09-02 14:48:28 +0200
committerLoïc Hoguin <[email protected]>2019-09-05 14:07:38 +0200
commit48f417ac8f3d00039e2dc674e312d982336dcfea (patch)
tree232092a3fcbe0364a92c10f074faccdaf389c6da /test/rfc7540_SUITE.erl
parentaedf6379cc769ce2be1e040de3fe631e6539f442 (diff)
downloadcowboy-48f417ac8f3d00039e2dc674e312d982336dcfea.tar.gz
cowboy-48f417ac8f3d00039e2dc674e312d982336dcfea.tar.bz2
cowboy-48f417ac8f3d00039e2dc674e312d982336dcfea.zip
Fix and optimize sending of WINDOW_UPDATE frames
For long-running connections it was possible for the connection window to become larger than allowed by the protocol because the window increases claimed by stream handlers were never reclaimed even if no data was consumed. The new code applies heuristics to fix this and reduce the number of WINDOW_UPDATE frames that are sent. It includes six new options to control that behavior: margin, max and threshold for both the connection and stream windows. The margin is some extra space added on top of the requested read size. The max is the maximum window size at any given time. The threshold is a minimum window size that must be reached before we even consider sending more WINDOW_UPDATE frames. We also avoid sending WINDOW_UPDATE frames when there is already enough space in the window, or when the read size is 0. Cowlib is set to master until a new tag is done.
Diffstat (limited to 'test/rfc7540_SUITE.erl')
-rw-r--r--test/rfc7540_SUITE.erl50
1 files changed, 0 insertions, 50 deletions
diff --git a/test/rfc7540_SUITE.erl b/test/rfc7540_SUITE.erl
index fe0c4ef..4f27dfa 100644
--- a/test/rfc7540_SUITE.erl
+++ b/test/rfc7540_SUITE.erl
@@ -3117,56 +3117,6 @@ data_reject_overflow_stream(Config0) ->
cowboy:stop_listener(?FUNCTION_NAME)
end.
-lingering_data_counts_toward_connection_window(Config0) ->
- doc("DATA frames received after sending RST_STREAM must be counted "
- "toward the connection flow-control window. (RFC7540 5.1)"),
- Config = cowboy_test:init_http(?FUNCTION_NAME, #{
- env => #{dispatch => cowboy_router:compile(init_routes(Config0))},
- initial_connection_window_size => 100000
- }, Config0),
- try
- %% We need to do the handshake manually because a WINDOW_UPDATE
- %% frame will be sent to update the connection window.
- {ok, Socket} = gen_tcp:connect("localhost", config(port, Config), [binary, {active, false}]),
- %% Send a valid preface.
- ok = gen_tcp:send(Socket, ["PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n", cow_http2:settings(#{})]),
- %% Receive the server preface.
- {ok, << Len1:24 >>} = gen_tcp:recv(Socket, 3, 1000),
- {ok, << 4:8, 0:40, _:Len1/binary >>} = gen_tcp:recv(Socket, 6 + Len1, 1000),
- %% Send the SETTINGS ack.
- ok = gen_tcp:send(Socket, cow_http2:settings_ack()),
- %% Receive the WINDOW_UPDATE for the connection.
- {ok, << 4:24, 8:8, 0:40, _:32 >>} = gen_tcp:recv(Socket, 13, 1000),
- %% Receive the SETTINGS ack.
- {ok, << 0:24, 4:8, 1:8, 0:32 >>} = gen_tcp:recv(Socket, 9, 1000),
- Headers = [
- {<<":method">>, <<"POST">>},
- {<<":scheme">>, <<"http">>},
- {<<":authority">>, <<"localhost">>}, %% @todo Correct port number.
- {<<":path">>, <<"/loop_handler_abort">>}
- ],
- {HeadersBlock, _} = cow_hpack:encode(Headers),
- ok = gen_tcp:send(Socket, [
- cow_http2:headers(1, nofin, HeadersBlock),
- cow_http2:data(1, nofin, <<0:1000/unit:8>>)
- ]),
- % Make sure server send RST_STREAM.
- timer:sleep(100),
- ok = gen_tcp:send(Socket, [
- cow_http2:data(1, nofin, <<0:0/unit:8>>),
- cow_http2:data(1, fin, <<0:1000/unit:8>>)
- ]),
- {ok, << SkipLen:24, 1:8, _:8, 1:32 >>} = gen_tcp:recv(Socket, 9, 1000),
- % Skip the header.
- {ok, _} = gen_tcp:recv(Socket, SkipLen, 1000),
- % Skip RST_STREAM.
- {ok, << 4:24, 3:8, 1:40, _:32 >>} = gen_tcp:recv(Socket, 13, 1000),
- % Received a WINDOW_UPDATE frame after we got RST_STREAM.
- {ok, << 4:24, 8:8, 0:40, 1000:32 >>} = gen_tcp:recv(Socket, 13, 1000)
- after
- cowboy:stop_listener(?FUNCTION_NAME)
- end.
-
%% (RFC7540 6.9.1)
% Frames with zero length with the END_STREAM flag set (that
% is, an empty DATA frame) MAY be sent if there is no available space