aboutsummaryrefslogtreecommitdiffstats
path: root/src/gun.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/gun.erl')
-rw-r--r--src/gun.erl80
1 files changed, 51 insertions, 29 deletions
diff --git a/src/gun.erl b/src/gun.erl
index 31833f5..b4c1686 100644
--- a/src/gun.erl
+++ b/src/gun.erl
@@ -103,7 +103,7 @@
-export([domain_lookup/3]).
-export([connecting/3]).
-export([initial_tls_handshake/3]).
--export([ensure_alpn_sni/3]).
+-export([ensure_tls_opts/3]).
-export([tls_handshake/3]).
-export([connected_protocol_init/3]).
-export([connected/3]).
@@ -281,6 +281,26 @@
}.
-export_type([ws_opts/0]).
+-type resp_headers() :: [{binary(), binary()}].
+
+-type await_result() :: {inform, 100..199, resp_headers()}
+ | {response, fin | nofin, non_neg_integer(), resp_headers()}
+ | {data, fin | nofin, binary()}
+ | {sse, cow_sse:event() | fin}
+ | {trailers, resp_headers()}
+ | {push, stream_ref(), binary(), binary(), resp_headers()}
+ | {upgrade, [binary()], resp_headers()}
+ | {ws, ws_frame()}
+ | {up, http | http2 | raw | socks}
+ | {notify, settings_changed, map()}
+ | {error, {stream_error | connection_error | down, any()} | timeout}.
+-export_type([await_result/0]).
+
+-type await_body_result() :: {ok, binary()}
+ | {ok, binary(), resp_headers()}
+ | {error, {stream_error | connection_error | down, any()} | timeout}.
+-export_type([await_body_result/0]).
+
-record(state, {
owner :: pid(),
status :: {up, reference()} | {down, any()} | shutdown,
@@ -445,12 +465,12 @@ check_protocols_opt(Protocols) ->
consider_tracing(ServerPid, #{trace := true}) ->
dbg:tracer(),
- dbg:tpl(gun, [{'_', [], [{return_trace}]}]),
- dbg:tpl(gun_http, [{'_', [], [{return_trace}]}]),
- dbg:tpl(gun_http2, [{'_', [], [{return_trace}]}]),
- dbg:tpl(gun_raw, [{'_', [], [{return_trace}]}]),
- dbg:tpl(gun_socks, [{'_', [], [{return_trace}]}]),
- dbg:tpl(gun_ws, [{'_', [], [{return_trace}]}]),
+ _ = dbg:tpl(gun, [{'_', [], [{return_trace}]}]),
+ _ = dbg:tpl(gun_http, [{'_', [], [{return_trace}]}]),
+ _ = dbg:tpl(gun_http2, [{'_', [], [{return_trace}]}]),
+ _ = dbg:tpl(gun_raw, [{'_', [], [{return_trace}]}]),
+ _ = dbg:tpl(gun_socks, [{'_', [], [{return_trace}]}]),
+ _ = dbg:tpl(gun_ws, [{'_', [], [{return_trace}]}]),
dbg:p(ServerPid, all);
consider_tracing(_, _) ->
ok.
@@ -707,19 +727,6 @@ connect(ServerPid, Destination, Headers, ReqOpts) ->
%% Awaiting gun messages.
--type resp_headers() :: [{binary(), binary()}].
--type await_result() :: {inform, 100..199, resp_headers()}
- | {response, fin | nofin, non_neg_integer(), resp_headers()}
- | {data, fin | nofin, binary()}
- | {sse, cow_sse:event() | fin}
- | {trailers, resp_headers()}
- | {push, stream_ref(), binary(), binary(), resp_headers()}
- | {upgrade, [binary()], resp_headers()}
- | {ws, ws_frame()}
- | {up, http | http2 | raw | socks}
- | {notify, settings_changed, map()}
- | {error, {stream_error | connection_error | down, any()} | timeout}.
-
-spec await(pid(), stream_ref()) -> await_result().
await(ServerPid, StreamRef) ->
MRef = monitor(process, ServerPid),
@@ -769,10 +776,6 @@ await(ServerPid, StreamRef, Timeout, MRef) ->
{error, timeout}
end.
--type await_body_result() :: {ok, binary()}
- | {ok, binary(), resp_headers()}
- | {error, {stream_error | connection_error | down, any()} | timeout}.
-
-spec await_body(pid(), stream_ref()) -> await_body_result().
await_body(ServerPid, StreamRef) ->
MRef = monitor(process, ServerPid),
@@ -1097,7 +1100,7 @@ connecting(_, {retries, Retries, LookupInfo}, State=#state{opts=Opts,
initial_tls_handshake(_, {retries, Retries, Socket}, State0=#state{opts=Opts, origin_host=OriginHost}) ->
Protocols = maps:get(protocols, Opts, [http2, http]),
HandshakeEvent = #{
- tls_opts => ensure_alpn_sni(Protocols, maps:get(tls_opts, Opts, []), OriginHost),
+ tls_opts => ensure_tls_opts(Protocols, maps:get(tls_opts, Opts, []), OriginHost),
timeout => maps:get(tls_handshake_timeout, Opts, infinity)
},
case normal_tls_handshake(Socket, State0, HandshakeEvent, Protocols) of
@@ -1109,7 +1112,26 @@ initial_tls_handshake(_, {retries, Retries, Socket}, State0=#state{opts=Opts, or
{next_event, internal, {retries, Retries, Reason}}}
end.
-ensure_alpn_sni(Protocols0, TransOpts0, OriginHost) ->
+ensure_tls_opts(Protocols0, TransOpts0, OriginHost) ->
+ %% CA certificates.
+ TransOpts1 = case lists:keymember(cacerts, 1, TransOpts0) of
+ true ->
+ TransOpts0;
+ false ->
+ case lists:keymember(cacertfile, 1, TransOpts0) of
+ true ->
+ TransOpts0;
+ false ->
+ %% This function was added in OTP-25. We use it when it is
+ %% available and keep the previous behavior when it isn't.
+ case erlang:function_exported(public_key, cacerts_get, 0) of
+ true ->
+ [{cacerts, public_key:cacerts_get()}|TransOpts0];
+ false ->
+ TransOpts0
+ end
+ end
+ end,
%% ALPN.
Protocols = lists:foldl(fun
(http, Acc) -> [<<"http/1.1">>|Acc];
@@ -1120,7 +1142,7 @@ ensure_alpn_sni(Protocols0, TransOpts0, OriginHost) ->
end, [], Protocols0),
TransOpts = [
{alpn_advertised_protocols, Protocols}
- |TransOpts0],
+ |TransOpts1],
%% SNI.
%%
%% Normally only DNS hostnames are supported for SNI. However, the ssl
@@ -1161,7 +1183,7 @@ tls_handshake(internal, {tls_handshake,
HandshakeEvent0=#{tls_opts := TLSOpts0, timeout := TLSTimeout}, Protocols, ReplyTo},
State=#state{socket=Socket, transport=Transport, origin_host=OriginHost, origin_port=OriginPort,
event_handler=EvHandler, event_handler_state=EvHandlerState0}) ->
- TLSOpts = ensure_alpn_sni(Protocols, TLSOpts0, OriginHost),
+ TLSOpts = ensure_tls_opts(Protocols, TLSOpts0, OriginHost),
HandshakeEvent = HandshakeEvent0#{
tls_opts => TLSOpts,
socket => Socket
@@ -1201,7 +1223,7 @@ tls_handshake(Type, Event, State) ->
normal_tls_handshake(Socket, State=#state{
origin_host=OriginHost, event_handler=EvHandler, event_handler_state=EvHandlerState0},
HandshakeEvent0=#{tls_opts := TLSOpts0, timeout := TLSTimeout}, Protocols) ->
- TLSOpts = ensure_alpn_sni(Protocols, TLSOpts0, OriginHost),
+ TLSOpts = ensure_tls_opts(Protocols, TLSOpts0, OriginHost),
HandshakeEvent = HandshakeEvent0#{
tls_opts => TLSOpts,
socket => Socket