Current section
Files
Jump to
Current section
Files
src/ranch_etls.erl
%%%-------------------------------------------------------------------
%%% @author Konrad Zemek
%%% @copyright (C) 2015 ACK CYFRONET AGH
%%% This software is released under the MIT license
%%% cited in 'LICENSE.md'.
%%% @end
%%%-------------------------------------------------------------------
%%% @doc
%%% An implementation of ranch_transport behavior on top of etls.
%%% For function documentation check Ranch's ranch_transport docs.
%%% @end
%%%-------------------------------------------------------------------
-module(ranch_etls).
-author("Konrad Zemek").
%% API
-export([name/0, secure/0, messages/0, listen/1, accept/2, accept_ack/2,
connect/3, connect/4, recv/3, send/2, setopts/2, controlling_process/2,
peername/1, sockname/1, shutdown/2, close/1, sendfile/2, sendfile/4,
sendfile/5]).
%%--------------------------------------------------------------------
%% @doc
%% {@link ranch_transport} callback name/0.
%% @end
%%--------------------------------------------------------------------
-spec name() -> atom().
name() ->
etls.
%%--------------------------------------------------------------------
%% @doc
%% {@link ranch_transport} callback secure/0.
%% @end
%%--------------------------------------------------------------------
-spec secure() -> boolean().
secure() ->
true.
%%--------------------------------------------------------------------
%% @doc
%% {@link ranch_transport} callback messages/0.
%% @end
%%--------------------------------------------------------------------
-spec messages() -> {OK :: atom(), Closed :: atom(), Error :: atom()}.
messages() ->
{etls, etls_closed, etls_error}.
%%--------------------------------------------------------------------
%% @doc
%% {@link ranch_transport} callback listen/1.
%% @end
%%--------------------------------------------------------------------
-spec listen([etls:option() | etls:ssl_option()]) ->
{ok, etls:socket()} |{error, atom()}.
listen(Opts) ->
Port = proplists:get_value(port, Opts),
etls:listen(Port, Opts).
%%--------------------------------------------------------------------
%% @doc
%% {@link ranch_transport} callback accept/2.
%% @end
%%--------------------------------------------------------------------
-spec accept(etls:acceptor(), timeout()) ->
{ok, etls:socket()} |
{error, closed | timeout | atom()}.
accept(Socket, Timeout) ->
etls:accept(Socket, Timeout).
%%--------------------------------------------------------------------
%% @doc
%% {@link ranch_transport} callback accept_ack/2.
%% @end
%%--------------------------------------------------------------------
-spec accept_ack(etls:socket(), timeout()) -> ok.
accept_ack(Socket, Timeout) ->
case etls:handshake(Socket, Timeout) of
ok ->
ok;
%% Socket most likely stopped responding, don't error out.
{error, Reason} when Reason =:= timeout; Reason =:= closed ->
ok = close(Socket),
exit(normal);
{error, Reason} ->
ok = close(Socket),
error(Reason)
end.
%%--------------------------------------------------------------------
%% @doc
%% {@link ranch_transport} callback connect/3.
%% @end
%%--------------------------------------------------------------------
-spec connect(string(), inet:port_number(),
[etls:option() | etls:ssl_option()]) ->
{ok, etls:socket()} |
{error, atom()}.
connect(Host, Port, Opts) ->
connect(Host, Port, Opts, infinity).
%%--------------------------------------------------------------------
%% @doc
%% {@link ranch_transport} callback connect/4.
%% @end
%%--------------------------------------------------------------------
-spec connect(string(), inet:port_number(), [etls:option() | etls:ssl_option()],
timeout()) ->
{ok, etls:socket()} |
{error, atom()}.
connect(Host, Port, Opts, Timeout) ->
etls:connect(Host, Port, Opts, Timeout).
%%--------------------------------------------------------------------
%% @doc
%% {@link ranch_transport} callback recv/3.
%% @end
%%--------------------------------------------------------------------
-spec recv(etls:socket(), non_neg_integer(), timeout()) ->
{ok, any()} |
{error, closed | timeout | atom()}.
recv(Socket, Size, Timeout) ->
etls:recv(Socket, Size, Timeout).
%%--------------------------------------------------------------------
%% @doc
%% {@link ranch_transport} callback send/2.
%% @end
%%--------------------------------------------------------------------
-spec send(etls:socket(), iodata()) -> ok | {error, atom()}.
send(Socket, Data) ->
etls:send(Socket, Data).
%%--------------------------------------------------------------------
%% @doc
%% {@link ranch_transport} callback setopts/2.
%% @end
%%--------------------------------------------------------------------
-spec setopts(etls:socket(), [etls:option() | etls:ssl_option()]) ->
ok | {error, atom()}.
setopts(Socket, Opts) ->
etls:setopts(Socket, Opts).
%%--------------------------------------------------------------------
%% @doc
%% {@link ranch_transport} callback controlling_process/2.
%% @end
%%--------------------------------------------------------------------
-spec controlling_process(etls:socket(), pid()) ->
ok | {error, closed | atom()}.
controlling_process(Socket, Pid) ->
etls:controlling_process(Socket, Pid).
%%--------------------------------------------------------------------
%% @doc
%% {@link ranch_transport} callback peername/1.
%% @end
%%--------------------------------------------------------------------
-spec peername(etls:socket()) ->
{ok, {inet:ip_address(), inet:port_number()}} |
{error, atom()}.
peername(Socket) ->
etls:peername(Socket).
%%--------------------------------------------------------------------
%% @doc
%% {@link ranch_transport} callback sockname/1.
%% @end
%%--------------------------------------------------------------------
-spec sockname(etls:socket() | etls:acceptor()) ->
{ok, {inet:ip_address(), inet:port_number()}} |
{error, atom()}.
sockname(Socket) ->
etls:sockname(Socket).
%%--------------------------------------------------------------------
%% @doc
%% {@link ranch_transport} callback shutdown/2.
%% @end
%%--------------------------------------------------------------------
-spec shutdown(etls:socket(), read | write | read_write) ->
ok | {error, atom()}.
shutdown(Socket, Type) ->
etls:shutdown(Socket, Type).
%%--------------------------------------------------------------------
%% @doc
%% {@link ranch_transport} callback close/1.
%% @end
%%--------------------------------------------------------------------
-spec close(etls:socket()) -> ok.
close(Socket) ->
etls:close(Socket).
%%--------------------------------------------------------------------
%% @doc
%% {@link ranch_transport} callback sendfile/2.
%% @end
%%--------------------------------------------------------------------
-spec sendfile(etls:socket(), file:name() | file:fd()) ->
{ok, non_neg_integer()} |
{error, atom()}.
sendfile(Socket, Filename) ->
sendfile(Socket, Filename, 0, 0, []).
%%--------------------------------------------------------------------
%% @doc
%% {@link ranch_transport} callback sendfile/4.
%% @end
%%--------------------------------------------------------------------
-spec sendfile(etls:socket(), file:name() | file:fd(),
non_neg_integer(), non_neg_integer()) ->
{ok, non_neg_integer()} |
{error, atom()}.
sendfile(Socket, File, Offset, Bytes) ->
sendfile(Socket, File, Offset, Bytes, []).
%%--------------------------------------------------------------------
%% @doc
%% {@link ranch_transport} callback sendfile/5.
%% @end
%%--------------------------------------------------------------------
-spec sendfile(etls:socket(), file:name() | file:fd(), non_neg_integer(),
non_neg_integer(), ranch_transport:sendfile_opts()) ->
{ok, non_neg_integer()} |
{error, atom()}.
sendfile(Socket, File, Offset, Bytes, Opts) ->
ranch_transport:sendfile(?MODULE, Socket, File, Offset, Bytes, Opts).