aboutsummaryrefslogtreecommitdiffstats
path: root/src/gun.erl
diff options
context:
space:
mode:
Diffstat (limited to 'src/gun.erl')
-rw-r--r--src/gun.erl44
1 files changed, 34 insertions, 10 deletions
diff --git a/src/gun.erl b/src/gun.erl
index af576fb..9c92281 100644
--- a/src/gun.erl
+++ b/src/gun.erl
@@ -120,7 +120,8 @@
port := inet:port_number(),
username => iodata(),
password => iodata(),
- protocol => http | http2,
+ protocol => http | http2, %% @todo Remove in Gun 2.0.
+ protocols => [http | http2],
transport => tcp | tls,
tls_opts => [ssl:connect_option()],
tls_handshake_timeout => timeout()
@@ -652,14 +653,9 @@ default_transport(443) -> tls;
default_transport(_) -> tcp.
transport_connect(State=#state{host=Host, port=Port, opts=Opts, transport=Transport=gun_tls}, Retries) ->
- Protocols = [case P of
- http -> <<"http/1.1">>;
- http2 -> <<"h2">>
- end || P <- maps:get(protocols, Opts, [http2, http])],
- TransportOpts = [binary, {active, false},
- {alpn_advertised_protocols, Protocols},
- {client_preferred_next_protocols, {client, Protocols, <<"http/1.1">>}}
- |maps:get(transport_opts, Opts, [])],
+ TransportOpts = [binary, {active, false}|ensure_alpn(
+ maps:get(protocols, Opts, [http2, http]),
+ maps:get(transport_opts, Opts, []))],
case Transport:connect(Host, Port, TransportOpts, maps:get(connect_timeout, Opts, infinity)) of
{ok, Socket} ->
{Protocol, ProtoOptsKey} = case ssl:negotiated_protocol(Socket) of
@@ -684,6 +680,16 @@ transport_connect(State=#state{host=Host, port=Port, opts=Opts, transport=Transp
retry(State#state{last_error=Reason}, Retries)
end.
+ensure_alpn(Protocols0, TransportOpts) ->
+ Protocols = [case P of
+ http -> <<"http/1.1">>;
+ http2 -> <<"h2">>
+ end || P <- Protocols0],
+ [
+ {alpn_advertised_protocols, Protocols},
+ {client_preferred_next_protocols, {client, Protocols, <<"http/1.1">>}}
+ |TransportOpts].
+
up(State=#state{owner=Owner, opts=Opts, transport=Transport}, Socket, Protocol, ProtoOptsKey) ->
ProtoOpts = maps:get(ProtoOptsKey, Opts, #{}),
ProtoState = Protocol:init(Owner, Socket, Transport, ProtoOpts),
@@ -778,7 +784,25 @@ loop(State=#state{parent=Parent, owner=Owner, owner_ref=OwnerRef,
ProtoState2 = Protocol:data(ProtoState,
StreamRef, ReplyTo, IsFin, Data),
loop(State#state{protocol_state=ProtoState2});
- {connect, ReplyTo, StreamRef, Destination, Headers} ->
+ {connect, ReplyTo, StreamRef, Destination0, Headers} ->
+ %% The protocol option has been deprecated in favor of the protocols option.
+ %% Nobody probably ended up using it, but let's not break the interface.
+ Destination1 = case Destination0 of
+ #{protocols := _} ->
+ Destination0;
+ #{protocol := DestProto} ->
+ Destination0#{protocols => [DestProto]};
+ _ ->
+ Destination0
+ end,
+ Destination = case Destination1 of
+ #{transport := tls} ->
+ Destination1#{tls_opts => ensure_alpn(
+ maps:get(protocols, Destination1, [http]),
+ maps:get(tls_opts, Destination1, []))};
+ _ ->
+ Destination1
+ end,
ProtoState2 = Protocol:connect(ProtoState, StreamRef, ReplyTo, Destination, Headers),
loop(State#state{protocol_state=ProtoState2});
{cancel, ReplyTo, StreamRef} ->