mirror of
https://github.com/seriyps/mtproto_proxy.git
synced 2026-05-13 08:46:46 +00:00
Split mtp_test_middle_server to 2 modules
- one with just middle-server implementation - one with proxy config mock and multi-server DC setup
This commit is contained in:
parent
8a80fd4b59
commit
e9ece4c817
3 changed files with 110 additions and 107 deletions
105
test/mtp_test_datacenter.erl
Normal file
105
test/mtp_test_datacenter.erl
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
%% Fake telegram "datacenters"
|
||||
%% Mock to emulate core.telegram.org and set of telegram
|
||||
%% "middle-proxies" for each datacenter ID
|
||||
-module(mtp_test_datacenter).
|
||||
|
||||
-export([start_dc/0,
|
||||
start_dc/3,
|
||||
stop_dc/1,
|
||||
start_config_server/5,
|
||||
stop_config_server/1]).
|
||||
-export([dc_list_to_config/1]).
|
||||
-export([do/1]).
|
||||
|
||||
-include_lib("inets/include/httpd.hrl").
|
||||
|
||||
-define(SECRET_PATH, "/getProxySecret").
|
||||
-define(CONFIG_PATH, "/getProxyConfig").
|
||||
|
||||
|
||||
start_dc() ->
|
||||
Secret = crypto:strong_rand_bytes(128),
|
||||
DcConf = [{1, {127, 0, 0, 1}, 8888}],
|
||||
{ok, _Cfg} = start_dc(Secret, DcConf, #{}).
|
||||
|
||||
start_dc(Secret, DcConf, Acc) ->
|
||||
Cfg = dc_list_to_config(DcConf),
|
||||
{ok, Acc1} = start_config_server({127, 0, 0, 1}, 3333, Secret, Cfg, Acc),
|
||||
Ids =
|
||||
[begin
|
||||
Id = {?MODULE, DcId},
|
||||
{ok, _Pid} = mtp_test_middle_server:start(Id, #{port => Port, ip => Ip, secret => Secret}),
|
||||
Id
|
||||
end || {DcId, Ip, Port} <- DcConf],
|
||||
{ok, Acc1#{srv_ids => Ids}}.
|
||||
|
||||
stop_dc(#{srv_ids := Ids} = Acc) ->
|
||||
{ok, Acc1} = stop_config_server(Acc),
|
||||
ok = lists:foreach(fun mtp_test_middle_server:stop/1, Ids),
|
||||
{ok, maps:without([srv_ids], Acc1)}.
|
||||
|
||||
%%
|
||||
%% Inets HTTPD to use as a mock for https://core.telegram.org
|
||||
%%
|
||||
|
||||
%% Api
|
||||
start_config_server(Ip, Port, Secret, DcConfig, Acc) ->
|
||||
application:load(mtproto_proxy),
|
||||
Netloc = lists:flatten(io_lib:format("http://~s:~w", [inet:ntoa(Ip), Port])),
|
||||
Env = [{proxy_secret_url,
|
||||
Netloc ++ ?SECRET_PATH},
|
||||
{proxy_config_url,
|
||||
Netloc ++ ?CONFIG_PATH},
|
||||
{external_ip, "127.0.0.1"},
|
||||
{ip_lookup_services, undefined}],
|
||||
OldEnv =
|
||||
[begin
|
||||
%% OldV is undefined | {ok, V}
|
||||
OldV = application:get_env(mtproto_proxy, K),
|
||||
case V of
|
||||
undefined -> application:unset_env(mtproto_proxy, K);
|
||||
_ ->
|
||||
application:set_env(mtproto_proxy, K, V)
|
||||
end,
|
||||
{K, OldV}
|
||||
end || {K, V} <- Env],
|
||||
RootDir = code:lib_dir(mtproto_proxy, test),
|
||||
{ok, Pid} =
|
||||
inets:start(httpd,
|
||||
[{port, Port},
|
||||
{server_name, "mtp_config"},
|
||||
{server_root, "/tmp"},
|
||||
{document_root, RootDir},
|
||||
|
||||
{bind_address, Ip},
|
||||
{modules, [?MODULE]},
|
||||
{mtp_secret, Secret},
|
||||
{mtp_dc_conf, DcConfig}]),
|
||||
{ok, Acc#{env => OldEnv,
|
||||
httpd_pid => Pid}}.
|
||||
|
||||
stop_config_server(#{env := Env, httpd_pid := Pid} = Acc) ->
|
||||
[case V of
|
||||
undefined ->
|
||||
application:unset_env(mtproto_proxy, K);
|
||||
{ok, Val} ->
|
||||
application:set_env(mtproto_proxy, K, Val)
|
||||
end || {K, V} <- Env],
|
||||
inets:stop(httpd, Pid),
|
||||
{ok, maps:without([env, httpd_pid], Acc)}.
|
||||
|
||||
dc_list_to_config(List) ->
|
||||
<<
|
||||
<<(list_to_binary(
|
||||
io_lib:format("proxy_for ~w ~s:~w;~n", [DcId, inet:ntoa(Ip), Port])
|
||||
))/binary>>
|
||||
|| {DcId, Ip, Port} <- List
|
||||
>>.
|
||||
|
||||
%% Inets callback
|
||||
do(#mod{request_uri = ?CONFIG_PATH, config_db = Db}) ->
|
||||
[{_, DcConf}] = ets:lookup(Db, mtp_dc_conf),
|
||||
{break, [{response, {200, binary_to_list(DcConf)}}]};
|
||||
do(#mod{request_uri = ?SECRET_PATH, config_db = Db}) ->
|
||||
[{_, Secret}] = ets:lookup(Db, mtp_secret),
|
||||
{break, [{response, {200, binary_to_list(Secret)}}]}.
|
||||
|
|
@ -1,19 +1,12 @@
|
|||
%% Fake telegram server
|
||||
%% Fake telegram "middle-proxy" server
|
||||
-module(mtp_test_middle_server).
|
||||
-behaviour(ranch_protocol).
|
||||
-behaviour(gen_statem).
|
||||
|
||||
-export([start_dc/0,
|
||||
start_dc/3,
|
||||
stop_dc/1,
|
||||
start/2,
|
||||
stop/1,
|
||||
start_config_server/5,
|
||||
stop_config_server/1]).
|
||||
-export([dc_list_to_config/1]).
|
||||
-export([start/2,
|
||||
stop/1]).
|
||||
-export([start_link/4,
|
||||
ranch_init/1]).
|
||||
-export([do/1]).
|
||||
-export([init/1,
|
||||
callback_mode/0,
|
||||
%% handle_call/3,
|
||||
|
|
@ -26,7 +19,6 @@
|
|||
wait_handshake/3,
|
||||
on_tunnel/3]).
|
||||
|
||||
-include_lib("inets/include/httpd.hrl").
|
||||
-record(hs_state,
|
||||
{sock,
|
||||
transport,
|
||||
|
|
@ -47,102 +39,8 @@
|
|||
-define(RPC_HANDSHAKE, 245,238,130,118).
|
||||
-define(RPC_FLAGS, 0, 0, 0, 0).
|
||||
|
||||
-define(SECRET_PATH, "/getProxySecret").
|
||||
-define(CONFIG_PATH, "/getProxyConfig").
|
||||
|
||||
%% -type state_name() :: wait_nonce | wait_handshake | on_tunnel.
|
||||
|
||||
start_dc() ->
|
||||
Secret = crypto:strong_rand_bytes(128),
|
||||
DcConf = [{1, {127, 0, 0, 1}, 8888}],
|
||||
{ok, _Cfg} = start_dc(Secret, DcConf, #{}).
|
||||
|
||||
start_dc(Secret, DcConf, Acc) ->
|
||||
Cfg = mtp_test_middle_server:dc_list_to_config(DcConf),
|
||||
{ok, Acc1} = start_config_server({127, 0, 0, 1}, 3333, Secret, Cfg, Acc),
|
||||
Ids =
|
||||
[begin
|
||||
Id = {?MODULE, DcId},
|
||||
{ok, _Pid} = start(Id, #{port => Port, ip => Ip, secret => Secret}),
|
||||
Id
|
||||
end || {DcId, Ip, Port} <- DcConf],
|
||||
{ok, Acc1#{srv_ids => Ids}}.
|
||||
|
||||
stop_dc(#{srv_ids := Ids} = Acc) ->
|
||||
{ok, Acc1} = stop_config_server(Acc),
|
||||
ok = lists:foreach(fun stop/1, Ids),
|
||||
{ok, maps:without([srv_ids], Acc1)}.
|
||||
|
||||
%%
|
||||
%% Inets HTTPD to use as a mock for https://core.telegram.org
|
||||
%%
|
||||
|
||||
%% Api
|
||||
start_config_server(Ip, Port, Secret, DcConfig, Acc) ->
|
||||
application:load(mtproto_proxy),
|
||||
Netloc = lists:flatten(io_lib:format("http://~s:~w", [inet:ntoa(Ip), Port])),
|
||||
Env = [{proxy_secret_url,
|
||||
Netloc ++ ?SECRET_PATH},
|
||||
{proxy_config_url,
|
||||
Netloc ++ ?CONFIG_PATH},
|
||||
{external_ip, "127.0.0.1"},
|
||||
{ip_lookup_services, undefined}],
|
||||
OldEnv =
|
||||
[begin
|
||||
%% OldV is undefined | {ok, V}
|
||||
OldV = application:get_env(mtproto_proxy, K),
|
||||
case V of
|
||||
undefined -> application:unset_env(mtproto_proxy, K);
|
||||
_ ->
|
||||
application:set_env(mtproto_proxy, K, V)
|
||||
end,
|
||||
{K, OldV}
|
||||
end || {K, V} <- Env],
|
||||
RootDir = code:lib_dir(mtproto_proxy, test),
|
||||
{ok, Pid} =
|
||||
inets:start(httpd,
|
||||
[{port, Port},
|
||||
{server_name, "mtp_config"},
|
||||
{server_root, "/tmp"},
|
||||
{document_root, RootDir},
|
||||
|
||||
{bind_address, Ip},
|
||||
{modules, [?MODULE]},
|
||||
{mtp_secret, Secret},
|
||||
{mtp_dc_conf, DcConfig}]),
|
||||
{ok, Acc#{env => OldEnv,
|
||||
httpd_pid => Pid}}.
|
||||
|
||||
stop_config_server(#{env := Env, httpd_pid := Pid} = Acc) ->
|
||||
[case V of
|
||||
undefined ->
|
||||
application:unset_env(mtproto_proxy, K);
|
||||
{ok, Val} ->
|
||||
application:set_env(mtproto_proxy, K, Val)
|
||||
end || {K, V} <- Env],
|
||||
inets:stop(httpd, Pid),
|
||||
{ok, maps:without([env, httpd_pid], Acc)}.
|
||||
|
||||
dc_list_to_config(List) ->
|
||||
<<
|
||||
<<(list_to_binary(
|
||||
io_lib:format("proxy_for ~w ~s:~w;~n", [DcId, inet:ntoa(Ip), Port])
|
||||
))/binary>>
|
||||
|| {DcId, Ip, Port} <- List
|
||||
>>.
|
||||
|
||||
%% Inets callback
|
||||
do(#mod{request_uri = ?CONFIG_PATH, config_db = Db}) ->
|
||||
[{_, DcConf}] = ets:lookup(Db, mtp_dc_conf),
|
||||
{break, [{response, {200, binary_to_list(DcConf)}}]};
|
||||
do(#mod{request_uri = ?SECRET_PATH, config_db = Db}) ->
|
||||
[{_, Secret}] = ets:lookup(Db, mtp_secret),
|
||||
{break, [{response, {200, binary_to_list(Secret)}}]}.
|
||||
|
||||
%%
|
||||
%% Mtproto telegram server
|
||||
%%
|
||||
|
||||
%% Api
|
||||
start(Id, Opts) ->
|
||||
{ok, _} = application:ensure_all_started(ranch),
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ setup_single(Name, Offset, Cfg) ->
|
|||
tag => <<"dcbe8f1493fa4cd9ab300891c0b5b326">>}],
|
||||
application:load(mtproto_proxy),
|
||||
Cfg1 = set_env([{ports, Listeners}], Cfg),
|
||||
{ok, DcCfg} = mtp_test_middle_server:start_dc(PubKey, DcConf, #{}),
|
||||
{ok, DcCfg} = mtp_test_datacenter:start_dc(PubKey, DcConf, #{}),
|
||||
application:load(mtproto_proxy),
|
||||
{ok, _} = application:ensure_all_started(mtproto_proxy),
|
||||
[{dc_id, DcId},
|
||||
|
|
@ -113,7 +113,7 @@ stop_single(Cfg) ->
|
|||
DcCfg = ?config(dc_conf, Cfg),
|
||||
MetricPid = ?config(metric, Cfg),
|
||||
ok = application:stop(mtproto_proxy),
|
||||
{ok, _} = mtp_test_middle_server:stop_dc(DcCfg),
|
||||
{ok, _} = mtp_test_datacenter:stop_dc(DcCfg),
|
||||
gen_server:stop(MetricPid),
|
||||
Cfg.
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue