Мой единственный метод отладки (io:format/2
) не работает в Y AWS. Я в недоумении. Мой руководитель запускает три процесса: ETS Manager, Y AWS Init и Ratelimiter. Это успешно. Я могу поиграть с ограничителем скорости в оболочке ... вызывая те же функции, Y AWS должно быть. Разница в том, что оболочка ведет себя так, как я ожидал, и я понятия не имею, что происходит в Y AWS.
Я знаю, если я спамю команду в оболочке: ratelimiter:limit(IP)
она вернет true
в конце концов. Я могу выполнить следующее, и он также вернет true
: ratelimiter:lockout(IP), ratelimiter:blacklist(IP)
. Ограничителем является gen_server
.
Функции выполняют следующее:
limit/1
: проверьте таблицу ETS, если счетчик> порог; счетчик обновлений. Если счетчик> порог черного списка, сделайте запись в таблице мнезий blacklist/1
: проверьте таблицу мнезий, если запись существует; Да: сброс таймера lockout/1
: немедленно вводит ID в таблицу мнезийных сообщений
В моем модуле arg_rewrite_mod
я делаю некоторые проверки, чтобы убедиться, что я получаю запросы HTTP Я ожидаю, а именно GET, POST и HEAD. Я думал, что это было бы хорошим местом, чтобы также сделать ограничение скорости. Сделайте это как можно скорее в цепочке событий веб-сервера.
Кажется, что все изменения, которые я внес в модуль arg_rewrite
, работают, за исключением использования "printf" и ограничителя. Я плохо знаком с языком, поэтому я не уверен, что моя ошибка очевидна или нет.
Скелет моего arg_rewrite_mod
:
-module(arg_preproc).
-export([arg_rewrite/1]).
-include("limiter_def.hrl").
-include_lib("/usr/lib/yaws/include/yaws_api.hrl").
is_blacklisted(ID) ->
case ratelimiter:blacklist(ID) of
false -> continue;
true -> throw(blacklist)
end.
is_limited(ID) ->
case ratelimiter:limit(ID) of
false -> continue;
true -> throw(limit)
end.
arg_rewrite(A) ->
Allow = ['GET','POST', 'HEAD'],
try
{IP, _} = A#arg.client_ip_port,
ID = IP,
is_blacklisted(ID),
io:format("~p ~p ~n",[ID, is_blacklisted(ID)]),
%% === Allow expected HTTP requests
HttpReq = (A#arg.req)#http_request.method,
case lists:member(HttpReq, Allow) of
true ->
{_,ReqTgt} = (A#arg.req)#http_request.path,
PassThru = [".css",".jpg",".jpeg",".png",".js"],
%% ... much more ...
false ->
is_limited(ID),
throw(http_method_denied)
end
catch
throw:blacklist -> %% Send back a 429;
throw:limit -> %% Same but no Retry-After;
throw:http_method_denied ->
%%Only thrown experienced
AllowedReq = string:join([atom_to_list(M) || M <- Allow], ","),
A#arg{state=#rewrite_response{status=405,
headers=[{header, {"Allow", AllowedReq}},{header, {connection, "close"}}]
}};
Type:Reason -> {error, {unhandled,{Type, Reason}}}
end.
Я могу спамить curl -I -X HEAD <<any page>>
так быстро как я могу в bash оболочке, и все, что я получаю, это HTTP 200
. Таблица ETS также имеет нулевые записи. Используя PUT
, я получаю HTTP 405
, как и предполагалось. Я могу ratelimiter:lockout({MY_IP})
и получить веб-страницу для загрузки в моем браузере и HTTP 200
с curl
.
Я в замешательстве. Я так начал Y AWS?
start() ->
os:putenv("YAWSHOME", ?HOMEPATH_YAWS),
code:add_patha(?MODPATH_YAWS),
ok = case (R = application:start(yaws)) of
{error, {already_started, _}} -> ok;
_ -> R
end,
{ok,self()}. %% Tell supervisor everything okay in a manner it expects.
Я сделал это, потому что думал, что это будет "проще".