fix: return 400 if node in query doesn't look like a known node
This commit is contained in:
parent
a26964291d
commit
1f7c02ecf5
|
@ -48,6 +48,7 @@
|
||||||
|
|
||||||
-define(TO_BIN(_B_), iolist_to_binary(_B_)).
|
-define(TO_BIN(_B_), iolist_to_binary(_B_)).
|
||||||
-define(NOT_FOUND(N), {404, #{code => 'NOT_FOUND', message => ?TO_BIN([N, " NOT FOUND"])}}).
|
-define(NOT_FOUND(N), {404, #{code => 'NOT_FOUND', message => ?TO_BIN([N, " NOT FOUND"])}}).
|
||||||
|
-define(BAD_REQUEST(C, M), {400, #{code => C, message => ?TO_BIN(M)}}).
|
||||||
-define(TAGS, [<<"Trace">>]).
|
-define(TAGS, [<<"Trace">>]).
|
||||||
|
|
||||||
namespace() -> "trace".
|
namespace() -> "trace".
|
||||||
|
@ -141,6 +142,7 @@ schema("/trace/:name/download") ->
|
||||||
#{schema => #{type => "string", format => "binary"}}
|
#{schema => #{type => "string", format => "binary"}}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
400 => emqx_dashboard_swagger:error_codes(['NODE_ERROR'], <<"Node Not Found">>),
|
||||||
404 => emqx_dashboard_swagger:error_codes(['NOT_FOUND'], <<"Trace Name Not Found">>)
|
404 => emqx_dashboard_swagger:error_codes(['NOT_FOUND'], <<"Trace Name Not Found">>)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -176,9 +178,8 @@ schema("/trace/:name/log") ->
|
||||||
{items, hoconsc:mk(binary(), #{example => "TEXT-LOG-ITEMS"})},
|
{items, hoconsc:mk(binary(), #{example => "TEXT-LOG-ITEMS"})},
|
||||||
{meta, fields(bytes) ++ fields(position)}
|
{meta, fields(bytes) ++ fields(position)}
|
||||||
],
|
],
|
||||||
400 => emqx_dashboard_swagger:error_codes(
|
400 => emqx_dashboard_swagger:error_codes(['NODE_ERROR'], <<"Trace Log Failed">>),
|
||||||
['READ_FILE_ERROR', 'RPC_ERROR', 'NODE_ERROR'], <<"Trace Log Failed">>
|
404 => emqx_dashboard_swagger:error_codes(['NOT_FOUND'], <<"Trace Name Not Found">>)
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.
|
}.
|
||||||
|
@ -450,15 +451,11 @@ update_trace(put, #{bindings := #{name := Name}}) ->
|
||||||
%% if HTTP request headers include accept-encoding: gzip and file size > 300 bytes.
|
%% if HTTP request headers include accept-encoding: gzip and file size > 300 bytes.
|
||||||
%% cowboy_compress_h will auto encode gzip format.
|
%% cowboy_compress_h will auto encode gzip format.
|
||||||
download_trace_log(get, #{bindings := #{name := Name}, query_string := Query}) ->
|
download_trace_log(get, #{bindings := #{name := Name}, query_string := Query}) ->
|
||||||
Nodes =
|
|
||||||
case parse_node(Query, undefined) of
|
case parse_node(Query, undefined) of
|
||||||
{ok, undefined} -> mria_mnesia:running_nodes();
|
{ok, Node} ->
|
||||||
{ok, Node0} -> [Node0];
|
|
||||||
{error, not_found} -> mria_mnesia:running_nodes()
|
|
||||||
end,
|
|
||||||
case emqx_trace:get_trace_filename(Name) of
|
case emqx_trace:get_trace_filename(Name) of
|
||||||
{ok, TraceLog} ->
|
{ok, TraceLog} ->
|
||||||
TraceFiles = collect_trace_file(Nodes, TraceLog),
|
TraceFiles = collect_trace_file(Node, TraceLog),
|
||||||
ZipDir = emqx_trace:zip_dir(),
|
ZipDir = emqx_trace:zip_dir(),
|
||||||
Zips = group_trace_file(ZipDir, TraceLog, TraceFiles),
|
Zips = group_trace_file(ZipDir, TraceLog, TraceFiles),
|
||||||
FileName = binary_to_list(Name) ++ ".zip",
|
FileName = binary_to_list(Name) ++ ".zip",
|
||||||
|
@ -471,11 +468,16 @@ download_trace_log(get, #{bindings := #{name := Name}, query_string := Query}) -
|
||||||
_ = file:delete(ZipFile),
|
_ = file:delete(ZipFile),
|
||||||
Headers = #{
|
Headers = #{
|
||||||
<<"content-type">> => <<"application/x-zip">>,
|
<<"content-type">> => <<"application/x-zip">>,
|
||||||
<<"content-disposition">> => iolist_to_binary("attachment; filename=" ++ ZipName)
|
<<"content-disposition">> => iolist_to_binary(
|
||||||
|
"attachment; filename=" ++ ZipName
|
||||||
|
)
|
||||||
},
|
},
|
||||||
{200, Headers, {file_binary, ZipName, Binary}};
|
{200, Headers, {file_binary, ZipName, Binary}};
|
||||||
{error, not_found} ->
|
{error, not_found} ->
|
||||||
?NOT_FOUND(Name)
|
?NOT_FOUND(Name)
|
||||||
|
end;
|
||||||
|
{error, not_found} ->
|
||||||
|
?BAD_REQUEST('NODE_ERROR', <<"Node not found">>)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
group_trace_file(ZipDir, TraceLog, TraceFiles) ->
|
group_trace_file(ZipDir, TraceLog, TraceFiles) ->
|
||||||
|
@ -503,8 +505,11 @@ group_trace_file(ZipDir, TraceLog, TraceFiles) ->
|
||||||
TraceFiles
|
TraceFiles
|
||||||
).
|
).
|
||||||
|
|
||||||
collect_trace_file(Nodes, TraceLog) ->
|
collect_trace_file(undefined, TraceLog) ->
|
||||||
wrap_rpc(emqx_mgmt_trace_proto_v2:trace_file(Nodes, TraceLog)).
|
Nodes = mria_mnesia:running_nodes(),
|
||||||
|
wrap_rpc(emqx_mgmt_trace_proto_v2:trace_file(Nodes, TraceLog));
|
||||||
|
collect_trace_file(Node, TraceLog) ->
|
||||||
|
wrap_rpc(emqx_mgmt_trace_proto_v2:trace_file([Node], TraceLog)).
|
||||||
|
|
||||||
collect_trace_file_detail(TraceLog) ->
|
collect_trace_file_detail(TraceLog) ->
|
||||||
Nodes = mria_mnesia:running_nodes(),
|
Nodes = mria_mnesia:running_nodes(),
|
||||||
|
@ -551,21 +556,13 @@ stream_log_file(get, #{bindings := #{name := Name}, query_string := Query}) ->
|
||||||
{error, enoent} ->
|
{error, enoent} ->
|
||||||
Meta = #{<<"position">> => Position, <<"bytes">> => Bytes},
|
Meta = #{<<"position">> => Position, <<"bytes">> => Bytes},
|
||||||
{200, #{meta => Meta, items => <<"">>}};
|
{200, #{meta => Meta, items => <<"">>}};
|
||||||
{error, Reason} ->
|
{error, not_found} ->
|
||||||
?SLOG(error, #{
|
?NOT_FOUND(Name);
|
||||||
msg => "read_file_failed",
|
|
||||||
node => Node,
|
|
||||||
name => Name,
|
|
||||||
reason => Reason,
|
|
||||||
position => Position,
|
|
||||||
bytes => Bytes
|
|
||||||
}),
|
|
||||||
{400, #{code => 'READ_FILE_ERROR', message => Reason}};
|
|
||||||
{badrpc, nodedown} ->
|
{badrpc, nodedown} ->
|
||||||
{400, #{code => 'RPC_ERROR', message => "BadRpc node down"}}
|
?BAD_REQUEST('NODE_ERROR', <<"Node not found">>)
|
||||||
end;
|
end;
|
||||||
{error, not_found} ->
|
{error, not_found} ->
|
||||||
{400, #{code => 'NODE_ERROR', message => <<"Node not found">>}}
|
?BAD_REQUEST('NODE_ERROR', <<"Node not found">>)
|
||||||
end.
|
end.
|
||||||
|
|
||||||
-spec get_trace_size() -> #{{node(), file:name_all()} => non_neg_integer()}.
|
-spec get_trace_size() -> #{{node(), file:name_all()} => non_neg_integer()}.
|
||||||
|
@ -633,8 +630,12 @@ read_file(Path, Offset, Bytes) ->
|
||||||
parse_node(Query, Default) ->
|
parse_node(Query, Default) ->
|
||||||
try
|
try
|
||||||
case maps:find(<<"node">>, Query) of
|
case maps:find(<<"node">>, Query) of
|
||||||
error -> {ok, Default};
|
error ->
|
||||||
{ok, Node} -> {ok, binary_to_existing_atom(Node)}
|
{ok, Default};
|
||||||
|
{ok, NodeBin} ->
|
||||||
|
Node = binary_to_existing_atom(NodeBin),
|
||||||
|
true = lists:member(Node, mria_mnesia:running_nodes()),
|
||||||
|
{ok, Node}
|
||||||
end
|
end
|
||||||
catch
|
catch
|
||||||
_:_ ->
|
_:_ ->
|
||||||
|
|
|
@ -213,6 +213,27 @@ t_log_file(_Config) ->
|
||||||
Path = api_path("trace/test_client_id/download?node=" ++ atom_to_list(node())),
|
Path = api_path("trace/test_client_id/download?node=" ++ atom_to_list(node())),
|
||||||
{ok, Binary2} = request_api(get, Path, Header),
|
{ok, Binary2} = request_api(get, Path, Header),
|
||||||
?assertEqual(ZipTab, zip:table(Binary2)),
|
?assertEqual(ZipTab, zip:table(Binary2)),
|
||||||
|
{error, {_, 400, _}, _} =
|
||||||
|
request_api(
|
||||||
|
get,
|
||||||
|
api_path("trace/test_client_id/download?node=unknonwn_node"),
|
||||||
|
Header
|
||||||
|
),
|
||||||
|
{error, {_, 400, _}, _} =
|
||||||
|
request_api(
|
||||||
|
get,
|
||||||
|
% known atom but unknown node
|
||||||
|
api_path("trace/test_client_id/download?node=undefined"),
|
||||||
|
Header
|
||||||
|
),
|
||||||
|
?assertMatch(
|
||||||
|
{error, {"HTTP/1.1", 404, "Not Found"}, _},
|
||||||
|
request_api(
|
||||||
|
get,
|
||||||
|
api_path("trace/test_client_not_found/download?node=" ++ atom_to_list(node())),
|
||||||
|
Header
|
||||||
|
)
|
||||||
|
),
|
||||||
ok = emqtt:disconnect(Client),
|
ok = emqtt:disconnect(Client),
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
|
@ -267,6 +288,25 @@ t_stream_log(_Config) ->
|
||||||
#{<<"meta">> := Meta1, <<"items">> := Bin1} = json(Binary1),
|
#{<<"meta">> := Meta1, <<"items">> := Bin1} = json(Binary1),
|
||||||
?assertEqual(#{<<"position">> => 30, <<"bytes">> => 10}, Meta1),
|
?assertEqual(#{<<"position">> => 30, <<"bytes">> => 10}, Meta1),
|
||||||
?assertEqual(10, byte_size(Bin1)),
|
?assertEqual(10, byte_size(Bin1)),
|
||||||
|
{error, {_, 400, _}, _} =
|
||||||
|
request_api(
|
||||||
|
get,
|
||||||
|
api_path("trace/test_stream_log/log?node=unknonwn_node"),
|
||||||
|
Header
|
||||||
|
),
|
||||||
|
{error, {_, 400, _}, _} =
|
||||||
|
request_api(
|
||||||
|
get,
|
||||||
|
% known atom but not a node
|
||||||
|
api_path("trace/test_stream_log/log?node=undefined"),
|
||||||
|
Header
|
||||||
|
),
|
||||||
|
{error, {_, 404, _}, _} =
|
||||||
|
request_api(
|
||||||
|
get,
|
||||||
|
api_path("trace/test_stream_log_not_found/log"),
|
||||||
|
Header
|
||||||
|
),
|
||||||
unload(),
|
unload(),
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
|
|
|
@ -38,3 +38,5 @@
|
||||||
|
|
||||||
- Fix shadowing `'client.authenticate'` callbacks by `emqx_authenticator`. Now `emqx_authenticator`
|
- Fix shadowing `'client.authenticate'` callbacks by `emqx_authenticator`. Now `emqx_authenticator`
|
||||||
passes execution to the further callbacks if none of the authenticators matches [#9496](https://github.com/emqx/emqx/pull/9496).
|
passes execution to the further callbacks if none of the authenticators matches [#9496](https://github.com/emqx/emqx/pull/9496).
|
||||||
|
|
||||||
|
- Return `400` if query param `node` is not a known in `/trace/:id/download?node={node}` [#9478](https://github.com/emqx/emqx/pull/9478).
|
||||||
|
|
|
@ -37,3 +37,5 @@
|
||||||
- 修复了 EMQX Helm Chart 通过环境变量修改部分 EMQX 的配置项时的错误
|
- 修复了 EMQX Helm Chart 通过环境变量修改部分 EMQX 的配置项时的错误
|
||||||
|
|
||||||
- 通过 `emqx_authenticator` 修复隐藏 `'client.authenticate'` 回调。 现在 `emqx_authenticator` 如果没有任何验证器匹配,则将执行传递给进一步的回调 [#9496](https://github.com/emqx/emqx/pull/9496)。
|
- 通过 `emqx_authenticator` 修复隐藏 `'client.authenticate'` 回调。 现在 `emqx_authenticator` 如果没有任何验证器匹配,则将执行传递给进一步的回调 [#9496](https://github.com/emqx/emqx/pull/9496)。
|
||||||
|
|
||||||
|
- 如果在调用 `/trace/:id/download?node={node}` 时,`node` 不存在,则会返回 `400` [#9478](https://github.com/emqx/emqx/pull/9478).
|
||||||
|
|
Loading…
Reference in New Issue