mirror of
https://github.com/ninenines/cowboy.git
synced 2025-07-14 20:30:23 +00:00
Ensure unknown options are ignored in set_options command
This commit is contained in:
parent
1949357f0c
commit
75045637fc
4 changed files with 31 additions and 2 deletions
|
@ -141,7 +141,8 @@ fold([Trailers={trailers, _}|Tail], State0=#state{compress=gzip}, Acc) ->
|
||||||
{{data, fin, Data}, State} = gzip_data({data, fin, <<>>}, State0),
|
{{data, fin, Data}, State} = gzip_data({data, fin, <<>>}, State0),
|
||||||
fold(Tail, State, [Trailers, {data, nofin, Data}|Acc]);
|
fold(Tail, State, [Trailers, {data, nofin, Data}|Acc]);
|
||||||
%% All the options from this handler can be updated for the current stream.
|
%% All the options from this handler can be updated for the current stream.
|
||||||
fold([{set_options, Opts}|Tail], State=#state{
|
%% The set_options command must be propagated as-is regardless.
|
||||||
|
fold([SetOptions={set_options, Opts}|Tail], State=#state{
|
||||||
threshold=CompressThreshold0, deflate_flush=DeflateFlush0}, Acc) ->
|
threshold=CompressThreshold0, deflate_flush=DeflateFlush0}, Acc) ->
|
||||||
CompressThreshold = maps:get(compress_threshold, Opts, CompressThreshold0),
|
CompressThreshold = maps:get(compress_threshold, Opts, CompressThreshold0),
|
||||||
DeflateFlush = case Opts of
|
DeflateFlush = case Opts of
|
||||||
|
@ -150,7 +151,8 @@ fold([{set_options, Opts}|Tail], State=#state{
|
||||||
_ ->
|
_ ->
|
||||||
DeflateFlush0
|
DeflateFlush0
|
||||||
end,
|
end,
|
||||||
fold(Tail, State#state{threshold=CompressThreshold, deflate_flush=DeflateFlush}, Acc);
|
fold(Tail, State#state{threshold=CompressThreshold, deflate_flush=DeflateFlush},
|
||||||
|
[SetOptions|Acc]);
|
||||||
%% Otherwise, we have an unrelated command or compression is disabled.
|
%% Otherwise, we have an unrelated command or compression is disabled.
|
||||||
fold([Command|Tail], State, Acc) ->
|
fold([Command|Tail], State, Acc) ->
|
||||||
fold(Tail, State, [Command|Acc]).
|
fold(Tail, State, [Command|Acc]).
|
||||||
|
|
|
@ -576,6 +576,9 @@ commands(State=#state{socket=Socket, transport=Transport, http2_init=upgrade},
|
||||||
commands(State0, StreamID, [{switch_protocol, Headers, _Mod, _ModState}|Tail]) ->
|
commands(State0, StreamID, [{switch_protocol, Headers, _Mod, _ModState}|Tail]) ->
|
||||||
State = info(State0, StreamID, {headers, 200, Headers}),
|
State = info(State0, StreamID, {headers, 200, Headers}),
|
||||||
commands(State, StreamID, Tail);
|
commands(State, StreamID, Tail);
|
||||||
|
%% Set options dynamically.
|
||||||
|
commands(State, StreamID, [{set_options, _Opts}|Tail]) ->
|
||||||
|
commands(State, StreamID, Tail);
|
||||||
commands(State, StreamID, [stop|_Tail]) ->
|
commands(State, StreamID, [stop|_Tail]) ->
|
||||||
%% @todo Do we want to run the commands after a stop?
|
%% @todo Do we want to run the commands after a stop?
|
||||||
%% @todo Do we even allow commands after?
|
%% @todo Do we even allow commands after?
|
||||||
|
|
|
@ -34,6 +34,12 @@ init_commands(_, _, #state{test=crash_in_terminate}) ->
|
||||||
[{response, 200, #{<<"content-length">> => <<"12">>}, <<"Hello world!">>}, stop];
|
[{response, 200, #{<<"content-length">> => <<"12">>}, <<"Hello world!">>}, stop];
|
||||||
init_commands(_, _, #state{test=crash_in_early_error}) ->
|
init_commands(_, _, #state{test=crash_in_early_error}) ->
|
||||||
error(crash);
|
error(crash);
|
||||||
|
init_commands(_, _, #state{test=set_options_ignore_unknown}) ->
|
||||||
|
[
|
||||||
|
{set_options, #{unknown_options => true}},
|
||||||
|
{response, 200, #{<<"content-length">> => <<"12">>}, <<"Hello world!">>},
|
||||||
|
stop
|
||||||
|
];
|
||||||
init_commands(_, _, State=#state{test=shutdown_on_stream_stop}) ->
|
init_commands(_, _, State=#state{test=shutdown_on_stream_stop}) ->
|
||||||
Spawn = init_process(false, State),
|
Spawn = init_process(false, State),
|
||||||
[{headers, 200, #{}}, {spawn, Spawn, 5000}, stop];
|
[{headers, 200, #{}}, {spawn, Spawn, 5000}, stop];
|
||||||
|
|
|
@ -224,6 +224,24 @@ do_crash_in_early_error_fatal(Config) ->
|
||||||
%% Confirm the connection gets closed.
|
%% Confirm the connection gets closed.
|
||||||
gun_down(ConnPid).
|
gun_down(ConnPid).
|
||||||
|
|
||||||
|
set_options_ignore_unknown(Config) ->
|
||||||
|
doc("Confirm that unknown options are ignored when using the set_options commands."),
|
||||||
|
Self = self(),
|
||||||
|
ConnPid = gun_open(Config),
|
||||||
|
Ref = gun:get(ConnPid, "/long_polling", [
|
||||||
|
{<<"accept-encoding">>, <<"gzip">>},
|
||||||
|
{<<"x-test-case">>, <<"set_options_ignore_unknown">>},
|
||||||
|
{<<"x-test-pid">>, pid_to_list(Self)}
|
||||||
|
]),
|
||||||
|
%% Confirm init/3 is called.
|
||||||
|
Pid = receive {Self, P, init, _, _, _} -> P after 1000 -> error(timeout) end,
|
||||||
|
%% Confirm terminate/3 is called, indicating the stream ended.
|
||||||
|
receive {Self, Pid, terminate, _, _, _} -> ok after 1000 -> error(timeout) end,
|
||||||
|
%% Confirm the response is sent.
|
||||||
|
{response, nofin, 200, _} = gun:await(ConnPid, Ref),
|
||||||
|
{ok, _} = gun:await_body(ConnPid, Ref),
|
||||||
|
ok.
|
||||||
|
|
||||||
shutdown_on_stream_stop(Config) ->
|
shutdown_on_stream_stop(Config) ->
|
||||||
doc("Confirm supervised processes are shutdown when stopping the stream."),
|
doc("Confirm supervised processes are shutdown when stopping the stream."),
|
||||||
Self = self(),
|
Self = self(),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue