From 148620ccf470897dc74439ca139d1848ac1996c0 Mon Sep 17 00:00:00 2001 From: Nelson Vides Date: Tue, 20 Apr 2021 14:58:58 +0200 Subject: [PATCH] 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. --- src/cowboy_clear.erl | 17 +++++++++++------ src/cowboy_tls.erl | 17 +++++++++++------ 2 files changed, 22 insertions(+), 12 deletions(-) diff --git a/src/cowboy_clear.erl b/src/cowboy_clear.erl index 4f3a234f..9f453d6c 100644 --- a/src/cowboy_clear.erl +++ b/src/cowboy_clear.erl @@ -33,12 +33,9 @@ start_link(Ref, Transport, Opts) -> -spec connection_process(pid(), ranch:ref(), module(), cowboy:opts()) -> ok. connection_process(Parent, Ref, Transport, Opts) -> - ProxyInfo = case maps:get(proxy_header, Opts, false) of - true -> - {ok, ProxyInfo0} = ranch:recv_proxy_header(Ref, 1000), - ProxyInfo0; - false -> - undefined + ProxyInfo = case maybe_proxy_info(Ref, Opts) of + {ok, ProxyInfo0} -> ProxyInfo0; + Error -> exit({shutdown, Error}) end, {ok, Socket} = ranch:handshake(Ref), %% 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) end, 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. diff --git a/src/cowboy_tls.erl b/src/cowboy_tls.erl index c049ecbe..cbfc9261 100644 --- a/src/cowboy_tls.erl +++ b/src/cowboy_tls.erl @@ -33,12 +33,9 @@ start_link(Ref, Transport, Opts) -> -spec connection_process(pid(), ranch:ref(), module(), cowboy:opts()) -> ok. connection_process(Parent, Ref, Transport, Opts) -> - ProxyInfo = case maps:get(proxy_header, Opts, false) of - true -> - {ok, ProxyInfo0} = ranch:recv_proxy_header(Ref, 1000), - ProxyInfo0; - false -> - undefined + ProxyInfo = case maybe_proxy_info(Ref, Opts) of + {ok, ProxyInfo0} -> ProxyInfo0; + Error -> exit({shutdown, Error}) end, {ok, Socket} = ranch:handshake(Ref), case ssl:negotiated_protocol(Socket) of @@ -54,3 +51,11 @@ init(Parent, Ref, Socket, Transport, ProxyInfo, Opts, Protocol) -> supervisor -> process_flag(trap_exit, true) end, 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.