fix ssl_channel
This commit is contained in:
parent
67b14096c7
commit
32cc8367c7
@ -47,17 +47,16 @@
|
|||||||
}}}
|
}}}
|
||||||
```
|
```
|
||||||
|
|
||||||
`iot` 回复:
|
`iot` 鉴权成功时回复:
|
||||||
|
|
||||||
```erlang
|
```erlang
|
||||||
{response, Ref, {auth_response, ok}}
|
{response, Ref, {auth_response, ok}}
|
||||||
{response, Ref, {auth_response, {error, {failed, Reason}}}}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
处理语义:
|
处理语义:
|
||||||
|
|
||||||
- `ok`:`efka` 进入 `activated` 状态。
|
- `ok`:`efka` 进入 `activated` 状态。
|
||||||
- `{error, {failed, Reason}}`:鉴权失败,连接关闭后重连。
|
- 鉴权失败、host 不存在、host 未启动或 attach channel 失败时,`iot` 不返回业务错误响应,直接关闭连接;`efka` 通过 socket close/error 或 auth timeout 进入重连流程。
|
||||||
|
|
||||||
## 授权控制
|
## 授权控制
|
||||||
|
|
||||||
|
|||||||
@ -22,6 +22,7 @@
|
|||||||
|
|
||||||
%% API
|
%% API
|
||||||
-export([start_link/2, get_name/1, get_alias_name/1, get_pid/1, handle/2, activate/2]).
|
-export([start_link/2, get_name/1, get_alias_name/1, get_pid/1, handle/2, activate/2]).
|
||||||
|
-export([lookup_pid/1]).
|
||||||
-export([get_metric/1, get_status/1, kill/1]).
|
-export([get_metric/1, get_status/1, kill/1]).
|
||||||
%% 通讯相关
|
%% 通讯相关
|
||||||
-export([pub/4, attach_channel/2]).
|
-export([pub/4, attach_channel/2]).
|
||||||
@ -52,6 +53,15 @@ get_pid(UUID) when is_binary(UUID) ->
|
|||||||
Name = get_name(UUID),
|
Name = get_name(UUID),
|
||||||
gproc:whereis_name({n, l, Name}).
|
gproc:whereis_name({n, l, Name}).
|
||||||
|
|
||||||
|
-spec lookup_pid(UUID :: binary()) -> {ok, pid()} | {error, Reason :: any()}.
|
||||||
|
lookup_pid(UUID) when is_binary(UUID) ->
|
||||||
|
case get_pid(UUID) of
|
||||||
|
undefined ->
|
||||||
|
{error, <<"host not found">>};
|
||||||
|
HostPid ->
|
||||||
|
{ok, HostPid}
|
||||||
|
end.
|
||||||
|
|
||||||
-spec get_name(UUID :: binary()) -> term().
|
-spec get_name(UUID :: binary()) -> term().
|
||||||
get_name(UUID) when is_binary(UUID) ->
|
get_name(UUID) when is_binary(UUID) ->
|
||||||
{iot_host, UUID}.
|
{iot_host, UUID}.
|
||||||
|
|||||||
@ -176,40 +176,17 @@ handle_request_frame(Ref, {auth_request, #{uuid := UUID}}, State = #state{is_aut
|
|||||||
logger:warning("[ws_channel] repeated auth request, ref: ~p, uuid: ~p, close channel", [Ref, UUID]),
|
logger:warning("[ws_channel] repeated auth request, ref: ~p, uuid: ~p, close channel", [Ref, UUID]),
|
||||||
{stop, repeated_auth, State};
|
{stop, repeated_auth, State};
|
||||||
handle_request_frame(Ref, {auth_request, #{uuid := UUID, token := Token, timestamp := Timestamp}}, State = #state{transport = Transport, socket = Socket}) ->
|
handle_request_frame(Ref, {auth_request, #{uuid := UUID, token := Token, timestamp := Timestamp}}, State = #state{transport = Transport, socket = Socket}) ->
|
||||||
logger:debug("[ws_channel] auth uuid: ~p", [UUID]),
|
maybe
|
||||||
case auth(Token, UUID, Timestamp) of
|
ok ?= auth(Token, UUID, Timestamp),
|
||||||
ok ->
|
{ok, HostPid} ?= iot_host:lookup_pid(UUID),
|
||||||
case iot_api_client:get_host_by_uuid(UUID) of
|
ok ?= iot_host:attach_channel(HostPid, self()),
|
||||||
undefined ->
|
|
||||||
logger:warning("[ws_channel] uuid: ~p, token: ~p, host not found", [UUID, Token]),
|
|
||||||
stop_after_reply(Transport, Socket, Ref, {auth_response, {error, {failed, <<"host not found">>}}}, normal, State);
|
|
||||||
{ok, _} ->
|
|
||||||
%% 尝试启动主机的服务进程
|
|
||||||
case iot_host_sup:ensured_host_started(UUID) of
|
|
||||||
{ok, HostPid} ->
|
|
||||||
case iot_host:attach_channel(HostPid, self()) of
|
|
||||||
ok ->
|
|
||||||
erlang:monitor(process, HostPid),
|
erlang:monitor(process, HostPid),
|
||||||
case send_reply_frame(Transport, Socket, Ref, {auth_response, ok}) of
|
ok ?= send_reply_frame(Transport, Socket, Ref, {auth_response, ok}),
|
||||||
ok ->
|
logger:debug("[ws_channel] auth uuid: ~p", [UUID]),
|
||||||
{noreply, State#state{uuid = UUID, is_authed = true, host_pid = HostPid}};
|
{noreply, State#state{uuid = UUID, is_authed = true, host_pid = HostPid}}
|
||||||
{error, Reason} ->
|
else {error, Reason} ->
|
||||||
logger:warning("[ws_channel] uuid: ~p, send auth response failed: ~p", [UUID, Reason]),
|
logger:warning("[ws_channel] uuid: ~p, auth failed with reason: ~p", [UUID, Reason]),
|
||||||
{stop, {send_failed, Reason}, State}
|
{stop, Reason, State}
|
||||||
end;
|
|
||||||
{error, Reason} when is_binary(Reason) ->
|
|
||||||
logger:debug("[ws_channel] uuid: ~p, attach channel get error: ~p, stop channel", [UUID, Reason]),
|
|
||||||
stop_after_reply(Transport, Socket, Ref, {auth_response, {error, {failed, Reason}}}, Reason, State)
|
|
||||||
end;
|
|
||||||
{error, Reason} ->
|
|
||||||
logger:warning("[ws_channel] uuid: ~p, ensure host failed: ~p", [UUID, Reason]),
|
|
||||||
ReasonBin = reason_to_binary(Reason),
|
|
||||||
stop_after_reply(Transport, Socket, Ref, {auth_response, {error, {failed, ReasonBin}}}, Reason, State)
|
|
||||||
end
|
|
||||||
end;
|
|
||||||
{error, Reason} ->
|
|
||||||
logger:warning("[ws_channel] uuid: ~p, token: ~p, auth failed, reason: ~p", [UUID, Token, Reason]),
|
|
||||||
stop_after_reply(Transport, Socket, Ref, {auth_response, {error, {failed, Reason}}}, Reason, State)
|
|
||||||
end;
|
end;
|
||||||
handle_request_frame(Ref, {container, ContainerCommand}, State) ->
|
handle_request_frame(Ref, {container, ContainerCommand}, State) ->
|
||||||
logger:warning("[ws_channel] unsupported request message type: container, ref: ~p, command: ~p", [Ref, ContainerCommand]),
|
logger:warning("[ws_channel] unsupported request message type: container, ref: ~p, command: ~p", [Ref, ContainerCommand]),
|
||||||
@ -257,16 +234,6 @@ send_reply_frame(Transport, Socket, Ref, Reply) ->
|
|||||||
Packet = term_to_binary({response, Ref, Reply}),
|
Packet = term_to_binary({response, Ref, Reply}),
|
||||||
Transport:send(Socket, Packet).
|
Transport:send(Socket, Packet).
|
||||||
|
|
||||||
-spec stop_after_reply(module(), any(), reference(), tuple(), term(), #state{}) -> {stop, term(), #state{}}.
|
|
||||||
stop_after_reply(Transport, Socket, Ref, Reply, StopReason, State) ->
|
|
||||||
case send_reply_frame(Transport, Socket, Ref, Reply) of
|
|
||||||
ok ->
|
|
||||||
{stop, StopReason, State};
|
|
||||||
{error, Reason} ->
|
|
||||||
logger:warning("[ws_channel] send response before stop failed, ref: ~p, reason: ~p", [Ref, Reason]),
|
|
||||||
{stop, {send_failed, Reason}, State}
|
|
||||||
end.
|
|
||||||
|
|
||||||
-spec decode_command_response({container, ok | {ok, term()} | {error, term()}} | tuple()) ->
|
-spec decode_command_response({container, ok | {ok, term()} | {error, term()}} | tuple()) ->
|
||||||
ok | {ok, term()} | {error, term()}.
|
ok | {ok, term()} | {error, term()}.
|
||||||
decode_command_response({container, ok}) ->
|
decode_command_response({container, ok}) ->
|
||||||
@ -327,9 +294,3 @@ auth(Token, UUID, Timestamp) when is_binary(Token), is_binary(UUID), is_integer(
|
|||||||
false ->
|
false ->
|
||||||
{error, <<"invalid timestamp">>}
|
{error, <<"invalid timestamp">>}
|
||||||
end.
|
end.
|
||||||
|
|
||||||
-spec reason_to_binary(term()) -> binary().
|
|
||||||
reason_to_binary(Reason) when is_binary(Reason) ->
|
|
||||||
Reason;
|
|
||||||
reason_to_binary(Reason) ->
|
|
||||||
unicode:characters_to_binary(io_lib:format("~p", [Reason])).
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user