mirror of
https://github.com/internetee/epp_proxy.git
synced 2025-08-20 06:23:47 +02:00
Reformat Erlang code, write more documentation
This commit is contained in:
parent
558e1f0ef7
commit
771cc06232
13 changed files with 323 additions and 330 deletions
|
@ -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),
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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().
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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) ->
|
||||
|
|
|
@ -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"}}}]}.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue