aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLoïc Hoguin <[email protected]>2025-02-04 12:12:49 +0100
committerLoïc Hoguin <[email protected]>2025-02-05 14:30:25 +0100
commit073c481656915f5c9c61f6ecea15a1754469a1f7 (patch)
treeeccf087969a5f6c20c9c9a2c07cd85edfac818d3 /src
parentd889291c4f2823d4af738743af4598f1ac947617 (diff)
downloadcowboy-073c481656915f5c9c61f6ecea15a1754469a1f7.tar.gz
cowboy-073c481656915f5c9c61f6ecea15a1754469a1f7.tar.bz2
cowboy-073c481656915f5c9c61f6ecea15a1754469a1f7.zip
HTTP/1: Ensure active mode is enabled for the next stream
In rare cases it was possible for active mode to be disabled when there were no streams pipelined. This resulted in the dropping of the connection due to timeouts as no data could be received. We now enable active mode when necessary even if there are no streams pipelined. This was found while benchmarking and I have not been able to extract a test case.
Diffstat (limited to 'src')
-rw-r--r--src/cowboy_http.erl13
1 files changed, 7 insertions, 6 deletions
diff --git a/src/cowboy_http.erl b/src/cowboy_http.erl
index de268a6..c1c4b8d 100644
--- a/src/cowboy_http.erl
+++ b/src/cowboy_http.erl
@@ -1392,23 +1392,24 @@ stream_terminate(State0=#state{opts=Opts, in_streamid=InStreamID, in_state=InSta
end.
stream_next(State0=#state{opts=Opts, active=Active, out_streamid=OutStreamID, streams=Streams}) ->
+ %% Enable active mode again if it was disabled.
+ State1 = case Active of
+ true -> State0;
+ false -> active(State0)
+ end,
NextOutStreamID = OutStreamID + 1,
case lists:keyfind(NextOutStreamID, #stream.id, Streams) of
false ->
- State = State0#state{out_streamid=NextOutStreamID, out_state=wait},
+ State = State1#state{out_streamid=NextOutStreamID, out_state=wait},
%% There are no streams remaining. We therefore can
%% and want to switch back to the request_timeout.
set_timeout(State, request_timeout);
#stream{queue=Commands} ->
- State = case Active of
- true -> State0;
- false -> active(State0)
- end,
%% @todo Remove queue from the stream.
%% We set the flow to the initial flow size even though
%% we might have sent some data through already due to pipelining.
Flow = maps:get(initial_stream_flow_size, Opts, 65535),
- commands(State#state{flow=Flow, out_streamid=NextOutStreamID, out_state=wait},
+ commands(State1#state{flow=Flow, out_streamid=NextOutStreamID, out_state=wait},
NextOutStreamID, Commands)
end.