diff options
author | Loïc Hoguin <[email protected]> | 2025-02-04 12:12:49 +0100 |
---|---|---|
committer | Loïc Hoguin <[email protected]> | 2025-02-05 14:30:25 +0100 |
commit | 073c481656915f5c9c61f6ecea15a1754469a1f7 (patch) | |
tree | eccf087969a5f6c20c9c9a2c07cd85edfac818d3 /src | |
parent | d889291c4f2823d4af738743af4598f1ac947617 (diff) | |
download | cowboy-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.erl | 13 |
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. |