• 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_controller.h"
17 
18 #include <js_native_api.h>
19 #include <js_native_api_types.h>
20 #include <napi/native_api.h>
21 #include <cstring>
22 #include "napi_parse_utils.h"
23 
24 #include "nweb_helper.h"
25 #include "nweb_log.h"
26 #include "business_error.h"
27 #include "web_errors.h"
28 
29 #include "proxy_config.h"
30 #include "proxy_rule.h"
31 
32 
33 namespace OHOS {
34 namespace NWeb {
35 
JS_Constructor(napi_env env,napi_callback_info info)36 napi_value NapiProxyController::JS_Constructor(napi_env env, napi_callback_info info)
37 {
38     WVLOG_I("[PROXYCONTROLLER] NapiProxyController::JS_Constructor");
39     size_t argc = 1;
40     napi_value argv[1] = {0};
41     napi_value thisVar = nullptr;
42     void *data = nullptr;
43     napi_get_cb_info(env, info, &argc, argv, &thisVar, &data);
44 
45     return thisVar;
46 }
47 
Init(napi_env env,napi_value exports)48 napi_value NapiProxyController::Init(napi_env env, napi_value exports)
49 {
50     napi_property_descriptor properties[] = {
51         DECLARE_NAPI_STATIC_FUNCTION("applyProxyOverride", NapiProxyController::JS_ApplyProxyOverride),
52         DECLARE_NAPI_STATIC_FUNCTION("removeProxyOverride", NapiProxyController::JS_RemoveProxyOverride),
53     };
54 
55     napi_value proxyController = nullptr;
56     napi_define_class(env, PROXY_CONTROLLER_CLASS_NAME.c_str(), PROXY_CONTROLLER_CLASS_NAME.length(),
57         JS_Constructor, nullptr, sizeof(properties) / sizeof(properties[0]), properties, &proxyController);
58     napi_status status = napi_set_named_property(env, exports, "ProxyController", proxyController);
59     NAPI_ASSERT(env, status == napi_ok, "NapiProxyController set property failed.");
60 
61     return exports;
62 }
63 
InnerApplyProxyOverride(ProxyConfig * proxyConfig,napi_env env,napi_ref jsCallback)64 void NapiProxyController::InnerApplyProxyOverride(ProxyConfig *proxyConfig, napi_env env, napi_ref jsCallback)
65 {
66     std::vector<std::string> proxyUrls;
67     std::vector<std::string> proxySchemeFilters;
68     std::vector<std::string> bypassRules;
69     bool reverseBypass;
70     for (auto proxyRule : proxyConfig->GetProxyRules()) {
71         WVLOG_I("[PROXYCONTROLLER] add proxy rule %{public}s : %{public}d",
72                 proxyRule.GetUrl().c_str(), proxyRule.GetSchemeFilter());
73         proxyUrls.push_back(proxyRule.GetUrl());
74         std::string proxySchemeFilter = "*";
75         switch (proxyRule.GetSchemeFilter()) {
76             case static_cast<int32_t>(ProxySchemeFilter::MATCH_ALL_SCHEMES):
77                 break;
78             case static_cast<int32_t>(ProxySchemeFilter::MATCH_HTTP):
79                 proxySchemeFilter = "http";
80                 break;
81             case static_cast<int32_t>(ProxySchemeFilter::MATCH_HTTPS):
82                 proxySchemeFilter = "https";
83                 break;
84         }
85         proxySchemeFilters.push_back(proxySchemeFilter);
86     }
87     reverseBypass = proxyConfig->IsReverseBypassEnabled();
88     WVLOG_I("[PROXYCONTROLLER] reverse bypass  %{public}d", reverseBypass);
89     for (auto bypassRule :proxyConfig->GetBypassRules()) {
90         WVLOG_I("[PROXYCONTROLLER] add bypass rule %{public}s", bypassRule.c_str());
91         bypassRules.push_back(bypassRule);
92     }
93 
94     auto resultCallback = std::make_shared<ProxyChangedCallbackImpl>(env, jsCallback);
95     NWebHelper::Instance().SetProxyOverride(proxyUrls, proxySchemeFilters, bypassRules,
96                                             reverseBypass, resultCallback);
97 }
98 
OnChanged()99 void ProxyChangedCallbackImpl::OnChanged()
100 {
101     napi_value callback = nullptr;
102     napi_get_reference_value(env_, callback_, &callback);
103 
104     napi_call_function(env_, nullptr, callback, INTEGER_ZERO, nullptr, nullptr);
105     napi_delete_reference(env_, callback_);
106 }
107 
JS_ApplyProxyOverride(napi_env env,napi_callback_info info)108 napi_value NapiProxyController::JS_ApplyProxyOverride(napi_env env, napi_callback_info info)
109 {
110     napi_value thisVar = nullptr;
111     size_t argc = INTEGER_TWO;
112     size_t argcCallback = INTEGER_TWO;
113     napi_value argv[INTEGER_TWO] = {0};
114 
115     WVLOG_I("[PROXYCONTROLLER] apply proxy override.");
116     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
117     if (argc != INTEGER_TWO) {
118         WVLOG_E("[PROXYCONTROLLER] param check error.");
119         NWebError::BusinessError::ThrowErrorByErrcode(env, NWebError::PARAM_CHECK_ERROR);
120         return nullptr;
121     }
122 
123     napi_valuetype valueType = napi_null;
124     napi_typeof(env, argv[argcCallback - 1], &valueType);
125     if (valueType != napi_function) {
126         WVLOG_E("[PROXYCONTROLLER] last arg is not function %{public}d.", valueType);
127         NWebError::BusinessError::ThrowErrorByErrcode(env, NWebError::PARAM_CHECK_ERROR,
128             NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "callback", "function"));
129         return nullptr;
130     }
131 
132     napi_ref jsCallback = nullptr;
133     napi_create_reference(env, argv[argcCallback - 1], INTEGER_ONE, &jsCallback);
134     if (!jsCallback) {
135         WVLOG_E("[PROXYCONTROLLER] generate reference for callback failed.");
136         NWebError::BusinessError::ThrowErrorByErrcode(env, NWebError::PARAM_CHECK_ERROR,
137             NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "callback", "function"));
138         return nullptr;
139     }
140 
141     ProxyConfig *proxyConfig = nullptr;
142     napi_unwrap(env, argv[0], (void **)&proxyConfig);
143 
144     if (!proxyConfig) {
145         WVLOG_E("[PROXYCONTROLLER] unwrap ProxyConfig failed.");
146         napi_delete_reference(env, jsCallback);
147         return nullptr;
148     }
149 
150     InnerApplyProxyOverride(proxyConfig, env, jsCallback);
151 
152     return nullptr;
153 }
154 
JS_RemoveProxyOverride(napi_env env,napi_callback_info info)155 napi_value NapiProxyController::JS_RemoveProxyOverride(napi_env env, napi_callback_info info)
156 {
157     napi_value thisVar = nullptr;
158     size_t argc = INTEGER_ONE;
159     size_t argcCallback = INTEGER_ONE;
160     napi_value argv[INTEGER_ONE] = {0};
161 
162     napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr);
163     if (argc != INTEGER_ONE) {
164         NWebError::BusinessError::ThrowErrorByErrcode(env, NWebError::PARAM_CHECK_ERROR);
165         return nullptr;
166     }
167 
168     napi_valuetype valueType = napi_null;
169     napi_typeof(env, argv[argcCallback - 1], &valueType);
170     if (valueType != napi_function) {
171         NWebError::BusinessError::ThrowErrorByErrcode(env, NWebError::PARAM_CHECK_ERROR,
172             NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "callback", "function"));
173         return nullptr;
174     }
175 
176     napi_ref jsCallback = nullptr;
177     napi_create_reference(env, argv[argcCallback - 1], INTEGER_ONE, &jsCallback);
178     if (!jsCallback) {
179         NWebError::BusinessError::ThrowErrorByErrcode(env, NWebError::PARAM_CHECK_ERROR,
180             NWebError::FormatString(ParamCheckErrorMsgTemplate::TYPE_ERROR, "callback", "function"));
181         return nullptr;
182     }
183 
184     auto resultCallback = std::make_shared<ProxyChangedCallbackImpl>(env, jsCallback);
185     NWebHelper::Instance().RemoveProxyOverride(resultCallback);
186 
187     return nullptr;
188 }
189 } // namespace NWeb
190 } // namespace OHOS