diff --git a/.tool-versions b/.tool-versions
index c0af933..81a1df3 100644
--- a/.tool-versions
+++ b/.tool-versions
@@ -1 +1,2 @@
erlang 21.3.8
+rebar 3.9.1
diff --git a/README.md b/README.md
index b7e4a78..bb2f9e1 100644
--- a/README.md
+++ b/README.md
@@ -9,6 +9,14 @@ emulate it's behaviour to the biggest possible extent.
Aside from the standard library of Erlang/OTP, it uses hackney for making HTTP requests
and lager for logging.
+Code style
+----
+We enforce the style from Erlang's own configuration.
+You can use the rebar3_fmt plugin to do it for you:
+
+ $ rebar3 fmt
+
+
Design
----
diff --git a/apps/epp_proxy/include/epp_proxy.hrl b/apps/epp_proxy/include/epp_proxy.hrl
index fdc6a2c..b754537 100644
--- a/apps/epp_proxy/include/epp_proxy.hrl
+++ b/apps/epp_proxy/include/epp_proxy.hrl
@@ -8,22 +8,22 @@
}).
-record(epp_error_request,
- {method, % get
- url, % "https://example.com/some-url"
- query_params, % {[{<<"msg">>, <<"Some">>}, {<<"code">>, <<"2001">>}]}
- cookies, % [<<"session=SomeSession; Version=1">>]
- headers % [{"User-Agent", <<"EPP proxy">>}, {"Other", <<"Header">>}]
- }).
+ {method, % get
+ url, % "https://example.com/some-url"
+ query_params, % {[{<<"msg">>, <<"Some">>}, {<<"code">>, <<"2001">>}]}
+ cookies, % [<<"session=SomeSession; Version=1">>]
+ headers % [{"User-Agent", <<"EPP proxy">>}, {"Other", <<"Header">>}]
+ }).
%% Unified version of the two records above. Depending on the method,
%% it either encodes parameters into multipart form or query parameters and url.
-record(epp_unified_request,
- {method, % get
- url, % "https://example.com/some-url"
- params, % {[{<<"msg">>, <<"Some">>}, {<<"code">>, <<"2001">>}]}
- cookies, % [<<"session=SomeSession; Version=1">>]
- headers % [{"User-Agent", <<"EPP proxy">>}, {"Other", <<"Header">>}]
- }).
+ {method, % get
+ url, % "https://example.com/some-url"
+ params, % {[{<<"msg">>, <<"Some">>}, {<<"code">>, <<"2001">>}]}
+ cookies, % [<<"session=SomeSession; Version=1">>]
+ headers % [{"User-Agent", <<"EPP proxy">>}, {"Other", <<"Header">>}]
+ }).
-type epp_request() :: #epp_request{}.
-type epp_error_request() :: #epp_error_request{}.
diff --git a/apps/epp_proxy/src/epp_certs.erl b/apps/epp_proxy/src/epp_certs.erl
index 0a2fff6..576c260 100644
--- a/apps/epp_proxy/src/epp_certs.erl
+++ b/apps/epp_proxy/src/epp_certs.erl
@@ -2,11 +2,12 @@
-include_lib("public_key/include/public_key.hrl").
--export([pem_certificate/1, subject_from_otp_certificate/1,
- common_name_from_subject/1, certificate_to_pem/1,
- der_certificate/1, headers_from_cert/1]).
+-export([certificate_to_pem/1,
+ common_name_from_subject/1, der_certificate/1,
+ headers_from_cert/1, pem_certificate/1,
+ subject_from_otp_certificate/1]).
-% Returns a tuple of headers {SSL_CLIENT_S_DN_CN, SSL_CLIENT_CERT}
+ % Returns a tuple of headers {SSL_CLIENT_S_DN_CN, SSL_CLIENT_CERT}
headers_from_cert(Der) ->
OTPCertificate = der_certificate(Der),
Subject = subject_from_otp_certificate(OTPCertificate),
@@ -24,26 +25,31 @@ der_certificate(Der) ->
certificate_to_pem(Certificate) ->
PemEntry = {'Certificate', Certificate, not_encrypted},
PemString = public_key:pem_encode([PemEntry]),
- CleanBinary = binary:replace(PemString, <<"\n">>, <<" ">>, [global]),
+ CleanBinary = binary:replace(PemString, <<"\n">>,
+ <<" ">>, [global]),
CleanBinary.
%% Read only a specific type of certificate, otherwise fail.
-subject_from_otp_certificate(Certificate) when is_record(Certificate, 'OTPCertificate') ->
- Subject = Certificate#'OTPCertificate'.tbsCertificate#'OTPTBSCertificate'.subject,
+subject_from_otp_certificate(Certificate)
+ when is_record(Certificate, 'OTPCertificate') ->
+ Subject =
+ (Certificate#'OTPCertificate'.tbsCertificate)#'OTPTBSCertificate'.subject,
Subject.
%% Take a subject rdnSequence that can be set into
%% HTTP header SSL_CLIENT_S_DN_CN.
common_name_from_subject(Subject) ->
- CommonName = ?'id-at-commonName',
- {_Type, Field} = field_from_subject(Subject, CommonName),
+ CommonName = (?'id-at-commonName'),
+ {_Type, Field} = field_from_subject(Subject,
+ CommonName),
Field.
%% Only used for local development test, is not required for the application.
pem_certificate(PathToCert) ->
{ok, PemBin} = file:file(PathToCert),
PemEntries = public_key:pem_decode(PemBin),
- {value, CertEntry} = lists:keysearch('Certificate', 1, PemEntries),
+ {value, CertEntry} = lists:keysearch('Certificate', 1,
+ PemEntries),
{_, DerCert, _} = CertEntry,
Decoded = public_key:pkix_decode_cert(DerCert, otp),
Decoded.
@@ -52,6 +58,7 @@ field_from_subject({rdnSequence, Attributes}, Field) ->
FlatList = lists:flatten(Attributes),
ValidAttrs = lists:filter(fun (X) ->
X#'AttributeTypeAndValue'.type =:= Field
- end, FlatList),
+ end,
+ FlatList),
Attribute = lists:last(ValidAttrs),
Attribute#'AttributeTypeAndValue'.value.
diff --git a/apps/epp_proxy/src/epp_http_client.erl b/apps/epp_proxy/src/epp_http_client.erl
index 3f89350..d20d3d9 100644
--- a/apps/epp_proxy/src/epp_http_client.erl
+++ b/apps/epp_proxy/src/epp_http_client.erl
@@ -4,126 +4,130 @@
-behaviour(epp_http_client_behaviour).
--export([request/1, error_request/1, request_builder/1]).
+-export([error_request/1, request/1,
+ request_builder/1]).
%% Callback API
request(#epp_request{} = Request) ->
HackneyArgs = handle_args(Request),
case apply(hackney, request, HackneyArgs) of
- {error, Error} ->
- log_and_return_canned(Error, Request);
+ {error, Error} -> log_and_return_canned(Error, Request);
{Status, _StatusCode, _Headers, ClientRef} ->
- {ok, Body} = hackney:body(ClientRef),
- {Status, Body}
- end.
+ {ok, Body} = hackney:body(ClientRef), {Status, Body}
+ end.
error_request(#epp_error_request{} = Request) ->
HackneyArgs = handle_error_args(Request),
case apply(hackney, request, HackneyArgs) of
- {error, Error} ->
- log_and_return_canned(Error, Request);
+ {error, Error} -> log_and_return_canned(Error, Request);
{Status, _StatusCode, _Headers, ClientRef} ->
- {ok, Body} = hackney:body(ClientRef),
- {Status, Body}
- end.
+ {ok, Body} = hackney:body(ClientRef), {Status, Body}
+ end.
-request_builder(Map) ->
- request_from_map(Map).
+request_builder(Map) -> request_from_map(Map).
%% Private API
-spec handle_args(epp_request()) -> list().
-handle_args(#epp_request{method=get, url=URL, headers=Headers, body="",
- cookies=Cookies}) ->
+
+handle_args(#epp_request{method = get, url = URL,
+ headers = Headers, body = "", cookies = Cookies}) ->
[get, URL, Headers, "", [{cookie, Cookies}, insecure]];
-handle_args(#epp_request{method=post, url=URL, headers=Headers, body=Body,
- cookies=Cookies}) ->
- [post, URL, Headers, Body, [{cookie, Cookies}, insecure]].
+handle_args(#epp_request{method = post, url = URL,
+ headers = Headers, body = Body, cookies = Cookies}) ->
+ [post, URL, Headers, Body,
+ [{cookie, Cookies}, insecure]].
-spec handle_error_args(epp_error_request()) -> list().
-handle_error_args(#epp_error_request{method=get, url=URL, headers=Headers,
- query_params=Params, cookies=Cookies}) ->
+
+handle_error_args(#epp_error_request{method = get,
+ url = URL, headers = Headers,
+ query_params = Params,
+ cookies = Cookies}) ->
QueryString = hackney_url:qs(Params),
CompleteURL = [URL, <<"?">>, QueryString],
- [get, CompleteURL, Headers, "", [{cookie, Cookies}, insecure]].
-
+ [get, CompleteURL, Headers, "",
+ [{cookie, Cookies}, insecure]].
%% Map request and return values.
-request_from_map(#{command := "error", session_id := SessionId,
- code := Code, message := Message, headers:=Headers,
+request_from_map(#{command := "error",
+ session_id := SessionId, code := Code,
+ message := Message, headers := Headers,
cl_trid := ClTRID}) ->
URL = epp_router:route_request("error"),
RequestMethod = epp_router:request_method("error"),
- Cookie = hackney_cookie:setcookie("session", SessionId, []),
+ Cookie = hackney_cookie:setcookie("session", SessionId,
+ []),
QueryParams = query_params(Code, Message, ClTRID),
- Headers=Headers,
- Request = #epp_error_request{url=URL,
- method=RequestMethod,
- query_params=QueryParams,
- cookies=[Cookie],
- headers=Headers},
+ Headers = Headers,
+ Request = #epp_error_request{url = URL,
+ method = RequestMethod,
+ query_params = QueryParams, cookies = [Cookie],
+ headers = Headers},
lager:info("Error Request from map: [~p]~n", [Request]),
Request;
-request_from_map(#{command := Command, session_id := SessionId,
- raw_frame := RawFrame, headers:=Headers, cl_trid := ClTRID}) ->
+request_from_map(#{command := Command,
+ session_id := SessionId, raw_frame := RawFrame,
+ headers := Headers, cl_trid := ClTRID}) ->
URL = epp_router:route_request(Command),
RequestMethod = epp_router:request_method(Command),
- Cookie = hackney_cookie:setcookie("session", SessionId, []),
+ Cookie = hackney_cookie:setcookie("session", SessionId,
+ []),
Body = request_body(Command, RawFrame, ClTRID),
- Headers=Headers,
- Request = #epp_request{url=URL,
- method=RequestMethod,
- body=Body,
- cookies=[Cookie],
- headers=Headers},
+ Headers = Headers,
+ Request = #epp_request{url = URL,
+ method = RequestMethod, body = Body,
+ cookies = [Cookie], headers = Headers},
lager:info("Request from map: [~p]~n", [Request]),
Request;
-request_from_map(#{command := Command, session_id := SessionId,
- raw_frame := RawFrame, common_name := CommonName,
- client_cert := ClientCert, peer_ip := PeerIp, cl_trid := ClTRID}) ->
+request_from_map(#{command := Command,
+ session_id := SessionId, raw_frame := RawFrame,
+ common_name := CommonName, client_cert := ClientCert,
+ peer_ip := PeerIp, cl_trid := ClTRID}) ->
URL = epp_router:route_request(Command),
RequestMethod = epp_router:request_method(Command),
- Cookie = hackney_cookie:setcookie("session", SessionId, []),
+ Cookie = hackney_cookie:setcookie("session", SessionId,
+ []),
Body = request_body(Command, RawFrame, ClTRID),
Headers = [{"SSL_CLIENT_CERT", ClientCert},
{"SSL_CLIENT_S_DN_CN", CommonName},
{"User-Agent", <<"EPP proxy">>},
{"X-Forwarded-for", epp_util:readable_ip(PeerIp)}],
- Request = #epp_request{url=URL,
- method=RequestMethod,
- body=Body,
- cookies=[Cookie],
- headers=Headers},
+ Request = #epp_request{url = URL,
+ method = RequestMethod, body = Body,
+ cookies = [Cookie], headers = Headers},
lager:info("Request from map: [~p]~n", [Request]),
Request.
%% Return form data or an empty list.
-request_body("hello", _, _) ->
- "";
+request_body("hello", _, _) -> "";
request_body(_Command, RawFrame, nomatch) ->
{multipart, [{<<"raw_frame">>, RawFrame}]};
request_body(_Command, RawFrame, ClTRID) ->
- {multipart, [{<<"raw_frame">>, RawFrame}, {<<"clTRID">>, ClTRID}]}.
+ {multipart,
+ [{<<"raw_frame">>, RawFrame}, {<<"clTRID">>, ClTRID}]}.
query_params(Code, Message, nomatch) ->
[{<<"code">>, Code}, {<<"msg">>, Message}];
query_params(Code, Message, ClTRID) ->
- [{<<"code">>, Code}, {<<"msg">>, Message}, {<<"clTRID">>, ClTRID}].
+ [{<<"code">>, Code}, {<<"msg">>, Message},
+ {<<"clTRID">>, ClTRID}].
%% Log critical information about a request that failed, and then
%% return a canned response with internal error status.
log_and_return_canned(Error, Request) ->
lager:alert("Registry cannot be reached!"),
- lager:alert("Error contacting registry: [~p, ~p]~n", [Error, Request]),
+ lager:alert("Error contacting registry: [~p, ~p]~n",
+ [Error, Request]),
{2400, canned_response()}.
%% In case registry is not accessible, return this response.
%% In the future, this should be configurable.
canned_response() ->
- <<"
-
-
-
- Internal server error.
-
-
-">>.
+ <<"\n<"
+ "epp xmlns=\"https://epp.tld.ee/schema/epp-ee-"
+ "1.0.xsd\" xmlns:xsi=\"http://www.w3.org/2001/"
+ "XMLSchema-instance\" xsi:schemaLocation=\"lib"
+ "/schemas/epp-ee-1.0.xsd\">\n \n "
+ " \n Internal server error.\n "
+ " \n \n">>.
diff --git a/apps/epp_proxy/src/epp_http_client_behaviour.erl b/apps/epp_proxy/src/epp_http_client_behaviour.erl
index b8980e1..b659bf1 100644
--- a/apps/epp_proxy/src/epp_http_client_behaviour.erl
+++ b/apps/epp_proxy/src/epp_http_client_behaviour.erl
@@ -7,5 +7,9 @@
%% Abstract module for http client behaviour. It should call EPP HTTP server
%% and return a response back to the caller.
-callback request(epp_request()) -> http_response().
--callback error_request(epp_error_request()) -> http_response().
--callback request_builder(map()) -> epp_request() | epp_error_request().
+
+-callback
+error_request(epp_error_request()) -> http_response().
+
+-callback request_builder(map()) -> epp_request() |
+ epp_error_request().
diff --git a/apps/epp_proxy/src/epp_pool_supervisor.erl b/apps/epp_proxy/src/epp_pool_supervisor.erl
index 0b6100a..c2d1077 100644
--- a/apps/epp_proxy/src/epp_pool_supervisor.erl
+++ b/apps/epp_proxy/src/epp_pool_supervisor.erl
@@ -12,5 +12,6 @@ start_link() ->
supervisor:start_link({local, ?SERVER}, ?MODULE, []).
init([]) ->
- SupFlags = #{strategy => one_for_one, intensity => 3, period => 60},
+ SupFlags = #{strategy => one_for_one, intensity => 3,
+ period => 60},
{ok, {SupFlags, []}}.
diff --git a/apps/epp_proxy/src/epp_proxy_app.erl b/apps/epp_proxy/src/epp_proxy_app.erl
index 6c07e47..8d25864 100644
--- a/apps/epp_proxy/src/epp_proxy_app.erl
+++ b/apps/epp_proxy/src/epp_proxy_app.erl
@@ -18,9 +18,9 @@ start(_StartType, _StartArgs) ->
epp_proxy_sup:start_link().
%%--------------------------------------------------------------------
-stop(_State) ->
- ok.
+stop(_State) -> ok.
%%====================================================================
%% Internal functions
%%====================================================================
+
diff --git a/apps/epp_proxy/src/epp_proxy_sup.erl b/apps/epp_proxy/src/epp_proxy_sup.erl
index a8c7bfe..74b0618 100644
--- a/apps/epp_proxy/src/epp_proxy_sup.erl
+++ b/apps/epp_proxy/src/epp_proxy_sup.erl
@@ -14,19 +14,21 @@
-export([init/1]).
-define(SERVER, ?MODULE).
--define(DevMode, application:get_env(epp_proxy, dev_mode)).
+
+-define(DevMode,
+ application:get_env(epp_proxy, dev_mode)).
+
-define(TCPPort,
case application:get_env(epp_proxy, tcp_port) of
undefined -> undefined;
{ok, Value} -> Value
- end).
+ end).
-define(TLSPort,
case application:get_env(epp_proxy, tls_port) of
undefined -> undefined;
{ok, Val} -> Val
- end).
-
+ end).
%%====================================================================
%% API functions
@@ -44,25 +46,25 @@ start_link() ->
%% Before OTP 18 tuples must be used to specify a child. e.g.
%% Child :: {Id,StartFunc,Restart,Shutdown,Type,Modules}
init([]) ->
- SupFlags = #{strategy => one_for_one, intensity => 3, period => 60},
- TCPAcceptor = #{id => epp_tcp_acceptor,
- type => worker,
- modules => [epp_tcp_acceptor],
- start => {epp_tcp_acceptor, start_link, [?TCPPort]}},
- TLSAcceptor = #{id => epp_tls_acceptor,
- type => worker,
- modules => [epp_tls_acceptor],
- start => {epp_tls_acceptor, start_link, [?TLSPort]}},
+ SupFlags = #{strategy => one_for_one, intensity => 3,
+ period => 60},
+ TCPAcceptor = #{id => epp_tcp_acceptor, type => worker,
+ modules => [epp_tcp_acceptor],
+ start => {epp_tcp_acceptor, start_link, [?TCPPort]}},
+ TLSAcceptor = #{id => epp_tls_acceptor, type => worker,
+ modules => [epp_tls_acceptor],
+ start => {epp_tls_acceptor, start_link, [?TLSPort]}},
PoolSupervisor = #{id => epp_pool_supervisor,
- type => supervisor,
- modules => [epp_pool_supervisor],
- start => {epp_pool_supervisor, start_link, []}},
+ type => supervisor, modules => [epp_pool_supervisor],
+ start => {epp_pool_supervisor, start_link, []}},
ChildrenSpec = case ?DevMode of
- {ok, true} -> [TCPAcceptor, TLSAcceptor, PoolSupervisor];
- _ -> [TLSAcceptor, PoolSupervisor]
- end,
+ {ok, true} ->
+ [TCPAcceptor, TLSAcceptor, PoolSupervisor];
+ _ -> [TLSAcceptor, PoolSupervisor]
+ end,
{ok, {SupFlags, ChildrenSpec}}.
%%====================================================================
%% Internal functions
%%====================================================================
+
diff --git a/apps/epp_proxy/src/epp_router.erl b/apps/epp_proxy/src/epp_router.erl
index 85de405..34e4032 100644
--- a/apps/epp_proxy/src/epp_router.erl
+++ b/apps/epp_proxy/src/epp_router.erl
@@ -1,53 +1,71 @@
-module(epp_router).
--export([route_request/1, request_method/1]).
+-export([request_method/1, route_request/1]).
--define(validCommands, ["hello", "login", "logout", "check", "info", "poll",
- "create", "delete", "renew", "update", "transfer"]).
+-define(validCommands,
+ ["hello", "login", "logout", "check", "info", "poll",
+ "create", "delete", "renew", "update", "transfer"]).
%% 47 is the character code
-define(forwardSlash, 47).
%% request method: GET for greeting, POST for everything else.
-request_method("hello") ->
- get;
-request_method(<<"hello">>) ->
- get;
-request_method("error") ->
- get;
-request_method(<<"error">>) ->
- get;
-request_method(_) ->
- post.
+request_method("hello") -> get;
+request_method(<<"hello">>) -> get;
+request_method("error") -> get;
+request_method(<<"error">>) -> get;
+request_method(_) -> post.
%% Base router
route_request(Command) when is_binary(Command) ->
- List = binary_to_list(Command),
- url_map(List);
-route_request(Command) when is_list(Command) -> url_map(Command).
+ List = binary_to_list(Command), url_map(List);
+route_request(Command) when is_list(Command) ->
+ url_map(Command).
%% Actually route to places
url_map(Command) when is_list(Command) ->
case Command of
%% Session commands
- "hello" -> unicode:characters_to_list([base_session_url(), Command]);
- "login" -> unicode:characters_to_list([base_session_url(), Command]);
- "logout" -> unicode:characters_to_list([base_session_url(), Command]);
+ "hello" ->
+ unicode:characters_to_list([base_session_url(),
+ Command]);
+ "login" ->
+ unicode:characters_to_list([base_session_url(),
+ Command]);
+ "logout" ->
+ unicode:characters_to_list([base_session_url(),
+ Command]);
%% Poll commands
- "check" -> unicode:characters_to_list([base_command_url(), Command]);
- "info" -> unicode:characters_to_list([base_command_url(), Command]);
- "poll" -> unicode:characters_to_list([base_command_url(), Command]);
+ "check" ->
+ unicode:characters_to_list([base_command_url(),
+ Command]);
+ "info" ->
+ unicode:characters_to_list([base_command_url(),
+ Command]);
+ "poll" ->
+ unicode:characters_to_list([base_command_url(),
+ Command]);
%% Transform commands
- "create" -> unicode:characters_to_list([base_command_url(), Command]);
- "delete" -> unicode:characters_to_list([base_command_url(), Command]);
- "renew" -> unicode:characters_to_list([base_command_url(), Command]);
- "update" -> unicode:characters_to_list([base_command_url(), Command]);
- % Transfer is both poll and query
- "transfer" -> unicode:characters_to_list([base_command_url(), Command]);
- % Error route
- "error" -> base_error_url()
- % Anything else should fail.
- end.
+ "create" ->
+ unicode:characters_to_list([base_command_url(),
+ Command]);
+ "delete" ->
+ unicode:characters_to_list([base_command_url(),
+ Command]);
+ "renew" ->
+ unicode:characters_to_list([base_command_url(),
+ Command]);
+ "update" ->
+ unicode:characters_to_list([base_command_url(),
+ Command]);
+ % Transfer is both poll and query
+ "transfer" ->
+ unicode:characters_to_list([base_command_url(),
+ Command]);
+ % Error route
+ "error" ->
+ base_error_url() % Anything else should fail.
+ end.
%% This allows the person who configures proxy to not care about trailing
%% slashes in HTTP.
@@ -62,8 +80,8 @@ appendable_route(Route) ->
parametrizable_route(Route) ->
case lists:last(Route) of
?forwardSlash -> lists:droplast(Route);
- _ -> Route
- end.
+ _ -> Route
+ end.
%% Every time a request is made, this will go to ETS to check what's the route,
%% But that is fast enough to not be noticed by anyone.
diff --git a/apps/epp_proxy/src/epp_tcp_acceptor.erl b/apps/epp_proxy/src/epp_tcp_acceptor.erl
index cbe0016..996c490 100644
--- a/apps/epp_proxy/src/epp_tcp_acceptor.erl
+++ b/apps/epp_proxy/src/epp_tcp_acceptor.erl
@@ -6,45 +6,50 @@
-module(epp_tcp_acceptor).
-behaviour(gen_server).
+
-define(SERVER, ?MODULE).
+
-define(POOL_SUPERVISOR, epp_pool_supervisor).
+
-define(WORKER, epp_tcp_worker).
%% gen_server callbacks
--export([init/1, handle_cast/2, handle_call/3, start_link/1]).
+-export([handle_call/3, handle_cast/2, init/1,
+ start_link/1]).
-record(state, {socket, port, options}).
start_link(Port) ->
- gen_server:start_link({local, ?SERVER}, ?MODULE, Port, []).
+ gen_server:start_link({local, ?SERVER}, ?MODULE, Port,
+ []).
init(Port) ->
- Options = [binary,
- {packet, raw},
- {active, false},
+ Options = [binary, {packet, raw}, {active, false},
{reuseaddr, true}],
-
{ok, ListenSocket} = gen_tcp:listen(Port, Options),
gen_server:cast(self(), accept),
-
- {ok, #state{socket=ListenSocket, port=Port, options=Options}}.
+ {ok,
+ #state{socket = ListenSocket, port = Port,
+ options = Options}}.
handle_cast(accept,
- State = #state{socket=ListenSocket, port=Port, options=Options}) ->
+ State = #state{socket = ListenSocket, port = Port,
+ options = Options}) ->
{ok, AcceptSocket} = gen_tcp:accept(ListenSocket),
{ok, NewOwner} = create_worker(AcceptSocket),
- ok = gen_tcp:controlling_process(AcceptSocket, NewOwner),
+ ok = gen_tcp:controlling_process(AcceptSocket,
+ NewOwner),
gen_server:cast(NewOwner, serve),
gen_server:cast(NewOwner, greeting),
gen_server:cast(self(), accept),
- {noreply, State#state{socket=ListenSocket, port=Port, options=Options}}.
+ {noreply,
+ State#state{socket = ListenSocket, port = Port,
+ options = Options}}.
handle_call(_E, _From, State) -> {noreply, State}.
create_worker(Socket) ->
- ChildSpec = #{id => rand:uniform(),
- type => worker,
- modules => [?WORKER],
- restart => temporary,
- start => {?WORKER, start_link, [Socket]}},
+ ChildSpec = #{id => rand:uniform(), type => worker,
+ modules => [?WORKER], restart => temporary,
+ start => {?WORKER, start_link, [Socket]}},
supervisor:start_child(?POOL_SUPERVISOR, ChildSpec).
diff --git a/apps/epp_proxy/src/epp_tcp_worker.erl b/apps/epp_proxy/src/epp_tcp_worker.erl
index 2fde5dc..7ee0267 100644
--- a/apps/epp_proxy/src/epp_tcp_worker.erl
+++ b/apps/epp_proxy/src/epp_tcp_worker.erl
@@ -1,25 +1,25 @@
-module(epp_tcp_worker).
-behaviour(gen_server).
+
-define(SERVER, ?MODULE).
-include("epp_proxy.hrl").
%% gen_server callbacks
--export([init/1, handle_cast/2, handle_call/3, start_link/1]).
+-export([handle_call/3, handle_cast/2, init/1,
+ start_link/1]).
+
-export([code_change/3]).
--record(valid_frame, {command,
- cl_trid,
- raw_frame}).
--record(invalid_frame, {code,
- cl_trid,
- message}).
--record(state, {socket,
- session_id,
- headers }).
+-record(valid_frame, {command, cl_trid, raw_frame}).
+
+-record(invalid_frame, {code, cl_trid, message}).
+
+-record(state, {socket, session_id, headers}).
-define(XMLErrorCode, <<"2001">>).
+
-define(XMLErrorMessage, <<"Command syntax error.">>).
%% Initialize process
@@ -27,7 +27,7 @@
init(Socket) ->
lager:info("Created a worker process: [~p]", [self()]),
SessionId = epp_util:session_id(self()),
- {ok, #state{socket=Socket, session_id=SessionId}}.
+ {ok, #state{socket = Socket, session_id = SessionId}}.
start_link(Socket) ->
gen_server:start_link(?MODULE, Socket, []).
@@ -36,32 +36,28 @@ start_link(Socket) ->
%% Gather data that we use a headers for
%% http request:
%% Client IP address
-handle_cast(serve, State = #state{socket=Socket}) ->
+handle_cast(serve, State = #state{socket = Socket}) ->
NewState = state_from_socket(Socket, State),
{noreply, NewState};
-
%% Step two:
%% Using the state of the connection, get the hello route from http server.
%% Send the response from HTTP server back to EPP client.
%% When this succeeds, send "process_command" to self and await further
%% commands.
-handle_cast(greeting, State = #state{socket=Socket,
- session_id=SessionId,
- headers=Headers}) ->
-
-
- Request = epp_http_client:request_builder(#{command => "hello",
+handle_cast(greeting,
+ State = #state{socket = Socket, session_id = SessionId,
+ headers = Headers}) ->
+ Request = epp_http_client:request_builder(#{command =>
+ "hello",
session_id => SessionId,
raw_frame => "",
headers => Headers,
cl_trid => nomatch}),
-
{_Status, Body} = epp_http_client:request(Request),
-
frame_to_socket(Body, Socket),
gen_server:cast(self(), process_command),
- {noreply, State#state{socket=Socket, session_id=SessionId}};
-
+ {noreply,
+ State#state{socket = Socket, session_id = SessionId}};
%% Step three to N:
%% Await input from client. Parse it, and perform an appropriate http request.
%% Commands go to commands, invalid XML goes to error.
@@ -72,44 +68,44 @@ handle_cast(greeting, State = #state{socket=Socket,
%%
%% Otherwise send "process_command" again to self to repeat the process.
handle_cast(process_command,
- State = #state{socket=Socket,session_id=SessionId,
- headers=Headers}) ->
+ State = #state{socket = Socket, session_id = SessionId,
+ headers = Headers}) ->
RawFrame = frame_from_socket(Socket, State),
-
case parse_frame(RawFrame) of
- #valid_frame{command=Command, cl_trid=ClTRID} ->
- Request = epp_http_client:request_builder(#{command => Command,
+ #valid_frame{command = Command, cl_trid = ClTRID} ->
+ Request = epp_http_client:request_builder(#{command =>
+ Command,
session_id => SessionId,
raw_frame => RawFrame,
headers => Headers,
cl_trid => ClTRID}),
-
{_Status, Body} = epp_http_client:request(Request);
- #invalid_frame{message=Message, code=Code, cl_trid=ClTRID} ->
+ #invalid_frame{message = Message, code = Code,
+ cl_trid = ClTRID} ->
Command = "error",
- Request = epp_http_client:request_builder(#{command => Command,
+ Request = epp_http_client:request_builder(#{command =>
+ Command,
session_id => SessionId,
headers => Headers,
code => Code,
message => Message,
cl_trid => ClTRID}),
{_Status, Body} = epp_http_client:error_request(Request)
- end,
-
+ end,
frame_to_socket(Body, Socket),
-
%% On logout, close the socket.
%% Else, go back to the beginning of the loop.
- if
- Command =:= "logout" ->
+ if Command =:= "logout" ->
ok = gen_tcp:shutdown(Socket, read_write),
{stop, normal, State};
- true ->
+ true ->
gen_server:cast(self(), process_command),
- {noreply, State#state{socket=Socket, session_id=SessionId}}
+ {noreply,
+ State#state{socket = Socket, session_id = SessionId}}
end.
handle_call(_E, _From, State) -> {noreply, State}.
+
code_change(_OldVersion, State, _Extra) -> {ok, State}.
%% Private function
@@ -120,54 +116,49 @@ read_length(Socket) ->
case gen_tcp:recv(Socket, 4) of
{ok, Data} ->
Length = binary:decode_unsigned(Data, big),
- LengthToReceive = epp_util:frame_length_to_receive(Length),
+ LengthToReceive =
+ epp_util:frame_length_to_receive(Length),
{ok, LengthToReceive};
{error, Reason} ->
- io:format("Error: ~p~n", [Reason]),
- {error, Reason}
+ io:format("Error: ~p~n", [Reason]), {error, Reason}
end.
read_frame(Socket, FrameLength) ->
case gen_tcp:recv(Socket, FrameLength) of
- {ok, Data} ->
- {ok, Data};
+ {ok, Data} -> {ok, Data};
{error, Reason} ->
- io:format("Error: ~p~n", [Reason]),
- {error, Reason}
+ io:format("Error: ~p~n", [Reason]), {error, Reason}
end.
%% Wrap a message in EPP frame, and then send it to socket.
frame_to_socket(Message, Socket) ->
Length = epp_util:frame_length_to_send(Message),
- ByteSize = << Length:32/big >>,
+ ByteSize = <>,
write_line(Socket, ByteSize),
write_line(Socket, Message).
%% Extract state info from socket. Fail if you must.
state_from_socket(Socket, State) ->
- {ok, {PeerIp, _PeerPort}} = inet:peername(Socket),
+ {ok, {PeerIp, _PeerPort}} = inet:peername(Socket),
Headers = [{"User-Agent", <<"EPP proxy">>},
{"X-Forwarded-for", epp_util:readable_ip(PeerIp)}],
- NewState = State#state{socket=Socket, headers=Headers},
- lager:info("Established connection with: [~p]~n", [NewState]),
+ NewState = State#state{socket = Socket,
+ headers = Headers},
+ lager:info("Established connection with: [~p]~n",
+ [NewState]),
NewState.
%% First, listen for 4 bytes, then listen until the declared length.
%% Return the frame binary at the very end.
frame_from_socket(Socket, State) ->
Length = case read_length(Socket) of
- {ok, Data} ->
- Data;
- {error, _Details} ->
- {stop, normal, State}
- end,
-
+ {ok, Data} -> Data;
+ {error, _Details} -> {stop, normal, State}
+ end,
Frame = case read_frame(Socket, Length) of
- {ok, FrameData} ->
- FrameData;
- {error, _FrameDetails} ->
- {stop, normal, State}
- end,
+ {ok, FrameData} -> FrameData;
+ {error, _FrameDetails} -> {stop, normal, State}
+ end,
Frame.
%% Get status, XML record, command and clTRID if defined.
@@ -177,11 +168,9 @@ parse_frame(Frame) ->
case epp_xml:parse(Frame) of
{ok, XMLRecord} ->
Command = epp_xml:get_command(XMLRecord),
- #valid_frame{command=Command,
- cl_trid=ClTRID,
- raw_frame=Frame};
+ #valid_frame{command = Command, cl_trid = ClTRID,
+ raw_frame = Frame};
{error, _} ->
- #invalid_frame{code=?XMLErrorCode,
- message=?XMLErrorMessage,
- cl_trid=ClTRID}
- end.
+ #invalid_frame{code = ?XMLErrorCode,
+ message = ?XMLErrorMessage, cl_trid = ClTRID}
+ end.
diff --git a/apps/epp_proxy/src/epp_tls_acceptor.erl b/apps/epp_proxy/src/epp_tls_acceptor.erl
index f2b3be8..1d9bffd 100644
--- a/apps/epp_proxy/src/epp_tls_acceptor.erl
+++ b/apps/epp_proxy/src/epp_tls_acceptor.erl
@@ -3,39 +3,36 @@
-behaviour(gen_server).
-define(SERVER, ?MODULE).
+
-define(POOL_SUPERVISOR, epp_pool_supervisor).
+
-define(WORKER, epp_tls_worker).
%% gen_server callbacks
--export([init/1, handle_cast/2, handle_call/3, start_link/1]).
+-export([handle_call/3, handle_cast/2, init/1,
+ start_link/1]).
-export([crl_file/0]).
-record(state, {socket, port, options}).
start_link(Port) ->
- gen_server:start_link({local, ?SERVER}, ?MODULE, Port, []).
+ gen_server:start_link({local, ?SERVER}, ?MODULE, Port,
+ []).
init(Port) ->
- Options = [binary,
- {packet, raw},
- {active, false},
- {reuseaddr, true},
- {verify, verify_peer},
- {depth, 1},
- {cacertfile, ca_cert_file()},
- {certfile, cert_file()},
- {keyfile, key_file()},
- {crl_check, peer},
- {crl_cache, {ssl_crl_cache, {internal, [{http, 5000}]}}}],
-
+ Options = [binary, {packet, raw}, {active, false},
+ {reuseaddr, true}, {verify, verify_peer}, {depth, 1},
+ {cacertfile, ca_cert_file()}, {certfile, cert_file()},
+ {keyfile, key_file()}, {crl_check, peer},
+ {crl_cache,
+ {ssl_crl_cache, {internal, [{http, 5000}]}}}],
ssl_crl_cache:insert({file, crl_file()}),
-
{ok, ListenSocket} = ssl:listen(Port, Options),
gen_server:cast(self(), accept),
-
- {ok, #state{socket=ListenSocket, port=Port, options=Options}}.
-
+ {ok,
+ #state{socket = ListenSocket, port = Port,
+ options = Options}}.
%% Acceptor has only one state that goes in a loop:
%% 1. Listen for a connection from anyone.
@@ -43,25 +40,27 @@ init(Port) ->
%% 3. Pass the connection to the worker and make it a controlling process for
%% the socket.
%% 4. Go back to listening.
-handle_cast(accept, State = #state{socket=ListenSocket, port=Port, options=Options}) ->
+handle_cast(accept,
+ State = #state{socket = ListenSocket, port = Port,
+ options = Options}) ->
{ok, AcceptSocket} = ssl:transport_accept(ListenSocket),
{ok, NewOwner} = create_worker(AcceptSocket),
ok = ssl:controlling_process(AcceptSocket, NewOwner),
gen_server:cast(NewOwner, serve),
gen_server:cast(NewOwner, greeting),
gen_server:cast(self(), accept),
- {noreply, State#state{socket=ListenSocket, port=Port, options=Options}}.
+ {noreply,
+ State#state{socket = ListenSocket, port = Port,
+ options = Options}}.
handle_call(_E, _From, State) -> {noreply, State}.
%% Create a worker process. These are short lived and should not be restarted,
%% but for the purpose of order we should put them in a supervision tree.
create_worker(Socket) ->
- ChildSpec = #{id => rand:uniform(),
- type => worker,
- modules => [?WORKER],
- restart => temporary,
- start => {?WORKER, start_link, [Socket]}},
+ ChildSpec = #{id => rand:uniform(), type => worker,
+ modules => [?WORKER], restart => temporary,
+ start => {?WORKER, start_link, [Socket]}},
supervisor:start_child(?POOL_SUPERVISOR, ChildSpec).
%% Private functions for returning paths to files. It costs almost nothing
diff --git a/apps/epp_proxy/src/epp_tls_worker.erl b/apps/epp_proxy/src/epp_tls_worker.erl
index 49bb43b..4cbdd1b 100644
--- a/apps/epp_proxy/src/epp_tls_worker.erl
+++ b/apps/epp_proxy/src/epp_tls_worker.erl
@@ -1,25 +1,25 @@
-module(epp_tls_worker).
-behaviour(gen_server).
+
-define(SERVER, ?MODULE).
-include("epp_proxy.hrl").
%% gen_server callbacks
--export([init/1, handle_cast/2, handle_call/3, start_link/1]).
+-export([handle_call/3, handle_cast/2, init/1,
+ start_link/1]).
+
-export([code_change/3]).
--record(valid_frame, {command,
- cl_trid,
- raw_frame}).
--record(invalid_frame, {code,
- cl_trid,
- message}).
--record(state, {socket,
- session_id,
- headers }).
+-record(valid_frame, {command, cl_trid, raw_frame}).
+
+-record(invalid_frame, {code, cl_trid, message}).
+
+-record(state, {socket, session_id, headers}).
-define(XMLErrorCode, <<"2001">>).
+
-define(XMLErrorMessage, <<"Command syntax error.">>).
%% Initialize process
@@ -27,7 +27,7 @@
init(Socket) ->
lager:info("Created a worker process: [~p]", [self()]),
SessionId = epp_util:session_id(self()),
- {ok, #state{socket=Socket, session_id=SessionId}}.
+ {ok, #state{socket = Socket, session_id = SessionId}}.
start_link(Socket) ->
gen_server:start_link(?MODULE, Socket, []).
@@ -35,37 +35,33 @@ start_link(Socket) ->
%% First step after spinning off the process:
%% Perform an TLS handshake and gather data that we use a headers for
%% http request:
-%% Common name
-%% Client certificate
-%% Client IP address
+%% Common name,
+%% Client certificate,
+%% Client IP address,
%% If certificate is revoked, this will fail right away here.
%% mod_epp does exactly the same thing.
-handle_cast(serve, State = #state{socket=Socket}) ->
+handle_cast(serve, State = #state{socket = Socket}) ->
{ok, SecureSocket} = ssl:handshake(Socket),
NewState = state_from_socket(SecureSocket, State),
{noreply, NewState};
-
-%% Step two:
-%% Using the state of the connection, get the hello route from http server.
-%% Send the response from HTTP server back to EPP client.
-%% When this succeeds, send "process_command" to self and await further
-%% commands.
-handle_cast(greeting, State = #state{socket=Socket,
- session_id=SessionId,
- headers=Headers}) ->
-
- Request = epp_http_client:request_builder(#{command => "hello",
+%% Step two: Using the state of the connection, get the hello route
+%% from http server. Send the response from HTTP server back to EPP
+%% client. When this succeeds, send "process_command" to self and
+%% await further commands.
+handle_cast(greeting,
+ State = #state{socket = Socket, session_id = SessionId,
+ headers = Headers}) ->
+ Request = epp_http_client:request_builder(#{command =>
+ "hello",
session_id => SessionId,
raw_frame => "",
headers => Headers,
cl_trid => nomatch}),
-
{_Status, Body} = epp_http_client:request(Request),
-
frame_to_socket(Body, Socket),
gen_server:cast(self(), process_command),
- {noreply, State#state{socket=Socket, session_id=SessionId}};
-
+ {noreply,
+ State#state{socket = Socket, session_id = SessionId}};
%% Step three to N:
%% Await input from client. Parse it, and perform an appropriate http request.
%% Commands go to commands, invalid XML goes to error.
@@ -76,44 +72,44 @@ handle_cast(greeting, State = #state{socket=Socket,
%%
%% Otherwise send "process_command" again to self to repeat the process.
handle_cast(process_command,
- State = #state{socket=Socket,session_id=SessionId,
- headers=Headers}) ->
+ State = #state{socket = Socket, session_id = SessionId,
+ headers = Headers}) ->
RawFrame = frame_from_socket(Socket, State),
-
case parse_frame(RawFrame) of
- #valid_frame{command=Command, cl_trid=ClTRID} ->
- Request = epp_http_client:request_builder(#{command => Command,
+ #valid_frame{command = Command, cl_trid = ClTRID} ->
+ Request = epp_http_client:request_builder(#{command =>
+ Command,
session_id => SessionId,
raw_frame => RawFrame,
headers => Headers,
cl_trid => ClTRID}),
-
{_Status, Body} = epp_http_client:request(Request);
- #invalid_frame{message=Message, code=Code, cl_trid=ClTRID} ->
+ #invalid_frame{message = Message, code = Code,
+ cl_trid = ClTRID} ->
Command = "error",
- Request = epp_http_client:request_builder(#{command => Command,
+ Request = epp_http_client:request_builder(#{command =>
+ Command,
session_id => SessionId,
headers => Headers,
code => Code,
message => Message,
cl_trid => ClTRID}),
{_Status, Body} = epp_http_client:error_request(Request)
- end,
-
+ end,
frame_to_socket(Body, Socket),
-
%% On logout, close the socket.
%% Else, go back to the beginning of the loop.
- if
- Command =:= "logout" ->
+ if Command =:= "logout" ->
ok = ssl:shutdown(Socket, read_write),
{stop, normal, State};
- true ->
+ true ->
gen_server:cast(self(), process_command),
- {noreply, State#state{socket=Socket, session_id=SessionId}}
+ {noreply,
+ State#state{socket = Socket, session_id = SessionId}}
end.
handle_call(_E, _From, State) -> {noreply, State}.
+
code_change(_OldVersion, State, _Extra) -> {ok, State}.
%% Private functions
@@ -121,47 +117,39 @@ read_length(Socket) ->
case ssl:recv(Socket, 4) of
{ok, Data} ->
Length = binary:decode_unsigned(Data, big),
- LengthToReceive = epp_util:frame_length_to_receive(Length),
+ LengthToReceive =
+ epp_util:frame_length_to_receive(Length),
{ok, LengthToReceive};
- {error, Reason} ->
- {error, Reason}
+ {error, Reason} -> {error, Reason}
end.
read_frame(Socket, FrameLength) ->
case ssl:recv(Socket, FrameLength) of
- {ok, Data} ->
- {ok, Data};
- {error, Reason} ->
- {error, Reason}
+ {ok, Data} -> {ok, Data};
+ {error, Reason} -> {error, Reason}
end.
%% Wrap a message in EPP frame, and then send it to socket.
frame_to_socket(Message, Socket) ->
Length = epp_util:frame_length_to_send(Message),
- ByteSize = << Length:32/big >>,
+ ByteSize = <>,
write_line(Socket, ByteSize),
write_line(Socket, Message).
-write_line(Socket, Line) ->
- ok = ssl:send(Socket, Line).
+write_line(Socket, Line) -> ok = ssl:send(Socket, Line).
%% First, listen for 4 bytes, then listen until the declared length.
%% Return the frame binary at the very end.
%% If the client closes connection abruptly, then kill the process
frame_from_socket(Socket, State) ->
Length = case read_length(Socket) of
- {ok, Data} ->
- Data;
- {error, closed} ->
- log_and_exit(State)
- end,
-
+ {ok, Data} -> Data;
+ {error, closed} -> log_and_exit(State)
+ end,
Frame = case read_frame(Socket, Length) of
- {ok, FrameData} ->
- FrameData;
- {error, closed} ->
- log_and_exit(State)
- end,
+ {ok, FrameData} -> FrameData;
+ {error, closed} -> log_and_exit(State)
+ end,
Frame.
log_and_exit(State) ->
@@ -171,15 +159,17 @@ log_and_exit(State) ->
%% Extract state info from socket. Fail if you must.
state_from_socket(Socket, State) ->
{ok, PeerCert} = ssl:peercert(Socket),
- {ok, {PeerIp, _PeerPort}} = ssl:peername(Socket),
+ {ok, {PeerIp, _PeerPort}} = ssl:peername(Socket),
{SSL_CLIENT_S_DN_CN, SSL_CLIENT_CERT} =
epp_certs:headers_from_cert(PeerCert),
Headers = [{"SSL-CLIENT-CERT", SSL_CLIENT_CERT},
{"SSL-CLIENT-S-DN-CN", SSL_CLIENT_S_DN_CN},
{"User-Agent", <<"EPP proxy">>},
{"X-Forwarded-for", epp_util:readable_ip(PeerIp)}],
- NewState = State#state{socket=Socket, headers=Headers},
- lager:info("Established connection with: [~p]~n", [NewState]),
+ NewState = State#state{socket = Socket,
+ headers = Headers},
+ lager:info("Established connection with: [~p]~n",
+ [NewState]),
NewState.
%% Get status, XML record, command and clTRID if defined.
@@ -189,11 +179,9 @@ parse_frame(Frame) ->
case epp_xml:parse(Frame) of
{ok, XMLRecord} ->
Command = epp_xml:get_command(XMLRecord),
- #valid_frame{command=Command,
- cl_trid=ClTRID,
- raw_frame=Frame};
+ #valid_frame{command = Command, cl_trid = ClTRID,
+ raw_frame = Frame};
{error, _} ->
- #invalid_frame{code=?XMLErrorCode,
- message=?XMLErrorMessage,
- cl_trid=ClTRID}
- end.
+ #invalid_frame{code = ?XMLErrorCode,
+ message = ?XMLErrorMessage, cl_trid = ClTRID}
+ end.
diff --git a/apps/epp_proxy/src/epp_util.erl b/apps/epp_proxy/src/epp_util.erl
index 1442f44..443ad7e 100644
--- a/apps/epp_proxy/src/epp_util.erl
+++ b/apps/epp_proxy/src/epp_util.erl
@@ -1,21 +1,23 @@
-module(epp_util).
--export([create_map/1, create_session_id/1, frame_length/1,
- frame_length_to_receive/1, frame_length_to_send/1,
- session_id/1, readable_ip/1]).
+-export([create_map/1, create_session_id/1,
+ frame_length/1, frame_length_to_receive/1,
+ frame_length_to_send/1, readable_ip/1, session_id/1]).
-define(OFFSET, 4).
%% Given a pid, return a sha512 hash of unique attributes.
--spec session_id(pid()) -> list(char()).
+-spec session_id(pid()) -> [char()].
+
session_id(Pid) ->
UniqueMap = create_map(Pid),
BinaryHash = create_session_id(UniqueMap),
BinaryHash.
%% Give me a process id, I'll create a random map for you.
--spec create_map(pid()) -> #{string() => pid(), string() => float(),
- string() => string()}.
+-spec create_map(pid()) -> #{string() => pid(),
+ string() => float(), string() => string()}.
+
create_map(Pid) when is_pid(Pid) ->
Now = erlang:system_time(second),
#{"pid" => Pid, "random" => rand:uniform(),
@@ -23,25 +25,29 @@ create_map(Pid) when is_pid(Pid) ->
%% Given the special data structure, return back a binary hash to pass to the
%% application server.
--spec create_session_id(#{string() => pid(), string() => float(),
- string() => string()}) -> list(char()).
-create_session_id(#{"pid" := Pid, "random" := Random, "timestamp" := Timestamp}) ->
- Map = #{"pid" => pid_to_list(Pid), "random" => float_to_list(Random),
+-spec create_session_id(#{string() => pid(),
+ string() => float(),
+ string() => string()}) -> [char()].
+
+create_session_id(#{"pid" := Pid, "random" := Random,
+ "timestamp" := Timestamp}) ->
+ Map = #{"pid" => pid_to_list(Pid),
+ "random" => float_to_list(Random),
"timestamp" => Timestamp},
ListOfTuples = maps:to_list(Map),
ListOfLists = [[X, ",", Y] || {X, Y} <- ListOfTuples],
- NestedList = lists:join(",",ListOfLists),
+ NestedList = lists:join(",", ListOfLists),
ListOfGlyphs = lists:flatten(NestedList),
BinaryHash = crypto:hash(sha512, ListOfGlyphs),
- String = lists:flatten([integer_to_list(X,16) || <> <= BinaryHash]),
+ String = lists:flatten([integer_to_list(X, 16)
+ || <> <= BinaryHash]),
String.
frame_length_to_receive(Size) when Size >= 0 ->
- Size - ?OFFSET.
+ Size - (?OFFSET).
frame_length_to_send(Frame) ->
- Length = frame_length(Frame),
- Length + ?OFFSET.
+ Length = frame_length(Frame), Length + (?OFFSET).
frame_length(Frame) when is_binary(Frame) ->
byte_size(Frame);
@@ -50,8 +56,11 @@ frame_length(Frame) when is_list(Frame) ->
byte_size(Bin).
%% Pass a tuple of IP address, return a binary for sending over the wire.
--spec readable_ip({integer(), integer(), integer(), integer()}) -> binary().
-readable_ip({FirstOctet, SecondOctet, ThirdOctet, FourthOctet}) ->
+-spec readable_ip({integer(), integer(), integer(),
+ integer()}) -> binary().
+
+readable_ip({FirstOctet, SecondOctet, ThirdOctet,
+ FourthOctet}) ->
List = [integer_to_list(FirstOctet), ".",
integer_to_list(SecondOctet), ".",
integer_to_list(ThirdOctet), ".",
diff --git a/apps/epp_proxy/src/epp_xml.erl b/apps/epp_proxy/src/epp_xml.erl
index 1728390..514a443 100644
--- a/apps/epp_proxy/src/epp_xml.erl
+++ b/apps/epp_proxy/src/epp_xml.erl
@@ -5,25 +5,28 @@
-include_lib("xmerl/include/xmerl.hrl").
%% Get command from an xmlElement. Otherwise return undefined.
-get_command(Record) when is_record(Record, xmlElement) ->
- case xmerl_xpath:string("name(/epp/command/*[1])", Record) of
+get_command(Record)
+ when is_record(Record, xmlElement) ->
+ case xmerl_xpath:string("name(/epp/command/*[1])",
+ Record)
+ of
{xmlObj, string, []} -> undefined;
{xmlObj, string, Command} -> Command
- end;
+ end;
get_command(_) -> undefined.
%% xml_erl expects a list of characters, so let's give it to it.
%% Otherwise return an error tuple.
parse(Text) when is_list(Text) -> parse_list(Text);
parse(Text) when is_binary(Text) ->
- List = binary_to_list(Text),
- parse_list(List);
+ List = binary_to_list(Text), parse_list(List);
parse(_) -> {error, {fatal, {expected_binary_or_list}}}.
%% Parse a record that came from the wire and return a xmlElement record.
parse_list(List) when is_list(List) ->
- try xmerl_scan:string(List, [{quiet, 'true'}]) of
- {Record, []} when is_record(Record, xmlElement) -> {ok, Record}
+ try xmerl_scan:string(List, [{quiet, true}]) of
+ {Record, []} when is_record(Record, xmlElement) ->
+ {ok, Record}
catch
exit:X -> {error, X}
end.
@@ -31,13 +34,16 @@ parse_list(List) when is_list(List) ->
%% The idea is that even when XML command is invalid,
%% we should recover cltrid from it, hence the regex use.
-spec find_cltrid(any()) -> binary() | nomatch.
+
find_cltrid(Text) when is_list(Text) -> run_regex(Text);
-find_cltrid(Text) when is_binary(Text) -> run_regex(Text);
+find_cltrid(Text) when is_binary(Text) ->
+ run_regex(Text);
find_cltrid(_) -> nomatch.
run_regex(Text) ->
- {ok, MP} = re:compile("(?.+)<\/clTRID>"),
- case re:run(Text, MP, [{capture, ["cltrid"], binary}]) of
+ {ok, MP} = re:compile("(?.+)"),
+ case re:run(Text, MP, [{capture, ["cltrid"], binary}])
+ of
{match, [Binary]} -> Binary;
nomatch -> nomatch
- end.
+ end.
diff --git a/apps/epp_proxy/test/epp_http_client_tests.erl b/apps/epp_proxy/test/epp_http_client_tests.erl
index 48e8c32..b1304ce 100644
--- a/apps/epp_proxy/test/epp_http_client_tests.erl
+++ b/apps/epp_proxy/test/epp_http_client_tests.erl
@@ -9,9 +9,9 @@ hello_request_builder_test() ->
headers => [{"User-Agent", <<"EPP proxy">>}]},
Request = epp_http_client:request_builder(RequestMap),
ExpectedTuple = {epp_request,get,"https://registry.test/epp/session/hello",
- [],
- [<<"session=Random; Version=1">>],
- [{"User-Agent",<<"EPP proxy">>}]},
+ [],
+ [<<"session=Random; Version=1">>],
+ [{"User-Agent",<<"EPP proxy">>}]},
?assert(is_record(Request, epp_request)),
?assertEqual(ExpectedTuple, Request).
@@ -38,8 +38,8 @@ command_request_builder_test() ->
ExpectedTuple = {epp_request,post,
"https://registry.test/epp/command/create",
{multipart,
- [{<<"raw_frame">>,"Some XML here"},
- {<<"clTRID">>,"EE-123456789"}]},
+ [{<<"raw_frame">>,"Some XML here"},
+ {<<"clTRID">>,"EE-123456789"}]},
[<<"session=Random; Version=1">>],
[{"User-Agent",<<"EPP proxy">>}]},
?assert(is_record(Request, epp_request)),
diff --git a/apps/epp_proxy/test/epp_xml_tests.erl b/apps/epp_proxy/test/epp_xml_tests.erl
index 17bd465..260625d 100644
--- a/apps/epp_proxy/test/epp_xml_tests.erl
+++ b/apps/epp_proxy/test/epp_xml_tests.erl
@@ -7,25 +7,25 @@
-define(sampleCommandList,
"
-
- test
- test
-
- sample1trid
-
- ").
+
+ test
+ test
+
+ sample1trid
+
+ ").
-define(validXMLNotEPPList,
"
test
- test@test.com
- ").
+ test@test.com
+ ").
%% parse
parse_not_a_list_or_binary_test() ->
- Input = 1234,
- ExpectedOutput = {error, {fatal, {expected_binary_or_list}}},
- ?assertEqual(ExpectedOutput, epp_xml:parse(Input)).
+ Input = 1234,
+ ExpectedOutput = {error, {fatal, {expected_binary_or_list}}},
+ ?assertEqual(ExpectedOutput, epp_xml:parse(Input)).
parse_sample_valid_xml_list_test() ->
Input = ?sampleCommandList,
diff --git a/rebar.config b/rebar.config
index 3550c0f..502d63f 100644
--- a/rebar.config
+++ b/rebar.config
@@ -47,3 +47,5 @@
},
{test, [{deps, [proper]}]}]
}.
+
+{plugins, [rebar3_fmt]}.