1 /*
2 * Copyright (c) 2025-2025 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "server_close_context.h"
17 #include "constant.h"
18 #include "netstack_common_utils.h"
19 #include "netstack_log.h"
20 #include "napi_utils.h"
21
22 namespace OHOS::NetStack::Websocket {
ServerCloseContext(napi_env env,const std::shared_ptr<EventManager> & manager)23 ServerCloseContext::ServerCloseContext(napi_env env, const std::shared_ptr<EventManager> &manager)
24 : BaseContext(env, manager), code(CLOSE_REASON_NORMAL_CLOSE), reason("CLOSE_NORMAL"), connection() {}
25
26 ServerCloseContext::~ServerCloseContext() = default;
27
ParseParams(napi_value * params,size_t paramsCount)28 void ServerCloseContext::ParseParams(napi_value *params, size_t paramsCount)
29 {
30 if (!CheckParamsType(params, paramsCount)) {
31 NETSTACK_LOGE("ServerCloseContext Parse Failed");
32 if (paramsCount == FUNCTION_PARAM_ONE) {
33 if (NapiUtils::GetValueType(GetEnv(), params[0]) == napi_function) {
34 SetCallback(params[0]);
35 }
36 return;
37 }
38
39 if (paramsCount == FUNCTION_PARAM_TWO) {
40 if (NapiUtils::GetValueType(GetEnv(), params[1]) == napi_function) {
41 SetCallback(params[1]);
42 }
43 return;
44 }
45 return;
46 }
47
48 if (paramsCount == FUNCTION_PARAM_ONE) {
49 NETSTACK_LOGI("paramsCount is one");
50 if (!HandleParseConnection(GetEnv(), params[0])) {
51 return;
52 }
53 }
54
55 if (paramsCount == FUNCTION_PARAM_TWO) {
56 NETSTACK_LOGI("paramsCount is two");
57 if (!HandleParseConnection(GetEnv(), params[0])) {
58 return;
59 }
60 if (!HandleParseCloseOption(GetEnv(), params[1])) {
61 return;
62 }
63 }
64 NETSTACK_LOGI("ServerCloseContext Parse OK");
65 return SetParseOK(true);
66 }
67
HandleParseConnection(napi_env env,napi_value params)68 bool ServerCloseContext::HandleParseConnection(napi_env env, napi_value params)
69 {
70 NETSTACK_LOGI("HandleParseConnection enter");
71 if (NapiUtils::GetValueType(env, params) == napi_object) {
72 connection.clientPort = NapiUtils::GetUint32Property(env, params, ContextKey::CLIENT_PORT);
73 if (connection.clientPort == 0) {
74 NETSTACK_LOGE("parse clientPort failed");
75 }
76 connection.clientIP = NapiUtils::GetStringPropertyUtf8(env, params, ContextKey::CLIENT_IP);
77 if (connection.clientIP == "") {
78 NETSTACK_LOGE("parse clientIP failed");
79 }
80 return true;
81 }
82 return false;
83 }
84
HandleParseCloseOption(napi_env env,napi_value params)85 bool ServerCloseContext::HandleParseCloseOption(napi_env env, napi_value params)
86 {
87 if (NapiUtils::GetValueType(env, params) == napi_object) {
88 uint32_t closeCode = NapiUtils::GetUint32Property(env, params, ContextKey::CODE);
89 if (closeCode >= CLOSE_REASON_NORMAL_CLOSE && closeCode <= CLOSE_REASON_RESERVED12) {
90 code = closeCode;
91 }
92 std::string tempReason = NapiUtils::GetStringPropertyUtf8(env, params, ContextKey::REASON);
93 if (!tempReason.empty()) {
94 reason = tempReason;
95 }
96 return true;
97 }
98 return false;
99 }
100
CheckParamsType(napi_value * params,size_t paramsCount)101 bool ServerCloseContext::CheckParamsType(napi_value *params, size_t paramsCount)
102 {
103 if (paramsCount == FUNCTION_PARAM_ONE) {
104 NETSTACK_LOGI("paramsCount one");
105 return IsValidWebsocketConnection(GetEnv(), params[0]);
106 }
107
108 if (paramsCount == FUNCTION_PARAM_TWO) {
109 NETSTACK_LOGI("paramsCount two");
110 return IsValidWebsocketConnection(GetEnv(), params[0]) &&
111 IsValidCloseOptions(GetEnv(), params[1]);
112 }
113 return false;
114 }
115
IsValidWebsocketConnection(napi_env env,napi_value params)116 bool ServerCloseContext::IsValidWebsocketConnection(napi_env env, napi_value params)
117 {
118 if (NapiUtils::GetValueType(env, params) != napi_object) {
119 return false;
120 }
121 return (NapiUtils::GetValueType(env, NapiUtils::GetNamedProperty(env, params,
122 ContextKey::CLIENT_PORT)) == napi_number) && (NapiUtils::GetValueType(env,
123 NapiUtils::GetNamedProperty(env, params, ContextKey::CLIENT_IP)) == napi_string);
124 }
125
IsValidCloseOptions(napi_env env,napi_value params)126 bool ServerCloseContext::IsValidCloseOptions(napi_env env, napi_value params)
127 {
128 if (NapiUtils::GetValueType(env, params) != napi_object) {
129 return false;
130 }
131 return NapiUtils::GetValueType(env, NapiUtils::GetNamedProperty(env, params,
132 ContextKey::CODE)) == napi_number && NapiUtils::GetValueType(env,
133 NapiUtils::GetNamedProperty(env, params, ContextKey::REASON)) == napi_string;
134 }
135
GetConnection() const136 WebSocketConnection ServerCloseContext::GetConnection() const
137 {
138 return connection;
139 }
140
GetErrorCode() const141 int32_t ServerCloseContext::GetErrorCode() const
142 {
143 if (BaseContext::IsPermissionDenied()) {
144 return PERMISSION_DENIED_CODE;
145 }
146
147 auto err = BaseContext::GetErrorCode();
148 if (err == PARSE_ERROR_CODE) {
149 return PARSE_ERROR_CODE;
150 }
151 if (WEBSOCKET_ERR_MAP.find(err) != WEBSOCKET_ERR_MAP.end()) {
152 return err;
153 }
154 return WEBSOCKET_UNKNOWN_OTHER_ERROR;
155 }
156
GetErrorMessage() const157 std::string ServerCloseContext::GetErrorMessage() const
158 {
159 if (BaseContext::IsPermissionDenied()) {
160 return PERMISSION_DENIED_MSG;
161 }
162
163 auto err = BaseContext::GetErrorCode();
164 if (err == PARSE_ERROR_CODE) {
165 return PARSE_ERROR_MSG;
166 }
167 auto it = WEBSOCKET_ERR_MAP.find(err);
168 if (it != WEBSOCKET_ERR_MAP.end()) {
169 return it->second;
170 }
171 it = WEBSOCKET_ERR_MAP.find(WEBSOCKET_UNKNOWN_OTHER_ERROR);
172 if (it != WEBSOCKET_ERR_MAP.end()) {
173 return it->second;
174 }
175 return {};
176 }
177 } // namespace OHOS::NetStack::Websocket