aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLoïc Hoguin <[email protected]>2018-06-04 08:40:31 +0200
committerLoïc Hoguin <[email protected]>2018-06-04 08:40:31 +0200
commit93c88fdc541c3f8a4ebbae3699bee90d00dc637f (patch)
tree236d186d109db248821674ead9e3148617d3e5d1
parent1be0151ec7b6a98064e648d5598f56cbdec65dc7 (diff)
downloadgun-93c88fdc541c3f8a4ebbae3699bee90d00dc637f.tar.gz
gun-93c88fdc541c3f8a4ebbae3699bee90d00dc637f.tar.bz2
gun-93c88fdc541c3f8a4ebbae3699bee90d00dc637f.zip
Remove the dependency on Ranch
We instead of two new modules, gun_tcp and gun_tls. They only have 6 functions so far, much less than what Ranch provided before. Also renames ssl to tls where applicable. It's still possible to use the ssl transport option but it's now undocumented.
-rw-r--r--Makefile3
-rw-r--r--doc/src/guide/connect.asciidoc8
-rw-r--r--doc/src/guide/start.asciidoc2
-rw-r--r--doc/src/manual/gun.asciidoc12
-rw-r--r--doc/src/manual/gun_app.asciidoc1
-rw-r--r--ebin/gun.app4
-rw-r--r--rebar.config2
-rw-r--r--src/gun.erl19
-rw-r--r--src/gun_http.erl2
-rw-r--r--src/gun_http2.erl30
-rw-r--r--src/gun_tcp.erl49
-rw-r--r--src/gun_tls.erl49
12 files changed, 141 insertions, 40 deletions
diff --git a/Makefile b/Makefile
index 6cedb2b..afa900f 100644
--- a/Makefile
+++ b/Makefile
@@ -12,9 +12,8 @@ CT_OPTS += -pa test -ct_hooks gun_ct_hook [] # -boot start_sasl
LOCAL_DEPS = ssl
-DEPS = cowlib ranch
+DEPS = cowlib
dep_cowlib = git https://github.com/ninenines/cowlib master
-dep_ranch = git https://github.com/ninenines/ranch master
TEST_DEPS = $(if $(CI_ERLANG_MK),ci.erlang.mk) ct_helper
dep_ct_helper = git https://github.com/extend/ct_helper.git master
diff --git a/doc/src/guide/connect.asciidoc b/doc/src/guide/connect.asciidoc
index e0b09d6..f7983bc 100644
--- a/doc/src/guide/connect.asciidoc
+++ b/doc/src/guide/connect.asciidoc
@@ -34,9 +34,9 @@ The `gun:open/{2,3}` function must be used to open a connection.
{ok, ConnPid} = gun:open("example.org", 443).
If the port given is 443, Gun will attempt to connect using
-SSL. The protocol will be selected automatically using the
+TLS. The protocol will be selected automatically using the
ALPN extension for TLS. By default Gun supports HTTP/2
-and HTTP/1.1 when connecting using SSL.
+and HTTP/1.1 when connecting using TLS.
For any other port, Gun will attempt to connect using TCP
and will use the HTTP/1.1 protocol.
@@ -47,10 +47,10 @@ options. The manual documents all available options.
Options can be provided as a third argument, and take the
form of a map.
-.Opening an SSL connection to example.org on port 8443
+.Opening a TLS connection to example.org on port 8443
[source,erlang]
-{ok, ConnPid} = gun:open("example.org", 8443, #{transport=>ssl}).
+{ok, ConnPid} = gun:open("example.org", 8443, #{transport => tls}).
=== Waiting for the connection to be established
diff --git a/doc/src/guide/start.asciidoc b/doc/src/guide/start.asciidoc
index 6d93e2e..17cbe87 100644
--- a/doc/src/guide/start.asciidoc
+++ b/doc/src/guide/start.asciidoc
@@ -27,7 +27,7 @@ use it.
[source,erlang]
----
1> application:ensure_all_started(gun).
-{ok,[ranch,crypto,cowlib,asn1,public_key,ssl,gun]}
+{ok,[crypto,cowlib,asn1,public_key,ssl,gun]}
----
=== Stopping
diff --git a/doc/src/manual/gun.asciidoc b/doc/src/manual/gun.asciidoc
index b5ed039..b15ce09 100644
--- a/doc/src/manual/gun.asciidoc
+++ b/doc/src/manual/gun.asciidoc
@@ -149,7 +149,7 @@ opts() :: #{
retry => non_neg_integer(),
retry_timeout => pos_integer(),
trace => boolean(),
- transport => tcp | ssl,
+ transport => tcp | tls,
transport_opts => [gen_tcp:connect_option()] | [ssl:connect_option()],
ws_opts => ws_opts()
}
@@ -175,11 +175,11 @@ protocols - see below::
Ordered list of preferred protocols. When the transport is `tcp`,
this list must contain exactly one protocol. When the transport
-is `ssl`, this list must contain at least one protocol and will be
+is `tls`, this list must contain at least one protocol and will be
used to negotiate a protocol via ALPN. When the server does not
support ALPN then `http` will always be used. Defaults to
`[http]` when the transport is `tcp`, and `[http2, http]` when the
-transport is `ssl`.
+transport is `tls`.
retry (5)::
@@ -196,12 +196,12 @@ only be used during debugging.
transport - see below::
-Whether to use SSL or plain TCP. The default varies depending on the
-port used. Port 443 defaults to `ssl`. All other ports default to `tcp`.
+Whether to use TLS or plain TCP. The default varies depending on the
+port used. Port 443 defaults to `tls`. All other ports default to `tcp`.
transport_opts ([])::
-Transport options. They are TCP options or SSL options depending on
+Transport options. They are TCP options or TLS options depending on
the selected transport.
ws_opts (#{})::
diff --git a/doc/src/manual/gun_app.asciidoc b/doc/src/manual/gun_app.asciidoc
index 606d9fb..c369095 100644
--- a/doc/src/manual/gun_app.asciidoc
+++ b/doc/src/manual/gun_app.asciidoc
@@ -19,7 +19,6 @@ to the server and reconnects automatically when necessary.
== Dependencies
-// @todo I do not want a dependency on Ranch, remove it
* link:man:cowlib(7)[cowlib(7)] - Support library for manipulating Web protocols
* ssl - Secure communication over sockets
diff --git a/ebin/gun.app b/ebin/gun.app
index f40aefd..374fb93 100644
--- a/ebin/gun.app
+++ b/ebin/gun.app
@@ -1,9 +1,9 @@
{application, 'gun', [
{description, "HTTP/1.1, HTTP/2 and Websocket client for Erlang/OTP."},
{vsn, "1.0.0-pre.5"},
- {modules, ['gun','gun_app','gun_content_handler','gun_data_h','gun_http','gun_http2','gun_sse_h','gun_sup','gun_ws','gun_ws_h']},
+ {modules, ['gun','gun_app','gun_content_handler','gun_data_h','gun_http','gun_http2','gun_sse_h','gun_sup','gun_tcp','gun_tls','gun_ws','gun_ws_h']},
{registered, [gun_sup]},
- {applications, [kernel,stdlib,ssl,cowlib,ranch]},
+ {applications, [kernel,stdlib,ssl,cowlib]},
{mod, {gun_app, []}},
{env, []}
]}. \ No newline at end of file
diff --git a/rebar.config b/rebar.config
index 21a0435..348f53e 100644
--- a/rebar.config
+++ b/rebar.config
@@ -1,4 +1,4 @@
{deps, [
-{cowlib,".*",{git,"https://github.com/ninenines/cowlib","master"}},{ranch,".*",{git,"https://github.com/ninenines/ranch","master"}}
+{cowlib,".*",{git,"https://github.com/ninenines/cowlib","master"}}
]}.
{erl_opts, [debug_info,warn_export_vars,warn_shadow_vars,warn_obsolete_guard]}.
diff --git a/src/gun.erl b/src/gun.erl
index 1224c82..8156015 100644
--- a/src/gun.erl
+++ b/src/gun.erl
@@ -99,7 +99,7 @@
retry => non_neg_integer(),
retry_timeout => pos_integer(),
trace => boolean(),
- transport => tcp | ssl,
+ transport => tcp | tls | ssl,
transport_opts => [gen_tcp:connect_option()] | [ssl:connect_option()],
ws_opts => ws_opts()
}.
@@ -161,7 +161,12 @@ open(Host, Port, Opts) when is_list(Host); is_atom(Host); is_tuple(Host) ->
open_unix(SocketPath, Opts) ->
do_open({local, SocketPath}, 0, Opts).
-do_open(Host, Port, Opts) ->
+do_open(Host, Port, Opts0) ->
+ %% We accept both ssl and tls but only use tls in the code.
+ Opts = case Opts0 of
+ #{transport := ssl} -> Opts0#{transport => tls};
+ _ -> Opts0
+ end,
case check_options(maps:to_list(Opts)) of
ok ->
case supervisor:start_child(gun_sup, [self(), Host, Port, Opts]) of
@@ -215,7 +220,7 @@ check_options([{retry_timeout, T}|Opts]) when is_integer(T), T >= 0 ->
check_options(Opts);
check_options([{trace, B}|Opts]) when B =:= true; B =:= false ->
check_options(Opts);
-check_options([{transport, T}|Opts]) when T =:= tcp; T =:= ssl ->
+check_options([{transport, T}|Opts]) when T =:= tcp; T =:= tls ->
check_options(Opts);
check_options([{transport_opts, L}|Opts]) when is_list(L) ->
check_options(Opts);
@@ -588,17 +593,17 @@ init(Parent, Owner, Host, Port, Opts) ->
ok = proc_lib:init_ack(Parent, {ok, self()}),
Retry = maps:get(retry, Opts, 5),
Transport = case maps:get(transport, Opts, default_transport(Port)) of
- tcp -> ranch_tcp;
- ssl -> ranch_ssl
+ tcp -> gun_tcp;
+ tls -> gun_tls
end,
OwnerRef = monitor(process, Owner),
connect(#state{parent=Parent, owner=Owner, owner_ref=OwnerRef,
host=Host, port=Port, opts=Opts, transport=Transport}, Retry).
-default_transport(443) -> ssl;
+default_transport(443) -> tls;
default_transport(_) -> tcp.
-connect(State=#state{host=Host, port=Port, opts=Opts, transport=Transport=ranch_ssl}, Retries) ->
+connect(State=#state{host=Host, port=Port, opts=Opts, transport=Transport=gun_tls}, Retries) ->
Protocols = [case P of
http -> <<"http/1.1">>;
http2 -> <<"h2">>
diff --git a/src/gun_http.erl b/src/gun_http.erl
index 2fd0aac..61409fb 100644
--- a/src/gun_http.erl
+++ b/src/gun_http.erl
@@ -500,7 +500,7 @@ ws_upgrade(State=#http_state{socket=Socket, transport=Transport, owner=Owner, ou
{<<"sec-websocket-key">>, Key}
|Headers2
],
- IsSecure = Transport:secure(),
+ IsSecure = Transport =:= gun_tls,
Headers = case lists:keymember(<<"host">>, 1, Headers0) of
true -> Headers3;
false when Port =:= 80, not IsSecure -> [{<<"host">>, Host}|Headers3];
diff --git a/src/gun_http2.erl b/src/gun_http2.erl
index 1f25e83..cf83970 100644
--- a/src/gun_http2.erl
+++ b/src/gun_http2.erl
@@ -370,9 +370,9 @@ prepare_headers(EncodeState, Transport, Method, Host0, Port, Path, Headers0) ->
lists:keydelete(<<"upgrade">>, 1, Headers0)))))),
Headers = [
{<<":method">>, Method},
- {<<":scheme">>, case Transport:secure() of
- true -> <<"https">>;
- false -> <<"http">>
+ {<<":scheme">>, case Transport of
+ gun_tls -> <<"https">>;
+ gun_tcp -> <<"http">>
end},
{<<":authority">>, Authority},
{<<":path">>, Path}
@@ -465,17 +465,17 @@ send_data(State=#http2_state{socket=Socket, transport=Transport, opts=Opts,
min(RemoteMaxFrameSize, ConfiguredMaxFrameSize)
),
case Data of
- {sendfile, Offset, Bytes, Path} when Bytes =< MaxSendSize ->
- Transport:send(Socket, cow_http2:data_header(StreamID, IsFin, Bytes)),
- Transport:sendfile(Socket, Path, Offset, Bytes),
- {State#http2_state{local_window=ConnWindow - Bytes},
- Stream#stream{local=IsFin, local_window=StreamWindow - Bytes}};
- {sendfile, Offset, Bytes, Path} ->
- Transport:send(Socket, cow_http2:data_header(StreamID, nofin, MaxSendSize)),
- Transport:sendfile(Socket, Path, Offset, MaxSendSize),
- send_data(State#http2_state{local_window=ConnWindow - MaxSendSize},
- Stream#stream{local_window=StreamWindow - MaxSendSize},
- IsFin, {sendfile, Offset + MaxSendSize, Bytes - MaxSendSize, Path}, In);
+% {sendfile, Offset, Bytes, Path} when Bytes =< MaxSendSize ->
+% Transport:send(Socket, cow_http2:data_header(StreamID, IsFin, Bytes)),
+% Transport:sendfile(Socket, Path, Offset, Bytes),
+% {State#http2_state{local_window=ConnWindow - Bytes},
+% Stream#stream{local=IsFin, local_window=StreamWindow - Bytes}};
+% {sendfile, Offset, Bytes, Path} ->
+% Transport:send(Socket, cow_http2:data_header(StreamID, nofin, MaxSendSize)),
+% Transport:sendfile(Socket, Path, Offset, MaxSendSize),
+% send_data(State#http2_state{local_window=ConnWindow - MaxSendSize},
+% Stream#stream{local_window=StreamWindow - MaxSendSize},
+% IsFin, {sendfile, Offset + MaxSendSize, Bytes - MaxSendSize, Path}, In);
Iolist0 ->
IolistSize = iolist_size(Iolist0),
if
@@ -500,7 +500,7 @@ send_trailers(State=#http2_state{socket=Socket, transport=Transport, encode_stat
queue_data(Stream=#stream{local_buffer=Q0, local_buffer_size=Size0}, IsFin, Data, In) ->
DataSize = case Data of
- {sendfile, _, Bytes, _} -> Bytes;
+% {sendfile, _, Bytes, _} -> Bytes;
Iolist -> iolist_size(Iolist)
end,
Q = queue:In({IsFin, DataSize, Data}, Q0),
diff --git a/src/gun_tcp.erl b/src/gun_tcp.erl
new file mode 100644
index 0000000..80bc45b
--- /dev/null
+++ b/src/gun_tcp.erl
@@ -0,0 +1,49 @@
+%% Copyright (c) 2011-2018, Loïc Hoguin <[email protected]>
+%%
+%% Permission to use, copy, modify, and/or distribute this software for any
+%% purpose with or without fee is hereby granted, provided that the above
+%% copyright notice and this permission notice appear in all copies.
+%%
+%% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+%% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+%% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+%% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+%% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+%% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+%% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+-module(gun_tcp).
+
+-export([messages/0]).
+-export([connect/4]).
+-export([send/2]).
+-export([setopts/2]).
+-export([sockname/1]).
+-export([close/1]).
+
+messages() -> {tcp, tcp_closed, tcp_error}.
+
+-spec connect(inet:ip_address() | inet:hostname(),
+ inet:port_number(), any(), timeout())
+ -> {ok, inet:socket()} | {error, atom()}.
+connect(Host, Port, Opts, Timeout) when is_integer(Port) ->
+ gen_tcp:connect(Host, Port,
+ Opts ++ [binary, {active, false}, {packet, raw}],
+ Timeout).
+
+-spec send(inet:socket(), iodata()) -> ok | {error, atom()}.
+send(Socket, Packet) ->
+ gen_tcp:send(Socket, Packet).
+
+-spec setopts(inet:socket(), list()) -> ok | {error, atom()}.
+setopts(Socket, Opts) ->
+ inet:setopts(Socket, Opts).
+
+-spec sockname(inet:socket())
+ -> {ok, {inet:ip_address(), inet:port_number()}} | {error, atom()}.
+sockname(Socket) ->
+ inet:sockname(Socket).
+
+-spec close(inet:socket()) -> ok.
+close(Socket) ->
+ gen_tcp:close(Socket).
diff --git a/src/gun_tls.erl b/src/gun_tls.erl
new file mode 100644
index 0000000..8ce46c3
--- /dev/null
+++ b/src/gun_tls.erl
@@ -0,0 +1,49 @@
+%% Copyright (c) 2011-2018, Loïc Hoguin <[email protected]>
+%%
+%% Permission to use, copy, modify, and/or distribute this software for any
+%% purpose with or without fee is hereby granted, provided that the above
+%% copyright notice and this permission notice appear in all copies.
+%%
+%% THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+%% WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+%% MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+%% ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+%% WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+%% ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+%% OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+-module(gun_tls).
+
+-export([messages/0]).
+-export([connect/4]).
+-export([send/2]).
+-export([setopts/2]).
+-export([sockname/1]).
+-export([close/1]).
+
+messages() -> {ssl, ssl_closed, ssl_error}.
+
+-spec connect(inet:ip_address() | inet:hostname(),
+ inet:port_number(), any(), timeout())
+ -> {ok, inet:socket()} | {error, atom()}.
+connect(Host, Port, Opts, Timeout) when is_integer(Port) ->
+ ssl:connect(Host, Port,
+ Opts ++ [binary, {active, false}, {packet, raw}],
+ Timeout).
+
+-spec send(ssl:sslsocket(), iodata()) -> ok | {error, atom()}.
+send(Socket, Packet) ->
+ ssl:send(Socket, Packet).
+
+-spec setopts(ssl:sslsocket(), list()) -> ok | {error, atom()}.
+setopts(Socket, Opts) ->
+ ssl:setopts(Socket, Opts).
+
+-spec sockname(ssl:sslsocket())
+ -> {ok, {inet:ip_address(), inet:port_number()}} | {error, atom()}.
+sockname(Socket) ->
+ ssl:sockname(Socket).
+
+-spec close(ssl:sslsocket()) -> ok.
+close(Socket) ->
+ ssl:close(Socket).