• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 "napi_proxy_config.h"
17 
18 #include <js_native_api.h>
19 #include <js_native_api_types.h>
20 #include <napi/native_api.h>
21 #include <securec.h>
22 
23 #include "business_error.h"
24 #include "nweb_log.h"
25 #include "napi_parse_utils.h"
26 #include "napi/native_node_api.h"
27 #include "web_errors.h"
28 
29 #include "proxy_config.h"
30 #include "proxy_rule.h"
31 #include "napi_proxy_rule.h"
32 
33 using namespace OHOS::NWebError;
34 
35 namespace OHOS {
36 namespace NWeb {
37 
JS_InsertBypassRule(napi_env env,napi_callback_info info)38 napi_value NapiProxyConfig::JS_InsertBypassRule(napi_env env, napi_callback_info info)
39 {
40     size_t argc = 1;
41     napi_value argv[1] = {0};
42     napi_value thisVar = nullptr;
43     void *data = nullptr;
44     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
45 
46     ProxyConfig *proxyConfig = nullptr;
47     napi_unwrap(env, thisVar, (void **)&proxyConfig);
48 
49     if (!proxyConfig) {
50         WVLOG_E("[PROXYCONTROLLER] unwrap ProxyConfig failed.");
51         return nullptr;
52     }
53 
54     std::string bypassRule;
55     if (!NapiParseUtils::ParseString(env, argv[0], bypassRule)) {
56         BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
57             NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "bypassRule", "string"));
58         return nullptr;
59     }
60 
61     WVLOG_I("[PROXYCONTROLLER] insert bypass rule %{public}s.", bypassRule.c_str());
62     proxyConfig->InsertBypassRule(bypassRule);
63     return nullptr;
64 }
65 
JS_InsertDirectRule(napi_env env,napi_callback_info info)66 napi_value NapiProxyConfig::JS_InsertDirectRule(napi_env env, napi_callback_info info)
67 {
68     size_t argc = 1;
69     napi_value argv[1] = {0};
70     napi_value thisVar = nullptr;
71     void *data = nullptr;
72     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
73 
74     ProxyConfig *proxyConfig = nullptr;
75     napi_unwrap(env, thisVar, (void **)&proxyConfig);
76 
77     if (!proxyConfig) {
78         WVLOG_E("[PROXYCONTROLLER] unwrap ProxyConfig failed.");
79         return nullptr;
80     }
81 
82     if (argc > 0) {
83         int32_t schemeFilter = 0;
84         if (!NapiParseUtils::ParseInt32(env, argv[0], schemeFilter)) {
85             WVLOG_E("[PROXYCONTROLLER] parse int32 failed");
86             BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
87                 "BusinessError 401: Parameter error. The type of 'schemeFilter' must be int.");
88             return nullptr;
89         }
90 
91         WVLOG_I("[PROXYCONTROLLER] insert direct rule %{public}d.", schemeFilter);
92         proxyConfig->InsertDirectRule(schemeFilter);
93     } else {
94         WVLOG_I("[PROXYCONTROLLER] insert default direct rule.");
95         proxyConfig->InsertDirectRule();
96     }
97 
98     return nullptr;
99 }
100 
JS_InsertProxyRule(napi_env env,napi_callback_info info)101 napi_value NapiProxyConfig::JS_InsertProxyRule(napi_env env, napi_callback_info info)
102 {
103     size_t argc = 2;
104     napi_value argv[2] = {0};
105     napi_value thisVar = nullptr;
106     void *data = nullptr;
107     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
108 
109     ProxyConfig *proxyConfig = nullptr;
110     napi_unwrap(env, thisVar, (void **)&proxyConfig);
111 
112     if (!proxyConfig) {
113         WVLOG_E("[PROXYCONTROLLER] unwrap ProxyConfig failed.");
114         return nullptr;
115     }
116 
117     std::string proxyUrl;
118     if (!NapiParseUtils::ParseString(env, argv[0], proxyUrl)) {
119         BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
120             NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "proxyUrl", "string"));
121         return nullptr;
122     }
123     if (argc > 1) {
124         int32_t schemeFilter = 0;
125         if (!NapiParseUtils::ParseInt32(env, argv[1], schemeFilter)) {
126             WVLOG_E("[PROXYCONTROLLER] parse int32 failed");
127             BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
128                 "BusinessError 401: Parameter error. The type of 'schemeFilter' must be int.");
129             return nullptr;
130         }
131 
132         WVLOG_I("[PROXYCONTROLLER] insert proxy rule %{public}s : %{public}d.", proxyUrl.c_str(), schemeFilter);
133         proxyConfig->InsertProxyRule(proxyUrl, schemeFilter);
134     } else {
135         WVLOG_I("[PROXYCONTROLLER] insert proxy rule, the schemeFilter is default.");
136         proxyConfig->InsertProxyRule(proxyUrl);
137     }
138 
139     return nullptr;
140 }
141 
JS_BypassHostnamesWithoutPeriod(napi_env env,napi_callback_info info)142 napi_value NapiProxyConfig::JS_BypassHostnamesWithoutPeriod(napi_env env, napi_callback_info info)
143 {
144     napi_value thisVar = nullptr;
145     void *data = nullptr;
146     napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, &data);
147 
148     ProxyConfig *proxyConfig = nullptr;
149     napi_unwrap(env, thisVar, (void **)&proxyConfig);
150 
151     if (!proxyConfig) {
152         WVLOG_E("[PROXYCONTROLLER] unwrap ProxyConfig failed.");
153         return nullptr;
154     }
155 
156     WVLOG_I("[PROXYCONTROLLER] bypass host names without period.");
157     proxyConfig->BypassHostnamesWithoutPeriod();
158     return nullptr;
159 }
160 
JS_ClearImplicitRules(napi_env env,napi_callback_info info)161 napi_value NapiProxyConfig::JS_ClearImplicitRules(napi_env env, napi_callback_info info)
162 {
163     napi_value thisVar = nullptr;
164     void *data = nullptr;
165     napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, &data);
166 
167     ProxyConfig *proxyConfig = nullptr;
168     napi_unwrap(env, thisVar, (void **)&proxyConfig);
169 
170     if (!proxyConfig) {
171         WVLOG_E("[PROXYCONTROLLER] unwrap ProxyConfig failed.");
172         return nullptr;
173     }
174 
175     WVLOG_I("[PROXYCONTROLLER] clear implicit rules.");
176     proxyConfig->ClearImplicitRules();
177     return nullptr;
178 }
179 
JS_EnableReverseBypass(napi_env env,napi_callback_info info)180 napi_value NapiProxyConfig::JS_EnableReverseBypass(napi_env env, napi_callback_info info)
181 {
182     size_t argc = 1;
183     napi_value argv[1] = {0};
184     napi_value thisVar = nullptr;
185     void *data = nullptr;
186     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
187 
188     ProxyConfig *proxyConfig = nullptr;
189     napi_unwrap(env, thisVar, (void **)&proxyConfig);
190 
191     if (!proxyConfig) {
192         WVLOG_E("[PROXYCONTROLLER] unwrap ProxyConfig failed.");
193         return nullptr;
194     }
195 
196     bool enableReverseBypass = false;
197     if (!NapiParseUtils::ParseBoolean(env, argv[0], enableReverseBypass)) {
198         WVLOG_E("[PROXYCONTROLLER] parse boolean failed.");
199         BusinessError::ThrowErrorByErrcode(env, PARAM_CHECK_ERROR,
200             NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "enableReverseBypass", "boolean"));
201         return nullptr;
202     }
203 
204     WVLOG_I("[PROXYCONTROLLER] enable reverse bypass %{public}d.", enableReverseBypass);
205     proxyConfig->EnableReverseBypass(enableReverseBypass);
206     return nullptr;
207 }
208 
JS_GetBypassRules(napi_env env,napi_callback_info info)209 napi_value NapiProxyConfig::JS_GetBypassRules(napi_env env, napi_callback_info info)
210 {
211     size_t argc = 1;
212     napi_value argv[1] = {0};
213     napi_value thisVar = nullptr;
214     void *data = nullptr;
215     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
216 
217     ProxyConfig *proxyConfig = nullptr;
218     napi_unwrap(env, thisVar, (void **)&proxyConfig);
219 
220     if (!proxyConfig) {
221         WVLOG_E("[PROXYCONTROLLER] unwrap ProxyConfig failed.");
222         return nullptr;
223     }
224 
225     napi_value result;
226     napi_create_array(env, &result);
227     std::vector<std::string> bypassRules = proxyConfig->GetBypassRules();
228 
229     for (size_t index = 0; index < bypassRules.size(); index++) {
230         WVLOG_I("[PROXYCONTROLLER] get bypass rules %{public}s.", bypassRules[index].c_str());
231         napi_value jsBypassRule = nullptr;
232         napi_status status = napi_create_string_utf8(env, bypassRules[index].c_str(),
233                                                      bypassRules[index].length(), &jsBypassRule);
234         if (status != napi_ok) {
235             WVLOG_I("[PROXYCONTROLLER] create js string error");
236             continue;
237         }
238         NAPI_CALL(env, napi_set_element(env, result, index, jsBypassRule));
239     }
240 
241     return result;
242 }
243 
JS_GetProxyRules(napi_env env,napi_callback_info info)244 napi_value NapiProxyConfig::JS_GetProxyRules(napi_env env, napi_callback_info info)
245 {
246     size_t argc = 1;
247     napi_value argv[1] = {0};
248     napi_value thisVar = nullptr;
249     void *data = nullptr;
250     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
251 
252     ProxyConfig *proxyConfig = nullptr;
253     napi_unwrap(env, thisVar, (void **)&proxyConfig);
254 
255     if (!proxyConfig) {
256         WVLOG_E("[PROXYCONTROLLER] unwrap ProxyConfig failed");
257         return nullptr;
258     }
259 
260     napi_value result = nullptr;
261     napi_create_array(env, &result);
262     std::vector<ProxyRule> proxyRules = proxyConfig->GetProxyRules();
263     for (size_t index = 0; index < proxyRules.size(); index++) {
264         WVLOG_I("[PROXYCONTROLLER] get proxy rules %{public}s %{public}d",
265                 proxyRules[index].GetUrl().c_str(), proxyRules[index].GetSchemeFilter());
266         napi_value jsProxyRule = nullptr;
267         napi_create_object(env, &jsProxyRule);
268         napi_wrap(
269             env, jsProxyRule, new ProxyRule(proxyRules[index].GetUrl().c_str(), proxyRules[index].GetSchemeFilter()),
270             [](napi_env /* env */, void *data, void * /* hint */) {
271                 if (data) {
272                     ProxyRule *proxyRule = static_cast<ProxyRule *>(data);
273                     delete proxyRule;
274                 }
275             },
276             nullptr, nullptr);
277         NapiProxyRule::DefineProperties(env, &jsProxyRule);
278         NAPI_CALL(env, napi_set_element(env, result, index, jsProxyRule));
279     }
280 
281     return result;
282 }
283 
JS_IsReverseBypassEnabled(napi_env env,napi_callback_info info)284 napi_value NapiProxyConfig::JS_IsReverseBypassEnabled(napi_env env, napi_callback_info info)
285 {
286     size_t argc = 1;
287     napi_value argv[1] = {0};
288     napi_value thisVar = nullptr;
289     void *data = nullptr;
290     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
291 
292     ProxyConfig *proxyConfig = nullptr;
293     napi_unwrap(env, thisVar, (void **)&proxyConfig);
294 
295     if (!proxyConfig) {
296         WVLOG_E("[PROXYCONTROLLER] unwrap ProxyConfig failed");
297         return nullptr;
298     }
299 
300     napi_value result = nullptr;
301     bool enabled = proxyConfig->IsReverseBypassEnabled();
302     WVLOG_I("[PROXYCONTROLLER] is reverse bypass enabled %{public}d", enabled);
303     NAPI_CALL(env, napi_get_boolean(env, enabled, &result));
304     return result;
305 }
306 
Init(napi_env env,napi_value exports)307 napi_value NapiProxyConfig::Init(napi_env env, napi_value exports)
308 {
309     WVLOG_I("[PROXYCONTROLLER] NapiProxyConfig::Init is called");
310     napi_property_descriptor properties[] = {
311         DECLARE_NAPI_FUNCTION("insertBypassRule", NapiProxyConfig::JS_InsertBypassRule),
312         DECLARE_NAPI_FUNCTION("insertDirectRule", NapiProxyConfig::JS_InsertDirectRule),
313         DECLARE_NAPI_FUNCTION("insertProxyRule", NapiProxyConfig::JS_InsertProxyRule),
314         DECLARE_NAPI_FUNCTION("bypassHostnamesWithoutPeriod", NapiProxyConfig::JS_BypassHostnamesWithoutPeriod),
315         DECLARE_NAPI_FUNCTION("clearImplicitRules", NapiProxyConfig::JS_ClearImplicitRules),
316         DECLARE_NAPI_FUNCTION("enableReverseBypass", NapiProxyConfig::JS_EnableReverseBypass),
317         DECLARE_NAPI_FUNCTION("getBypassRules", NapiProxyConfig::JS_GetBypassRules),
318         DECLARE_NAPI_FUNCTION("getProxyRules", NapiProxyConfig::JS_GetProxyRules),
319         DECLARE_NAPI_FUNCTION("isReverseBypassEnabled", NapiProxyConfig::JS_IsReverseBypassEnabled),
320     };
321 
322     napi_value constructor = nullptr;
323     napi_define_class(env, PROXY_CONFIG_CLASS_NAME.c_str(), PROXY_CONFIG_CLASS_NAME.length(),
324         JS_Constructor, nullptr, sizeof(properties) / sizeof(properties[0]), properties, &constructor);
325     NAPI_ASSERT(env, constructor != nullptr, "NapiProxyConfig define js class failed.");
326     napi_status status = napi_set_named_property(env, exports, PROXY_CONFIG_CLASS_NAME.c_str(), constructor);
327     NAPI_ASSERT(env, status == napi_ok, "NapiProxyConfig set property failed.");
328 
329     return exports;
330 }
331 
JS_Constructor(napi_env env,napi_callback_info info)332 napi_value NapiProxyConfig::JS_Constructor(napi_env env, napi_callback_info info)
333 {
334     WVLOG_I("[PROXYCONTROLLER] NapiProxyConfig::JS_Constructor is called");
335     napi_value thisVar = nullptr;
336     void *data = nullptr;
337     napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, &data);
338 
339     ProxyConfig *nativeProxyConfig = new ProxyConfig();
340 
341     napi_wrap(
342         env, thisVar, nativeProxyConfig,
343         [](napi_env /* env */, void *data, void * /* hint */) {
344             ProxyConfig *proxyConfig = (ProxyConfig *)data;
345             delete proxyConfig;
346         },
347         nullptr, nullptr);
348 
349     return thisVar;
350 }
351 
352 }
353 }