Reformat Erlang code, write more documentation

This commit is contained in:
Maciej Szlosarczyk 2019-07-11 09:17:17 +03:00
parent 558e1f0ef7
commit 771cc06232
No known key found for this signature in database
GPG key ID: 41D62D42D3B0D765
13 changed files with 323 additions and 330 deletions

View file

@ -7,7 +7,7 @@
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),

View file

@ -5,7 +5,9 @@
-behaviour(epp_http_client_behaviour).
-export([request/1, request_builder/1]).
-define(errorCommand, "error").
-define(helloCommand, "hello").
%% Callback API
@ -21,32 +23,27 @@ request_builder(Map) -> request_from_map(Map).
%% Private API
-spec handle_args(epp_request()) -> list().
%% For hello command, we ignore the payload, and send an empty body over the wire.
handle_args(#epp_request{method=get,
url = URL,
headers = Headers,
cookies = Cookies,
handle_args(#epp_request{method = get, url = URL,
headers = Headers, cookies = Cookies,
epp_verb = ?helloCommand}) ->
[get, URL, Headers, "", [{cookie, Cookies}, insecure]];
%% For error command, we convert the message and code into query parameters,
%% and append them to the original URL.
handle_args(#epp_request{method=get,
url = URL,
payload = Payload,
headers = Headers,
cookies = Cookies,
epp_verb = ?errorCommand}) ->
handle_args(#epp_request{method = get, url = URL,
payload = Payload, headers = Headers,
cookies = Cookies, epp_verb = ?errorCommand}) ->
QueryString = hackney_url:qs(Payload),
CompleteURL = [URL, <<"?">>, QueryString],
[get, CompleteURL, Headers, "", [{cookie, Cookies}, insecure]];
[get, CompleteURL, Headers, "",
[{cookie, Cookies}, insecure]];
%% For valid commands, we set the multipart body earlier, now we just pass it on.
handle_args(#epp_request{method=post,
url = URL,
payload = Payload,
headers = Headers,
handle_args(#epp_request{method = post, url = URL,
payload = Payload, headers = Headers,
cookies = Cookies}) ->
[post, URL, Headers, Payload, [{cookie, Cookies}, insecure]].
[post, URL, Headers, Payload,
[{cookie, Cookies}, insecure]].
%% Map request and return values.
request_from_map(#{command := ?errorCommand,
@ -54,15 +51,16 @@ request_from_map(#{command := ?errorCommand,
message := Message, headers := Headers,
cl_trid := ClTRID}) ->
URL = epp_router:route_request(?errorCommand),
RequestMethod = epp_router:request_method(?errorCommand),
RequestMethod =
epp_router:request_method(?errorCommand),
Cookie = hackney_cookie:setcookie("session", SessionId,
[]),
QueryParams = query_params(Code, Message, ClTRID),
Headers = Headers,
Request = #epp_request{url = URL,
method = RequestMethod,
payload = QueryParams, cookies = [Cookie],
headers = Headers, epp_verb= ?errorCommand},
method = RequestMethod, payload = QueryParams,
cookies = [Cookie], headers = Headers,
epp_verb = ?errorCommand},
lager:info("Error Request from map: [~p]~n", [Request]),
Request;
request_from_map(#{command := Command,
@ -97,7 +95,8 @@ request_from_map(#{command := Command,
method = RequestMethod, payload = Body,
cookies = [Cookie], headers = Headers,
epp_verb = Command},
lager:info("Unified Request from map: [~p]~n", [Request]),
lager:info("Unified Request from map: [~p]~n",
[Request]),
Request.
%% Return form data or an empty list.

View file

@ -7,4 +7,5 @@
%% 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 request_builder(map()) -> epp_request().

View file

@ -47,8 +47,8 @@ handle_cast(serve, State = #state{socket = Socket}) ->
handle_cast(greeting,
State = #state{socket = Socket, session_id = SessionId,
headers = Headers}) ->
Request =
epp_http_client:request_builder(#{command => "hello",
Request = epp_http_client:request_builder(#{command =>
"hello",
session_id => SessionId,
raw_frame => "",
headers => Headers,
@ -73,16 +73,17 @@ handle_cast(process_command,
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,
Request = epp_http_client:request_builder(#{command =>
Command,
session_id => SessionId,
raw_frame => RawFrame,
headers => Headers,
cl_trid => ClTRID});
#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,

View file

@ -53,8 +53,8 @@ handle_cast(serve, State = #state{socket = Socket}) ->
handle_cast(greeting,
State = #state{socket = Socket, session_id = SessionId,
headers = Headers}) ->
Request =
epp_http_client:request_builder(#{command => "hello",
Request = epp_http_client:request_builder(#{command =>
"hello",
session_id => SessionId,
raw_frame => "",
headers => Headers,
@ -79,8 +79,8 @@ handle_cast(process_command,
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,
Request = epp_http_client:request_builder(#{command =>
Command,
session_id => SessionId,
raw_frame => RawFrame,
headers => Headers,
@ -88,8 +88,8 @@ handle_cast(process_command,
#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,
@ -113,50 +113,41 @@ handle_call(_E, _From, State) -> {noreply, State}.
code_change(_OldVersion, State, _Extra) -> {ok, State}.
%% Private functions
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),
{ok, LengthToReceive};
{error, Reason} -> {error, Reason}
end.
read_frame(Socket, FrameLength) ->
case ssl:recv(Socket, FrameLength, ?DefaultTimeout) of
{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>>,
write_line(Socket, ByteSize),
write_line(Socket, Message).
CompleteMessage = <<ByteSize/binary, Message/binary>>,
write_line(Socket, CompleteMessage).
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) ->
{ok, CompleteFrame} = ssl:recv(Socket, 0, ?DefaultTimeout),
EPPEnvelope = binary:part(CompleteFrame, {0, 4}),
ReportedLength = binary:decode_unsigned(EPPEnvelope, big),
case ssl:recv(Socket, 0, ?DefaultTimeout) of
{ok, Data} ->
EPPEnvelope = binary:part(Data, {0, 4}),
ReportedLength = binary:decode_unsigned(EPPEnvelope,
big),
read_until_exhausted(Socket, ReportedLength, Data);
{error, closed} -> log_and_exit(State);
{error, timeout} -> log_on_timeout(State)
end.
read_until_exhausted(Socket, CompleteFrame, ReportedLength).
read_until_exhausted(Socket, Frame, ExpectedLength) ->
if
ExpectedLength =:= byte_size(Frame) ->
binary:part(Frame, {byte_size(Frame), 4 - ExpectedLength});
%% When an EPP message is long, it will be received in smaller chunks.
%% For example, first 4 bytes equal 800 000, but we'd receive only 200 000
%% in the first chunk. In such a case, we should listen for more.
%%
%% Note that there is no case for messages the exceed the reported length of a
%% frame. Those cases are invalid from the perspective of EPP protocol and
%% should not be supported.
read_until_exhausted(Socket, ExpectedLength, Frame) ->
if ExpectedLength =:= byte_size(Frame) ->
binary:part(Frame,
{byte_size(Frame), 4 - ExpectedLength});
ExpectedLength > byte_size(Frame) ->
{ok, NextFrame} = ssl:recv(Socket, 0, ?DefaultTimeout),
NewFrame = <<Frame/binary, NextFrame/binary>>,
read_until_exhausted(Socket, NewFrame, ExpectedLength)
read_until_exhausted(Socket, ExpectedLength, NewFrame)
end.
log_and_exit(State) ->

View file

@ -48,4 +48,5 @@
{test, [{deps, [proper]}]}]
}.
{plugins, [rebar3_fmt]}.
{plugins, [rebar3_auto,
{erl_tidy_prv_fmt, ".*", {git, "git://github.com/tsloughter/erl_tidy.git", {branch, "master"}}}]}.