0
Fork 0
mirror of https://github.com/ninenines/cowboy.git synced 2025-07-14 12:20:24 +00:00

Exit proc_lib gracefully on proxy header mismatch

If the proxy header was not to match (like, the header not being sent),
cowboy libraries were expecting really strict matching and then crashing
the proc_lib with a badmatch, that generates a hard error report. I
believe this error should be expected and termination should be graceful.
This commit is contained in:
Nelson Vides 2021-04-20 14:58:58 +02:00
parent 879a6b8bc5
commit 148620ccf4
No known key found for this signature in database
GPG key ID: D63DE880D7BA9432
2 changed files with 22 additions and 12 deletions

View file

@ -33,12 +33,9 @@ start_link(Ref, Transport, Opts) ->
-spec connection_process(pid(), ranch:ref(), module(), cowboy:opts()) -> ok. -spec connection_process(pid(), ranch:ref(), module(), cowboy:opts()) -> ok.
connection_process(Parent, Ref, Transport, Opts) -> connection_process(Parent, Ref, Transport, Opts) ->
ProxyInfo = case maps:get(proxy_header, Opts, false) of ProxyInfo = case maybe_proxy_info(Ref, Opts) of
true -> {ok, ProxyInfo0} -> ProxyInfo0;
{ok, ProxyInfo0} = ranch:recv_proxy_header(Ref, 1000), Error -> exit({shutdown, Error})
ProxyInfo0;
false ->
undefined
end, end,
{ok, Socket} = ranch:handshake(Ref), {ok, Socket} = ranch:handshake(Ref),
%% Use cowboy_http2 directly only when 'http' is missing. %% Use cowboy_http2 directly only when 'http' is missing.
@ -58,3 +55,11 @@ init(Parent, Ref, Socket, Transport, ProxyInfo, Opts, Protocol) ->
supervisor -> process_flag(trap_exit, true) supervisor -> process_flag(trap_exit, true)
end, end,
Protocol:init(Parent, Ref, Socket, Transport, ProxyInfo, Opts). Protocol:init(Parent, Ref, Socket, Transport, ProxyInfo, Opts).
maybe_proxy_info(Ref, Opts) ->
case maps:get(proxy_header, Opts, false) of
true ->
ranch:recv_proxy_header(Ref, 1000);
false ->
undefined
end.

View file

@ -33,12 +33,9 @@ start_link(Ref, Transport, Opts) ->
-spec connection_process(pid(), ranch:ref(), module(), cowboy:opts()) -> ok. -spec connection_process(pid(), ranch:ref(), module(), cowboy:opts()) -> ok.
connection_process(Parent, Ref, Transport, Opts) -> connection_process(Parent, Ref, Transport, Opts) ->
ProxyInfo = case maps:get(proxy_header, Opts, false) of ProxyInfo = case maybe_proxy_info(Ref, Opts) of
true -> {ok, ProxyInfo0} -> ProxyInfo0;
{ok, ProxyInfo0} = ranch:recv_proxy_header(Ref, 1000), Error -> exit({shutdown, Error})
ProxyInfo0;
false ->
undefined
end, end,
{ok, Socket} = ranch:handshake(Ref), {ok, Socket} = ranch:handshake(Ref),
case ssl:negotiated_protocol(Socket) of case ssl:negotiated_protocol(Socket) of
@ -54,3 +51,11 @@ init(Parent, Ref, Socket, Transport, ProxyInfo, Opts, Protocol) ->
supervisor -> process_flag(trap_exit, true) supervisor -> process_flag(trap_exit, true)
end, end,
Protocol:init(Parent, Ref, Socket, Transport, ProxyInfo, Opts). Protocol:init(Parent, Ref, Socket, Transport, ProxyInfo, Opts).
maybe_proxy_info(Ref, Opts) ->
case maps:get(proxy_header, Opts, false) of
true ->
ranch:recv_proxy_header(Ref, 1000);
false ->
undefined
end.