1 /*
2 * Copyright (c) 2022 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 "send_context.h"
17
18 #include "constant.h"
19 #include "netstack_log.h"
20 #include "napi_utils.h"
21 #include "securec.h"
22
23 static constexpr size_t MAX_LIMIT = 5 * 1024 * 1024;
24
25 namespace OHOS::NetStack {
SendContext(napi_env env,EventManager * manager)26 SendContext::SendContext(napi_env env, EventManager *manager)
27 : BaseContext(env, manager), data(nullptr), length(0), protocol(LWS_WRITE_TEXT)
28 {
29 }
30
ParseParams(napi_value * params,size_t paramsCount)31 void SendContext::ParseParams(napi_value *params, size_t paramsCount)
32 {
33 if (!CheckParamsType(params, paramsCount)) {
34 NETSTACK_LOGE("SendContext Parse Failed");
35 if (paramsCount == FUNCTION_PARAM_ONE) {
36 if (NapiUtils::GetValueType(GetEnv(), params[0]) == napi_function) {
37 SetCallback(params[0]);
38 }
39 return;
40 }
41
42 if (paramsCount == FUNCTION_PARAM_TWO) {
43 if (NapiUtils::GetValueType(GetEnv(), params[1]) == napi_function) {
44 SetCallback(params[1]);
45 }
46 return;
47 }
48 return;
49 }
50
51 if (NapiUtils::GetValueType(GetEnv(), params[0]) == napi_string) {
52 NETSTACK_LOGI("SendContext NapiUtils::GetValueType(GetEnv(), params[0]) == napi_string");
53 std::string str = NapiUtils::GetStringFromValueUtf8(GetEnv(), params[0]);
54 // must have PRE and POST
55 size_t dataLen = LWS_SEND_BUFFER_PRE_PADDING + str.length() + LWS_SEND_BUFFER_POST_PADDING;
56 if (dataLen == 0 || dataLen > MAX_LIMIT) {
57 NETSTACK_LOGE("SendContext data is exceeded the limit");
58 return;
59 }
60 data = malloc(dataLen);
61 if (data == nullptr) {
62 NETSTACK_LOGE("no memory");
63 return;
64 }
65 if (memcpy_s(reinterpret_cast<void *>(reinterpret_cast<uint8_t *>(data) + LWS_SEND_BUFFER_PRE_PADDING),
66 str.length(), str.c_str(), str.length()) < 0) {
67 NETSTACK_LOGE("copy failed");
68 return;
69 }
70 length = str.length();
71 protocol = LWS_WRITE_TEXT;
72 } else {
73 NETSTACK_LOGI("SendContext data is ArrayBuffer");
74 size_t len = 0;
75 void *mem = NapiUtils::GetInfoFromArrayBufferValue(GetEnv(), params[0], &len);
76 if (mem == nullptr || len == 0) {
77 NETSTACK_LOGE("no memory");
78 return;
79 }
80 // must have PRE and POST
81 size_t dataLen = LWS_SEND_BUFFER_PRE_PADDING + len + LWS_SEND_BUFFER_POST_PADDING;
82 if (dataLen == 0 || dataLen > MAX_LIMIT) {
83 NETSTACK_LOGE("SendContext data is exceeded the limit");
84 return;
85 }
86 data = malloc(dataLen);
87 if (data == nullptr) {
88 NETSTACK_LOGE("no memory");
89 return;
90 }
91 if (memcpy_s(reinterpret_cast<void *>(reinterpret_cast<uint8_t *>(data) + LWS_SEND_BUFFER_PRE_PADDING), len,
92 mem, len) < 0) {
93 NETSTACK_LOGE("copy failed");
94 return;
95 }
96 length = len;
97 protocol = LWS_WRITE_BINARY;
98 }
99
100 if (NapiUtils::GetValueType(GetEnv(), params[1]) == napi_function) {
101 NETSTACK_LOGI("SendContext NapiUtils::GetValueType(GetEnv(), params[1]) == napi_function");
102 return SetParseOK(SetCallback(params[1]) == napi_ok);
103 }
104
105 NETSTACK_LOGI("SendContext SetParseOK");
106 return SetParseOK(true);
107 }
108
CheckParamsType(napi_value * params,size_t paramsCount)109 bool SendContext::CheckParamsType(napi_value *params, size_t paramsCount)
110 {
111 if (paramsCount == FUNCTION_PARAM_ONE) {
112 return NapiUtils::GetValueType(GetEnv(), params[0]) == napi_string ||
113 NapiUtils::ValueIsArrayBuffer(GetEnv(), params[0]);
114 }
115
116 if (paramsCount == FUNCTION_PARAM_TWO) {
117 return (NapiUtils::GetValueType(GetEnv(), params[0]) == napi_string ||
118 NapiUtils::ValueIsArrayBuffer(GetEnv(), params[0])) &&
119 NapiUtils::GetValueType(GetEnv(), params[1]) == napi_function;
120 }
121
122 return false;
123 }
124
GetErrorCode() const125 int32_t SendContext::GetErrorCode() const
126 {
127 if (BaseContext::IsPermissionDenied()) {
128 return PERMISSION_DENIED_CODE;
129 }
130
131 auto err = BaseContext::GetErrorCode();
132 if (err == PARSE_ERROR_CODE) {
133 return PARSE_ERROR_CODE;
134 }
135 if (WEBSOCKET_ERR_MAP.find(err) != WEBSOCKET_ERR_MAP.end()) {
136 return err;
137 }
138 return WEBSOCKET_UNKNOWN_OTHER_ERROR;
139 }
140
GetErrorMessage() const141 std::string SendContext::GetErrorMessage() const
142 {
143 if (BaseContext::IsPermissionDenied()) {
144 return PERMISSION_DENIED_MSG;
145 }
146
147 auto err = BaseContext::GetErrorCode();
148 if (err == PARSE_ERROR_CODE) {
149 return PARSE_ERROR_MSG;
150 }
151 auto it = WEBSOCKET_ERR_MAP.find(err);
152 if (it != WEBSOCKET_ERR_MAP.end()) {
153 return it->second;
154 }
155 it = WEBSOCKET_ERR_MAP.find(WEBSOCKET_UNKNOWN_OTHER_ERROR);
156 if (it != WEBSOCKET_ERR_MAP.end()) {
157 return it->second;
158 }
159 return {};
160 }
161 } // namespace OHOS::NetStack
162