From 616cad6dafb3404db73586d5987d491b522ccad7 Mon Sep 17 00:00:00 2001 From: anlicheng <244108715@qq.com> Date: Fri, 31 Oct 2025 12:04:15 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=E5=8F=82=E6=95=B0=E6=A0=A1?= =?UTF-8?q?=E9=AA=8C?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../src/http_handlers/container_handler.erl | 95 ++++++++++++------- .../http_handlers/event_stream_handler.erl | 5 +- 2 files changed, 62 insertions(+), 38 deletions(-) diff --git a/apps/iot/src/http_handlers/container_handler.erl b/apps/iot/src/http_handlers/container_handler.erl index 6293d06..4b14b74 100644 --- a/apps/iot/src/http_handlers/container_handler.erl +++ b/apps/iot/src/http_handlers/container_handler.erl @@ -63,21 +63,27 @@ handle_request("POST", "/container/push_config", _, handle_request("POST", "/container/deploy", _, #{<<"uuid">> := UUID, <<"task_id">> := TaskId, <<"config">> := Config}) when is_binary(UUID), is_integer(TaskId), is_map(Config) -> - case iot_host:get_pid(UUID) of - undefined -> - {ok, 200, iot_util:json_error(404, <<"host not found">>)}; - Pid when is_pid(Pid) -> - case iot_host:deploy_container(Pid, TaskId, Config) of - {ok, Ref} -> - case iot_host:await_reply(Ref, ?REQ_TIMEOUT) of - {ok, Result} -> - {ok, 200, iot_util:json_data(Result)}; - {error, Reason} -> + case validate_config(Config) of + ok -> + case iot_host:get_pid(UUID) of + undefined -> + {ok, 200, iot_util:json_error(404, <<"host not found">>)}; + Pid when is_pid(Pid) -> + case iot_host:deploy_container(Pid, TaskId, Config) of + {ok, Ref} -> + case iot_host:await_reply(Ref, ?REQ_TIMEOUT) of + {ok, Result} -> + {ok, 200, iot_util:json_data(Result)}; + {error, Reason} -> + {ok, 200, iot_util:json_error(400, Reason)} + end; + {error, Reason} when is_binary(Reason) -> {ok, 200, iot_util:json_error(400, Reason)} - end; - {error, Reason} when is_binary(Reason) -> - {ok, 200, iot_util:json_error(400, Reason)} - end + end + end; + {error, Errors} -> + Reason = iolist_to_binary(lists:join(<<"|||">>, Errors)), + {ok, 200, iot_util:json_error(400, Reason)} end; %% 启动服务 @@ -186,34 +192,34 @@ validate_config(Config) when is_map(Config) -> Required = [ {image, binary}, {container_name, binary}, - {command, list}, + {command, {list, binary}}, {restart, binary}, {privileged, boolean} ], %% 可选参数(附带默认值) Optional = [ - {envs, list}, - {ports, list}, - {expose, list}, - {volumes, list}, - {networks, list}, - {labels, map}, + {envs, {list, binary}}, + {ports, {list, binary}}, + {expose, {list, binary}}, + {volumes, {list, binary}}, + {networks, {list, binary}}, + {labels, {map, {binary, binary}}}, {user, binary}, {working_dir, binary}, {hostname, binary}, - {cap_add, list}, - {cap_drop, list}, - {devices, list}, + {cap_add, {list, binary}}, + {cap_drop, {list, binary}}, + {devices, {list, binary}}, {mem_limit, binary}, {mem_reservation, binary}, {cpu_shares, integer}, {cpus, number}, - {ulimits, map}, - {sysctls, map}, - {tmpfs, list}, - {extra_hosts, list}, - {healthcheck, map} + {ulimits, {map, {binary, binary}}}, + {sysctls, {map, {binary, binary}}}, + {tmpfs, {list, binary}}, + {extra_hosts, {list, binary}}, + {healthcheck, {map, {binary, any}}} ], Errors1 = check_required(Config, Required), @@ -273,10 +279,27 @@ check_optional(Config, Fields) -> %%------------------------------------------------------------------------------ %% 类型检查辅助函数(binary版) %%------------------------------------------------------------------------------ -check_type(Value, binary) -> is_binary(Value); -check_type(Value, integer) -> is_integer(Value); -check_type(Value, number) -> is_number(Value); -check_type(Value, list) -> is_list(Value); -check_type(Value, map) -> is_map(Value); -check_type(Value, boolean) -> is_boolean(Value); -check_type(_, _) -> false. \ No newline at end of file +check_type(Value, binary) -> + is_binary(Value); +check_type(Value, integer) -> + is_integer(Value); +check_type(Value, number) -> + is_number(Value); +check_type(Value, list) when is_list(Value) -> + true; +check_type(Value, {list, binary}) when is_list(Value) -> + lists:all(fun(E) -> is_binary(E) end, Value); +check_type(Value, {list, number}) when is_list(Value) -> + lists:all(fun(E) -> is_number(E) end, Value); +check_type(Value, {list, integer}) when is_list(Value) -> + lists:all(fun(E) -> is_integer(E) end, Value); +check_type(Value, map) when is_map(Value) -> + true; +check_type(Value, {map, {binary, binary}}) when is_map(Value) -> + lists:all(fun({K, V}) -> is_binary(K) andalso is_binary(V) end, maps:to_list(Value)); +check_type(Value, {map, {binary, any}}) when is_map(Value) -> + lists:all(fun({K, _}) -> is_binary(K) end, maps:to_list(Value)); +check_type(Value, boolean) -> + is_boolean(Value); +check_type(_, _) -> + false. \ No newline at end of file diff --git a/apps/iot/src/http_handlers/event_stream_handler.erl b/apps/iot/src/http_handlers/event_stream_handler.erl index 85efc84..5ca6bbb 100644 --- a/apps/iot/src/http_handlers/event_stream_handler.erl +++ b/apps/iot/src/http_handlers/event_stream_handler.erl @@ -23,8 +23,9 @@ init(Req0, Opts) -> lager:debug("method: ~p, path: ~p, get: ~p", [Method, Path, GetParams]), Req1 = cowboy_req:stream_reply(200, #{ - <<"content-type">> => <<"text/event-stream">>, - <<"cache-control">> => <<"no-cache">> + <<"Content-Type">> => <<"text/event-stream">>, + <<"Cache-Control">> => <<"no-cache">>, + <<"Connection">> => <<"keep-alive">> }, Req0), ok = iot_event_stream_observer:add_listener(self(), TaskId),