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 #include "native_module_uri.h"
16 
17 #include "js_uri.h"
18 #include "securec.h"
19 #include "tools/log.h"
20 #include "napi/native_api.h"
21 #include "napi/native_node_api.h"
22 
23 extern const char _binary_js_uri_js_start[];
24 extern const char _binary_js_uri_js_end[];
25 extern const char _binary_uri_abc_start[];
26 extern const char _binary_uri_abc_end[];
27 
28 namespace OHOS::Uri {
UriConstructor(napi_env env, napi_callback_info info)29     static napi_value UriConstructor(napi_env env, napi_callback_info info)
30     {
31         napi_value thisVar = nullptr;
32         void *data = nullptr;
33         size_t argc = 1;
34         napi_value argv[1] = { 0 };
35         Uri *object = nullptr;
36         NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, &data));
37         napi_valuetype valuetype;
38         NAPI_CALL(env, napi_typeof(env, argv[0], &valuetype));
39         if (valuetype == napi_string) {
40             std::string type = "";
41             size_t typelen = 0;
42             NAPI_CALL(env, napi_get_value_string_utf8(env, argv[0], nullptr, 0, &typelen));
43             type.resize(typelen);
44             NAPI_CALL(env, napi_get_value_string_utf8(env, argv[0], type.data(), typelen + 1, &typelen));
45             object = new (std::nothrow) Uri(type);
46             if (object == nullptr) {
47                 HILOG_ERROR("UriConstructor:: object is nullptr");
48                 return nullptr;
49             }
50         }
51         NAPI_CALL(env, napi_wrap(env, thisVar, object,
52             [](napi_env environment, void *data, void *hint) {
53             auto obj = reinterpret_cast<Uri*>(data);
54             if (obj != nullptr) {
55                 delete obj;
56             }
57         }, nullptr, nullptr));
58         return thisVar;
59     }
60 
Normalize(napi_env env, napi_callback_info info)61     static napi_value Normalize(napi_env env, napi_callback_info info)
62     {
63         napi_value thisVar = nullptr;
64         NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
65         Uri *muri = nullptr;
66         NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&muri)));
67         std::string normalizeUri = muri->Normalize();
68         napi_value result = nullptr;
69         size_t tempLen = normalizeUri.size();
70         NAPI_CALL(env, napi_create_string_utf8(env, normalizeUri.c_str(), tempLen, &result));
71         return result;
72     }
73 
Equals(napi_env env, napi_callback_info info)74     static napi_value Equals(napi_env env, napi_callback_info info)
75     {
76         napi_value thisVar = nullptr;
77         napi_value result = nullptr;
78         size_t argc = 1;
79         napi_value argv[1] = { 0 };
80         NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr));
81 
82         Uri *muri = nullptr;
83         NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&muri)));
84         Uri *other = nullptr;
85         NAPI_CALL(env, napi_unwrap(env, argv[0], reinterpret_cast<void**>(&other)));
86 
87         bool flag = muri->Equals(*other);
88         NAPI_CALL(env, napi_get_boolean(env, flag, &result));
89         return result;
90     }
91 
IsAbsolute(napi_env env, napi_callback_info info)92     static napi_value IsAbsolute(napi_env env, napi_callback_info info)
93     {
94         napi_value thisVar = nullptr;
95         napi_value result = nullptr;
96         NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
97         Uri *muri = nullptr;
98         NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&muri)));
99         bool flag = muri->IsAbsolute();
100         NAPI_CALL(env, napi_get_boolean(env, flag, &result));
101         return result;
102     }
103 
IsFailed(napi_env env, napi_callback_info info)104     static napi_value IsFailed(napi_env env, napi_callback_info info)
105     {
106         napi_value thisVar = nullptr;
107         napi_value result = nullptr;
108         NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
109         Uri *muri = nullptr;
110         NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&muri)));
111         std::string temp = muri->IsFailed();
112         size_t templen = temp.size();
113         NAPI_CALL(env, napi_create_string_utf8(env, temp.c_str(), templen, &result));
114         return result;
115     }
116 
UriToString(napi_env env, napi_callback_info info)117     static napi_value UriToString(napi_env env, napi_callback_info info)
118     {
119         napi_value thisVar = nullptr;
120         napi_value result = nullptr;
121         NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
122         Uri *muri = nullptr;
123         NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&muri)));
124         std::string temp = muri->ToString();
125         size_t templen = temp.size();
126         NAPI_CALL(env, napi_create_string_utf8(env, temp.c_str(), templen, &result));
127         return result;
128     }
129 
IsRelative(napi_env env, napi_callback_info info)130     static napi_value IsRelative(napi_env env, napi_callback_info info)
131     {
132         napi_value thisVar = nullptr;
133         napi_value result = nullptr;
134         NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
135         Uri *muri = nullptr;
136         NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&muri)));
137         bool flag = muri->IsRelative();
138         NAPI_CALL(env, napi_get_boolean(env, flag, &result));
139         return result;
140     }
141 
IsOpaque(napi_env env, napi_callback_info info)142     static napi_value IsOpaque(napi_env env, napi_callback_info info)
143     {
144         napi_value thisVar = nullptr;
145         napi_value result = nullptr;
146         NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
147         Uri *muri = nullptr;
148         NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&muri)));
149         bool flag = muri->IsOpaque();
150         NAPI_CALL(env, napi_get_boolean(env, flag, &result));
151         return result;
152     }
153 
IsHierarchical(napi_env env, napi_callback_info info)154     static napi_value IsHierarchical(napi_env env, napi_callback_info info)
155     {
156         napi_value thisVar = nullptr;
157         napi_value result = nullptr;
158         NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
159         Uri *muri = nullptr;
160         NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&muri)));
161         bool flag = muri->IsHierarchical();
162         NAPI_CALL(env, napi_get_boolean(env, flag, &result));
163         return result;
164     }
165 
AddQueryValue(napi_env env, napi_callback_info info)166     static napi_value AddQueryValue(napi_env env, napi_callback_info info)
167     {
168         napi_value thisVar = nullptr;
169         napi_value result = nullptr;
170         size_t argc = 2;
171         napi_value argv[2] = { nullptr };
172         NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr));
173         Uri *muri = nullptr;
174         NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&muri)));
175         std::string key = "";
176         size_t keyLen = 0;
177         NAPI_CALL(env, napi_get_value_string_utf8(env, argv[0], nullptr, 0, &keyLen));
178         key.resize(keyLen);
179         NAPI_CALL(env, napi_get_value_string_utf8(env, argv[0], key.data(), keyLen + 1, &keyLen));
180         std::string value = "";
181         size_t valueLen = 0;
182         NAPI_CALL(env, napi_get_value_string_utf8(env, argv[1], nullptr, 0, &valueLen));
183         value.resize(valueLen);
184         NAPI_CALL(env, napi_get_value_string_utf8(env, argv[1], value.data(), valueLen + 1, &valueLen));
185         std::string temp = muri->AddQueryValue(key, value);
186         if (temp.empty()) {
187             napi_get_null(env, &result);
188             return result;
189         }
190         size_t templen = temp.size();
191         NAPI_CALL(env, napi_create_string_utf8(env, temp.c_str(), templen, &result));
192         return result;
193     }
194 
AddSegment(napi_env env, napi_callback_info info)195     static napi_value AddSegment(napi_env env, napi_callback_info info)
196     {
197         napi_value thisVar = nullptr;
198         napi_value result = nullptr;
199         size_t argc = 1;
200         napi_value argv[1] = { nullptr };
201         NAPI_CALL(env, napi_get_cb_info(env, info, &argc, argv, &thisVar, nullptr));
202         Uri *muri = nullptr;
203         NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&muri)));
204         std::string segment = "";
205         size_t segmentLen = 0;
206         NAPI_CALL(env, napi_get_value_string_utf8(env, argv[0], nullptr, 0, &segmentLen));
207         segment.resize(segmentLen);
208         NAPI_CALL(env, napi_get_value_string_utf8(env, argv[0], segment.data(), segmentLen + 1, &segmentLen));
209         std::string temp = muri->AddSegment(segment);
210         if (temp.empty()) {
211             napi_get_null(env, &result);
212             return result;
213         }
214         size_t tempLen = temp.size();
215         NAPI_CALL(env, napi_create_string_utf8(env, temp.c_str(), tempLen, &result));
216         return result;
217     }
218 
GetSegment(napi_env env, napi_callback_info info)219     static napi_value GetSegment(napi_env env, napi_callback_info info)
220     {
221         napi_value thisVar = nullptr;
222         napi_value result = nullptr;
223         NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
224         Uri *muri = nullptr;
225         NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&muri)));
226         std::vector<std::string> temp = muri->GetSegment();
227         if (temp.empty()) {
228             napi_get_null(env, &result);
229             return result;
230         }
231         napi_value segment = nullptr;
232         napi_create_array(env, &result);
233         size_t size = temp.size();
234         for (size_t i = 0; i < size; i++) {
235             napi_create_string_utf8(env, temp[i].c_str(), temp[i].length(), &segment);
236             napi_set_element(env, result, i, segment);
237         }
238         return result;
239     }
240 
GetScheme(napi_env env, napi_callback_info info)241     static napi_value GetScheme(napi_env env, napi_callback_info info)
242     {
243         napi_value thisVar = nullptr;
244         napi_value result = nullptr;
245         NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
246         Uri *muri = nullptr;
247         NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&muri)));
248         std::string temp = muri->GetScheme();
249         if (temp.empty()) {
250             napi_get_null(env, &result);
251             return result;
252         }
253         size_t templen = temp.size();
254         NAPI_CALL(env, napi_create_string_utf8(env, temp.c_str(), templen, &result));
255         return result;
256     }
257 
GetAuthority(napi_env env, napi_callback_info info)258     static napi_value GetAuthority(napi_env env, napi_callback_info info)
259     {
260         napi_value thisVar = nullptr;
261         napi_value result = nullptr;
262         NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
263         Uri *muri = nullptr;
264         NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&muri)));
265         std::string temp = muri->GetAuthority();
266         if (temp.empty()) {
267             napi_get_null(env, &result);
268             return result;
269         }
270         size_t templen = temp.size();
271         NAPI_CALL(env, napi_create_string_utf8(env, temp.c_str(), templen, &result));
272         return result;
273     }
274 
GetSsp(napi_env env, napi_callback_info info)275     static napi_value GetSsp(napi_env env, napi_callback_info info)
276     {
277         napi_value thisVar = nullptr;
278         napi_value result = nullptr;
279         NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
280         Uri *muri = nullptr;
281         NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&muri)));
282         std::string temp = muri->GetSsp();
283         size_t templen = temp.size();
284         NAPI_CALL(env, napi_create_string_utf8(env, temp.c_str(), templen, &result));
285         return result;
286     }
287 
GetUserinfo(napi_env env, napi_callback_info info)288     static napi_value GetUserinfo(napi_env env, napi_callback_info info)
289     {
290         napi_value thisVar = nullptr;
291         napi_value result = nullptr;
292         NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
293         Uri *muri = nullptr;
294         NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&muri)));
295         std::string temp = muri->GetUserinfo();
296         if (temp.empty()) {
297             napi_get_null(env, &result);
298             return result;
299         }
300         size_t templen = temp.size();
301         NAPI_CALL(env, napi_create_string_utf8(env, temp.c_str(), templen, &result));
302         return result;
303     }
304 
GetHost(napi_env env, napi_callback_info info)305     static napi_value GetHost(napi_env env, napi_callback_info info)
306     {
307         napi_value thisVar = nullptr;
308         napi_value result = nullptr;
309         NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
310         Uri *muri = nullptr;
311         NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&muri)));
312         std::string temp = muri->GetHost();
313         if (temp.empty()) {
314             napi_get_null(env, &result);
315             return result;
316         }
317         size_t templen = temp.size();
318         NAPI_CALL(env, napi_create_string_utf8(env, temp.c_str(), templen, &result));
319         return result;
320     }
321 
GetPort(napi_env env, napi_callback_info info)322     static napi_value GetPort(napi_env env, napi_callback_info info)
323     {
324         napi_value thisVar = nullptr;
325         napi_value result = nullptr;
326         NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
327         Uri *muri = nullptr;
328         NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&muri)));
329         std::string temp = muri->GetPort();
330         size_t templen = temp.size();
331         NAPI_CALL(env, napi_create_string_utf8(env, temp.c_str(), templen, &result));
332         return result;
333     }
334 
GetPath(napi_env env, napi_callback_info info)335     static napi_value GetPath(napi_env env, napi_callback_info info)
336     {
337         napi_value thisVar = nullptr;
338         napi_value result = nullptr;
339         NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
340         Uri *muri = nullptr;
341         NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&muri)));
342         std::string temp = muri->GetPath();
343         if (temp.empty()) {
344             napi_get_null(env, &result);
345             return result;
346         }
347         size_t templen = temp.size();
348         NAPI_CALL(env, napi_create_string_utf8(env, temp.c_str(), templen, &result));
349         return result;
350     }
351 
GetQuery(napi_env env, napi_callback_info info)352     static napi_value GetQuery(napi_env env, napi_callback_info info)
353     {
354         napi_value thisVar = nullptr;
355         napi_value result = nullptr;
356         NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
357         Uri *muri = nullptr;
358         NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&muri)));
359         std::string temp = muri->GetQuery();
360         if (temp.empty()) {
361             napi_get_null(env, &result);
362             return result;
363         }
364         size_t templen = temp.size();
365         NAPI_CALL(env, napi_create_string_utf8(env, temp.c_str(), templen, &result));
366         return result;
367     }
368 
GetFragment(napi_env env, napi_callback_info info)369     static napi_value GetFragment(napi_env env, napi_callback_info info)
370     {
371         napi_value thisVar = nullptr;
372         napi_value result = nullptr;
373         NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
374         Uri *muri = nullptr;
375         NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&muri)));
376         std::string temp = muri->GetFragment();
377         if (temp.empty()) {
378             napi_get_null(env, &result);
379             return result;
380         }
381         size_t templen = temp.size();
382         NAPI_CALL(env, napi_create_string_utf8(env, temp.c_str(), templen, &result));
383         return result;
384     }
385 
ClearQuery(napi_env env, napi_callback_info info)386     static napi_value ClearQuery(napi_env env, napi_callback_info info)
387     {
388         napi_value thisVar = nullptr;
389         napi_value result = nullptr;
390         NAPI_CALL(env, napi_get_cb_info(env, info, nullptr, nullptr, &thisVar, nullptr));
391         Uri *muri = nullptr;
392         NAPI_CALL(env, napi_unwrap(env, thisVar, reinterpret_cast<void**>(&muri)));
393         std::string temp = muri->ClearQuery();
394         if (temp.empty()) {
395             napi_get_null(env, &result);
396             return result;
397         }
398         size_t tempLen = temp.size();
399         NAPI_CALL(env, napi_create_string_utf8(env, temp.c_str(), tempLen, &result));
400         return result;
401     }
402 
UriInit(napi_env env, napi_value exports)403     napi_value UriInit(napi_env env, napi_value exports)
404     {
405         const char *uriClassName = "uri";
406         napi_value uriClass = nullptr;
407         napi_property_descriptor uriDesc[] = {
408             DECLARE_NAPI_FUNCTION("normalize", Normalize),
409             DECLARE_NAPI_FUNCTION("equals", Equals),
410             DECLARE_NAPI_FUNCTION("checkIsAbsolute", IsAbsolute),
411             DECLARE_NAPI_FUNCTION("toString", UriToString),
412             DECLARE_NAPI_FUNCTION("checkIsRelative", IsRelative),
413             DECLARE_NAPI_FUNCTION("checkIsOpaque", IsOpaque),
414             DECLARE_NAPI_FUNCTION("checkIsHierarchical", IsHierarchical),
415             DECLARE_NAPI_FUNCTION("addQueryValue", AddQueryValue),
416             DECLARE_NAPI_FUNCTION("getSegment", GetSegment),
417             DECLARE_NAPI_FUNCTION("addSegment", AddSegment),
418             DECLARE_NAPI_FUNCTION("clearQuery", ClearQuery),
419             DECLARE_NAPI_GETTER("scheme", GetScheme),
420             DECLARE_NAPI_GETTER("authority", GetAuthority),
421             DECLARE_NAPI_GETTER("ssp", GetSsp),
422             DECLARE_NAPI_GETTER("userInfo", GetUserinfo),
423             DECLARE_NAPI_GETTER("host", GetHost),
424             DECLARE_NAPI_GETTER("port", GetPort),
425             DECLARE_NAPI_GETTER("path", GetPath),
426             DECLARE_NAPI_GETTER("query", GetQuery),
427             DECLARE_NAPI_GETTER("fragment", GetFragment),
428             DECLARE_NAPI_GETTER("isFailed", IsFailed),
429         };
430         NAPI_CALL(env, napi_define_class(env, uriClassName, strlen(uriClassName), UriConstructor,
431                                          nullptr, sizeof(uriDesc) / sizeof(uriDesc[0]), uriDesc, &uriClass));
432         napi_property_descriptor desc[] = {
433             DECLARE_NAPI_PROPERTY("Uri", uriClass)
434         };
435         napi_define_properties(env, exports, sizeof(desc) / sizeof(desc[0]), desc);
436         return exports;
437     }
438 
439     extern "C"
NAPI_uri_GetJSCode(const char **buf, int *bufLen)440     __attribute__((visibility("default"))) void NAPI_uri_GetJSCode(const char **buf, int *bufLen)
441     {
442         if (buf != nullptr) {
443             *buf = _binary_js_uri_js_start;
444         }
445         if (bufLen != nullptr) {
446             *bufLen = _binary_js_uri_js_end - _binary_js_uri_js_start;
447         }
448     }
449     extern "C"
NAPI_uri_GetABCCode(const char** buf, int* buflen)450     __attribute__((visibility("default"))) void NAPI_uri_GetABCCode(const char** buf, int* buflen)
451     {
452         if (buf != nullptr) {
453             *buf = _binary_uri_abc_start;
454         }
455         if (buflen != nullptr) {
456             *buflen = _binary_uri_abc_end - _binary_uri_abc_start;
457         }
458     }
459 
460     static napi_module_with_js UriModule = {
461         .nm_version = 1,
462         .nm_flags = 0,
463         .nm_filename = nullptr,
464         .nm_register_func = UriInit,
465         .nm_modname = "uri",
466         .nm_priv = reinterpret_cast<void*>(0),
467         .nm_get_abc_code = NAPI_uri_GetABCCode,
468         .nm_get_js_code = NAPI_uri_GetJSCode,
469     };
UriRegisterModule()470     extern "C" __attribute__((constructor)) void UriRegisterModule()
471     {
472         napi_module_with_js_register(&UriModule);
473     }
474 } // namespace OHOS::Uri
475