mirror of
https://github.com/internetee/epp_proxy.git
synced 2025-08-14 19:43:48 +02:00
Merge pull request #17 from internetee/fix-undefined-command-error
Introduce error 2000
This commit is contained in:
commit
65d5e6ccc9
6 changed files with 86 additions and 24 deletions
|
@ -9,3 +9,14 @@
|
||||||
}).
|
}).
|
||||||
|
|
||||||
-type epp_request() :: #epp_request{}.
|
-type epp_request() :: #epp_request{}.
|
||||||
|
|
||||||
|
|
||||||
|
-define(XMLErrorCode, <<"2001">>).
|
||||||
|
|
||||||
|
-define(XMLErrorMessage, <<"Command syntax error.">>).
|
||||||
|
|
||||||
|
-define(UnknownCommandErrorCode, <<"2000">>).
|
||||||
|
|
||||||
|
-define(UnknownCommandErrorMessage, <<"Unknown command.">>).
|
||||||
|
|
||||||
|
-define(DefaultTimeout, 120000).
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
-module(epp_router).
|
-module(epp_router).
|
||||||
|
|
||||||
-export([request_method/1, route_request/1]).
|
-export([is_valid_command/1, request_method/1,
|
||||||
|
route_request/1]).
|
||||||
|
|
||||||
-define(validCommands,
|
-define(validCommands,
|
||||||
["hello", "login", "logout", "check", "info", "poll",
|
["hello", "login", "logout", "check", "info", "poll",
|
||||||
|
@ -9,14 +10,22 @@
|
||||||
%% 47 is the character code
|
%% 47 is the character code
|
||||||
-define(forwardSlash, 47).
|
-define(forwardSlash, 47).
|
||||||
|
|
||||||
%% request method: GET for greeting, POST for everything else.
|
%% request method: GET for greeting and error, POST for everything else.
|
||||||
request_method("hello") -> get;
|
request_method("hello") -> get;
|
||||||
request_method(<<"hello">>) -> get;
|
request_method(<<"hello">>) -> get;
|
||||||
request_method("error") -> get;
|
request_method("error") -> get;
|
||||||
request_method(<<"error">>) -> get;
|
request_method(<<"error">>) -> get;
|
||||||
request_method(_) -> post.
|
request_method(_) -> post.
|
||||||
|
|
||||||
|
is_valid_command(Command) when is_binary(Command) ->
|
||||||
|
CommandAsList = binary_to_list(Command),
|
||||||
|
lists:member(CommandAsList, ?validCommands);
|
||||||
|
is_valid_command(Command) when is_list(Command) ->
|
||||||
|
lists:member(Command, ?validCommands);
|
||||||
|
is_valid_command(_) -> false.
|
||||||
|
|
||||||
%% Base router
|
%% Base router
|
||||||
|
route_request(undefined) -> url_map("error");
|
||||||
route_request(Command) when is_binary(Command) ->
|
route_request(Command) when is_binary(Command) ->
|
||||||
List = binary_to_list(Command), url_map(List);
|
List = binary_to_list(Command), url_map(List);
|
||||||
route_request(Command) when is_list(Command) ->
|
route_request(Command) when is_list(Command) ->
|
||||||
|
|
|
@ -18,12 +18,6 @@
|
||||||
|
|
||||||
-record(state, {socket, session_id, headers}).
|
-record(state, {socket, session_id, headers}).
|
||||||
|
|
||||||
-define(XMLErrorCode, <<"2001">>).
|
|
||||||
|
|
||||||
-define(XMLErrorMessage, <<"Command syntax error.">>).
|
|
||||||
|
|
||||||
-define(DefaultTimeout, 120000).
|
|
||||||
|
|
||||||
%% Initialize process
|
%% Initialize process
|
||||||
%% Assign an unique session id that will be passed on to http server as a cookie
|
%% Assign an unique session id that will be passed on to http server as a cookie
|
||||||
init(Socket) ->
|
init(Socket) ->
|
||||||
|
@ -177,8 +171,15 @@ parse_frame(Frame) ->
|
||||||
case epp_xml:parse(Frame) of
|
case epp_xml:parse(Frame) of
|
||||||
{ok, XMLRecord} ->
|
{ok, XMLRecord} ->
|
||||||
Command = epp_xml:get_command(XMLRecord),
|
Command = epp_xml:get_command(XMLRecord),
|
||||||
#valid_frame{command = Command, cl_trid = ClTRID,
|
case epp_router:is_valid_command(Command) of
|
||||||
raw_frame = Frame};
|
true ->
|
||||||
|
#valid_frame{command = Command, cl_trid = ClTRID,
|
||||||
|
raw_frame = Frame};
|
||||||
|
false ->
|
||||||
|
#invalid_frame{code = ?UnknownCommandErrorCode,
|
||||||
|
message = ?UnknownCommandErrorMessage,
|
||||||
|
cl_trid = ClTRID}
|
||||||
|
end;
|
||||||
{error, _} ->
|
{error, _} ->
|
||||||
#invalid_frame{code = ?XMLErrorCode,
|
#invalid_frame{code = ?XMLErrorCode,
|
||||||
message = ?XMLErrorMessage, cl_trid = ClTRID}
|
message = ?XMLErrorMessage, cl_trid = ClTRID}
|
||||||
|
|
|
@ -18,12 +18,6 @@
|
||||||
|
|
||||||
-record(state, {socket, session_id, headers}).
|
-record(state, {socket, session_id, headers}).
|
||||||
|
|
||||||
-define(XMLErrorCode, <<"2001">>).
|
|
||||||
|
|
||||||
-define(XMLErrorMessage, <<"Command syntax error.">>).
|
|
||||||
|
|
||||||
-define(DefaultTimeout, 120000).
|
|
||||||
|
|
||||||
%% Initialize process
|
%% Initialize process
|
||||||
%% Assign an unique session id that will be passed on to http server as a cookie
|
%% Assign an unique session id that will be passed on to http server as a cookie
|
||||||
init(Socket) ->
|
init(Socket) ->
|
||||||
|
@ -197,8 +191,15 @@ parse_frame(Frame) ->
|
||||||
case epp_xml:parse(Frame) of
|
case epp_xml:parse(Frame) of
|
||||||
{ok, XMLRecord} ->
|
{ok, XMLRecord} ->
|
||||||
Command = epp_xml:get_command(XMLRecord),
|
Command = epp_xml:get_command(XMLRecord),
|
||||||
#valid_frame{command = Command, cl_trid = ClTRID,
|
case epp_router:is_valid_command(Command) of
|
||||||
raw_frame = Frame};
|
true ->
|
||||||
|
#valid_frame{command = Command, cl_trid = ClTRID,
|
||||||
|
raw_frame = Frame};
|
||||||
|
false ->
|
||||||
|
#invalid_frame{code = ?UnknownCommandErrorCode,
|
||||||
|
message = ?UnknownCommandErrorMessage,
|
||||||
|
cl_trid = ClTRID}
|
||||||
|
end;
|
||||||
{error, _} ->
|
{error, _} ->
|
||||||
#invalid_frame{code = ?XMLErrorCode,
|
#invalid_frame{code = ?XMLErrorCode,
|
||||||
message = ?XMLErrorMessage, cl_trid = ClTRID}
|
message = ?XMLErrorMessage, cl_trid = ClTRID}
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
valid_command_test_case/1,
|
valid_command_test_case/1,
|
||||||
long_message_test_case/1,
|
long_message_test_case/1,
|
||||||
invalid_command_test_case/1,
|
invalid_command_test_case/1,
|
||||||
|
missing_command_test_case/1,
|
||||||
error_test_case/1]).
|
error_test_case/1]).
|
||||||
|
|
||||||
all() ->
|
all() ->
|
||||||
|
@ -20,6 +21,7 @@ all() ->
|
||||||
valid_command_test_case,
|
valid_command_test_case,
|
||||||
long_message_test_case,
|
long_message_test_case,
|
||||||
invalid_command_test_case,
|
invalid_command_test_case,
|
||||||
|
missing_command_test_case,
|
||||||
error_test_case].
|
error_test_case].
|
||||||
|
|
||||||
init_per_suite(Config) ->
|
init_per_suite(Config) ->
|
||||||
|
@ -133,8 +135,7 @@ long_message_test_case(Config) ->
|
||||||
"Command completed successfully; no messages"),
|
"Command completed successfully; no messages"),
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
%% Sending an invalid command frame should close the connection.
|
%% Sending an invalid command frame should return a canned response.
|
||||||
%% It also crashes the process.
|
|
||||||
invalid_command_test_case(Config) ->
|
invalid_command_test_case(Config) ->
|
||||||
Options = proplists:get_value(tcp_options, Config),
|
Options = proplists:get_value(tcp_options, Config),
|
||||||
{ok, Socket} = gen_tcp:connect("localhost", 1180, Options, 2000),
|
{ok, Socket} = gen_tcp:connect("localhost", 1180, Options, 2000),
|
||||||
|
@ -150,7 +151,26 @@ invalid_command_test_case(Config) ->
|
||||||
"</command>\n"
|
"</command>\n"
|
||||||
"</epp>\n">>,
|
"</epp>\n">>,
|
||||||
ok = send_data(InvalidCommand, Socket),
|
ok = send_data(InvalidCommand, Socket),
|
||||||
{error, closed} = receive_data(Socket),
|
ErrorResponse = receive_data(Socket),
|
||||||
|
match_data(ErrorResponse,
|
||||||
|
"Unknown command."),
|
||||||
|
ok.
|
||||||
|
|
||||||
|
%% Sending a valid XML without command frame should return a canned response.
|
||||||
|
missing_command_test_case(Config) ->
|
||||||
|
Options = proplists:get_value(tcp_options, Config),
|
||||||
|
{ok, Socket} = gen_tcp:connect("localhost", 1180, Options, 2000),
|
||||||
|
_Data = receive_data(Socket),
|
||||||
|
ok = send_data(login_command(), Socket),
|
||||||
|
_LoginResponse = receive_data(Socket),
|
||||||
|
InvalidCommand =
|
||||||
|
<<"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n"
|
||||||
|
"<epp xmlns=\"https://epp.tld.ee/schema/epp-ee-1.0.xsd\">\n"
|
||||||
|
"</epp>\n">>,
|
||||||
|
ok = send_data(InvalidCommand, Socket),
|
||||||
|
ErrorResponse = receive_data(Socket),
|
||||||
|
match_data(ErrorResponse,
|
||||||
|
"Unknown command."),
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
error_test_case(Config) ->
|
error_test_case(Config) ->
|
||||||
|
|
|
@ -11,6 +11,7 @@
|
||||||
valid_command_test_case/1,
|
valid_command_test_case/1,
|
||||||
long_message_test_case/1,
|
long_message_test_case/1,
|
||||||
invalid_command_test_case/1,
|
invalid_command_test_case/1,
|
||||||
|
missing_command_test_case/1,
|
||||||
error_test_case/1,
|
error_test_case/1,
|
||||||
revoked_cert_test_case/1]).
|
revoked_cert_test_case/1]).
|
||||||
|
|
||||||
|
@ -21,6 +22,7 @@ all() ->
|
||||||
valid_command_test_case,
|
valid_command_test_case,
|
||||||
long_message_test_case,
|
long_message_test_case,
|
||||||
invalid_command_test_case,
|
invalid_command_test_case,
|
||||||
|
missing_command_test_case,
|
||||||
error_test_case,
|
error_test_case,
|
||||||
revoked_cert_test_case].
|
revoked_cert_test_case].
|
||||||
|
|
||||||
|
@ -142,8 +144,7 @@ long_message_test_case(Config) ->
|
||||||
"Command completed successfully; no messages"),
|
"Command completed successfully; no messages"),
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
%% Sending an invalid command frame should close the connection.
|
%% Sending an invalid command frame returns a canned response.
|
||||||
%% It also crashes the process.
|
|
||||||
invalid_command_test_case(Config) ->
|
invalid_command_test_case(Config) ->
|
||||||
Options = proplists:get_value(ssl_options, Config),
|
Options = proplists:get_value(ssl_options, Config),
|
||||||
{ok, Socket} = ssl:connect("localhost", 1443, Options, 2000),
|
{ok, Socket} = ssl:connect("localhost", 1443, Options, 2000),
|
||||||
|
@ -159,7 +160,26 @@ invalid_command_test_case(Config) ->
|
||||||
"</command>\n"
|
"</command>\n"
|
||||||
"</epp>\n">>,
|
"</epp>\n">>,
|
||||||
ok = send_data(InvalidCommand, Socket),
|
ok = send_data(InvalidCommand, Socket),
|
||||||
{error, closed} = receive_data(Socket),
|
ErrorResponse = receive_data(Socket),
|
||||||
|
match_data(ErrorResponse,
|
||||||
|
"Unknown command."),
|
||||||
|
ok.
|
||||||
|
|
||||||
|
%% Sending a missing command frame should return a canned response.
|
||||||
|
missing_command_test_case(Config) ->
|
||||||
|
Options = proplists:get_value(ssl_options, Config),
|
||||||
|
{ok, Socket} = ssl:connect("localhost", 1443, Options, 2000),
|
||||||
|
_Data = receive_data(Socket),
|
||||||
|
ok = send_data(login_command(), Socket),
|
||||||
|
_LoginResponse = receive_data(Socket),
|
||||||
|
InvalidCommand =
|
||||||
|
<<"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n"
|
||||||
|
"<epp xmlns=\"https://epp.tld.ee/schema/epp-ee-1.0.xsd\">\n"
|
||||||
|
"</epp>\n">>,
|
||||||
|
ok = send_data(InvalidCommand, Socket),
|
||||||
|
ErrorResponse = receive_data(Socket),
|
||||||
|
match_data(ErrorResponse,
|
||||||
|
"Unknown command."),
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
error_test_case(Config) ->
|
error_test_case(Config) ->
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue