1 /*
2 * Copyright (c) 2024 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 "cj_initialize.h"
17
18 #include <algorithm>
19 #include <cstring>
20 #include <fcntl.h>
21 #include <filesystem>
22 #include <fstream>
23 #include <regex>
24 #include <sys/stat.h>
25 #include "cj_request_common.h"
26 #include "cj_request_task.h"
27 #include "constant.h"
28 #include "js_common.h"
29 #include "log.h"
30 #include "net_conn_client.h"
31 #include "request_manager.h"
32 #include "securec.h"
33
34 namespace OHOS::CJSystemapi::Request {
35
36 using OHOS::AbilityRuntime::Context;
37 using OHOS::Request::Action;
38 using OHOS::Request::ExceptionErrorCode;
39 using OHOS::Request::FileSpec;
40 using OHOS::Request::FormItem;
41 using OHOS::Request::Version;
42
43 static constexpr uint32_t URL_MAXIMUM = 2048;
44 static constexpr uint32_t TITLE_MAXIMUM = 256;
45 static constexpr uint32_t DESCRIPTION_MAXIMUM = 1024;
46
47 static constexpr uint32_t FILE_PERMISSION = 0644;
48
49 static const std::string AREA1 = "/data/storage/el1/base";
50 static const std::string AREA2 = "/data/storage/el2/base";
51 static const std::string AREA5 = "/data/storage/el5/base";
52
ParseBundleName(const std::shared_ptr<OHOS::AbilityRuntime::Context> & context,std::string & bundleName)53 ExceptionError CJInitialize::ParseBundleName(const std::shared_ptr<OHOS::AbilityRuntime::Context> &context,
54 std::string &bundleName)
55 {
56 ExceptionError err;
57 if (context->GetApplicationInfo() == nullptr) {
58 err.code = ExceptionErrorCode::E_OTHER;
59 err.errInfo = "ApplicationInfo is null";
60 return err;
61 }
62
63 bundleName = context->GetBundleName();
64 return err;
65 }
66
ParseUrl(std::string & url)67 bool CJInitialize::ParseUrl(std::string &url)
68 {
69 if (url.size() > URL_MAXIMUM) {
70 REQUEST_HILOGE("The URL exceeds the maximum length of 2048");
71 return false;
72 }
73 if (!std::regex_match(url, std::regex("^http(s)?:\\/\\/.+"))) {
74 REQUEST_HILOGE("ParseUrl error");
75 return false;
76 }
77
78 return true;
79 }
80
ParseCertsPath(std::string & url,std::vector<std::string> & certsPath)81 bool CJInitialize::ParseCertsPath(std::string &url, std::vector<std::string> &certsPath)
82 {
83 if (url.size() > URL_MAXIMUM) {
84 REQUEST_HILOGE("The URL exceeds the maximum length of 2048");
85 return false;
86 }
87 if (!regex_match(url, std::regex("^http(s)?:\\/\\/.+"))) {
88 REQUEST_HILOGE("ParseUrl error");
89 return false;
90 }
91
92 typedef std::string::const_iterator iter_t;
93 iter_t urlEnd = url.end();
94 iter_t protocolStart = url.cbegin();
95 iter_t protocolEnd = std::find(protocolStart, urlEnd, ':');
96 std::string protocol = std::string(protocolStart, protocolEnd);
97 if (protocol != "https") {
98 REQUEST_HILOGD("Using Http");
99 return true;
100 }
101 if (protocolEnd != urlEnd) {
102 std::string afterProtocol = &*(protocolEnd);
103 // 3 is the num of ://
104 if ((afterProtocol.length() > 3) && (afterProtocol.substr(0, 3) == "://")) {
105 // 3 means go beyound :// in protocolEnd
106 protocolEnd += 3;
107 } else {
108 protocolEnd = url.cbegin();
109 }
110 } else {
111 protocolEnd = url.cbegin();
112 }
113 iter_t hostStart = protocolEnd;
114 iter_t pathStart = std::find(hostStart, urlEnd, '/');
115 iter_t queryStart = std::find(url.cbegin(), urlEnd, '?');
116 iter_t hostEnd = std::find(protocolEnd, (pathStart != urlEnd) ? pathStart : queryStart, ':');
117 std::string hostname = std::string(hostStart, hostEnd);
118 REQUEST_HILOGD("Hostname is %{public}s", hostname.c_str());
119 NetManagerStandard::NetConnClient::GetInstance().GetTrustAnchorsForHostName(hostname, certsPath);
120
121 return true;
122 }
123
Convert2FileSpec(const CFileSpec * cFile,const char * name,FileSpec & file)124 bool CJInitialize::Convert2FileSpec(const CFileSpec *cFile, const char *name, FileSpec &file)
125 {
126 file.name = name;
127
128 if (cFile->path == nullptr) {
129 return false;
130 }
131 file.uri = cFile->path;
132 if (file.uri.empty()) {
133 return false;
134 }
135 if (cFile->filename != nullptr) {
136 file.filename = cFile->filename;
137 }
138
139 if (cFile->mimeType != nullptr) {
140 file.type = cFile->mimeType;
141 }
142
143 return true;
144 }
145
Convert2FileSpecs(const CFileSpecArr * cFiles,const char * name,std::vector<FileSpec> & files)146 bool CJInitialize::Convert2FileSpecs(const CFileSpecArr *cFiles, const char *name, std::vector<FileSpec> &files)
147 {
148 for (int i = 0; i < cFiles->size; ++i) {
149 FileSpec file;
150 if (!Convert2FileSpec(&cFiles->head[i], name, file)) {
151 return false;
152 }
153 files.push_back(file);
154 }
155 return true;
156 }
157
ParseFormItems(const CFormItemArr * cForms,std::vector<FormItem> & forms,std::vector<FileSpec> & files)158 bool CJInitialize::ParseFormItems(const CFormItemArr *cForms, std::vector<FormItem> &forms,
159 std::vector<FileSpec> &files)
160 {
161 for (int i = 0; i < cForms->size; ++i) {
162 CFormItem *cForm = &cForms->head[i];
163 if (cForm->value.str != nullptr) {
164 FormItem form;
165 form.name = cForm->name;
166 form.value = cForm->value.str;
167 forms.push_back(form);
168 } else if (cForm->value.file.path != nullptr) {
169 FileSpec file;
170 if (!Convert2FileSpec(&cForm->value.file, cForm->name, file)) {
171 REQUEST_HILOGE("Convert2FileSpec failed");
172 return false;
173 }
174 files.push_back(file);
175 } else if (cForm->value.files.size > 0) {
176 if (!Convert2FileSpecs(&cForm->value.files, cForm->name, files)) {
177 return false;
178 }
179 } else {
180 REQUEST_HILOGE("value type is error");
181 return false;
182 }
183 }
184
185 return true;
186 }
187
ParseData(const CConfig * config,Config & out)188 bool CJInitialize::ParseData(const CConfig *config, Config &out)
189 {
190 REQUEST_HILOGD("formItems.size is %{public}" PRIi64 ", data.str is %{public}p", config->data.formItems.size,
191 config->data.str);
192 if (config->data.str == nullptr && config->data.formItems.size <= 0) {
193 return true;
194 }
195
196 if (out.action == Action::UPLOAD && config->data.formItems.size > 0) {
197 return ParseFormItems(&config->data.formItems, out.forms, out.files);
198 } else if (out.action == Action::DOWNLOAD && config->data.str != nullptr) {
199 out.data = config->data.str;
200 } else {
201 REQUEST_HILOGE("data type is error");
202 return false;
203 }
204
205 return true;
206 }
207
ParseIndex(Config & config)208 bool CJInitialize::ParseIndex(Config &config)
209 {
210 if (config.action == Action::DOWNLOAD) {
211 config.index = 0;
212 return true;
213 }
214 if (config.files.size() <= config.index) {
215 REQUEST_HILOGE("files.size is %{public}zu, index is %{public}d", config.files.size(), config.index);
216 return false;
217 }
218 return true;
219 }
220
ParseBegins(int64_t & begins)221 int64_t CJInitialize::ParseBegins(int64_t &begins)
222 {
223 return begins >= 0 ? begins : 0;
224 }
225
ParseTitle(Config & config)226 bool CJInitialize::ParseTitle(Config &config)
227 {
228 if (config.title.size() > TITLE_MAXIMUM) {
229 return false;
230 }
231
232 if (config.title.empty()) {
233 config.title = config.action == Action::UPLOAD ? "upload" : "download";
234 }
235
236 return true;
237 }
238
ParseToken(Config & config,std::string & errInfo)239 bool CJInitialize::ParseToken(Config &config, std::string &errInfo)
240 {
241 if (config.token.empty()) {
242 config.token = "null";
243 return true;
244 }
245 size_t len = config.token.length();
246 if (len < TOKEN_MIN_BYTES || len > TOKEN_MAX_BYTES) {
247 errInfo = "Parameter verification failed, the length of token should between 8 and 2048 bytes";
248 return false;
249 }
250
251 config.token = SHA256(config.token.c_str(), len);
252 return true;
253 }
254
ParseDescription(std::string & description)255 bool CJInitialize::ParseDescription(std::string &description)
256 {
257 return description.size() <= DESCRIPTION_MAXIMUM;
258 }
259
ParseSaveas(Config & config)260 bool CJInitialize::ParseSaveas(Config &config)
261 {
262 if (config.action != Action::DOWNLOAD) {
263 config.saveas = "";
264 return true;
265 }
266
267 std::string temp = config.saveas;
268 if (temp.empty() || temp == "./") {
269 return InterceptData("/", config.url, config.saveas);
270 }
271 temp = std::string(temp, 0, temp.find_last_not_of(' ') + 1);
272 if (temp.size() == 0 || temp[temp.size() - 1] == '/') {
273 return false;
274 }
275 config.saveas = temp;
276 return true;
277 }
278
ParseMethod(Config & config)279 void CJInitialize::ParseMethod(Config &config)
280 {
281 std::string method = config.method;
282 config.method = config.action == Action::UPLOAD ? "PUT" : "GET";
283 if (!method.empty()) {
284 transform(method.begin(), method.end(), method.begin(), ::toupper);
285 if (config.action == Action::UPLOAD && (method == "POST" || method == "PUT")) {
286 config.method = method;
287 }
288 if (config.action == Action::DOWNLOAD && (method == "POST" || method == "GET")) {
289 config.method = method;
290 }
291 }
292 }
293
ParseNetwork(Network & network)294 void CJInitialize::ParseNetwork(Network &network)
295 {
296 if (network != Network::ANY && network != Network::WIFI && network != Network::CELLULAR) {
297 network = Network::ANY;
298 }
299 }
300
ParseBackGround(Mode mode,bool & background)301 void CJInitialize::ParseBackGround(Mode mode, bool &background)
302 {
303 background = mode == Mode::BACKGROUND;
304 }
305
StringSplit(const std::string & str,const char delim,std::vector<std::string> & elems)306 void CJInitialize::StringSplit(const std::string &str, const char delim, std::vector<std::string> &elems)
307 {
308 std::stringstream stream(str);
309 std::string item;
310 while (std::getline(stream, item, delim)) {
311 if (!item.empty()) {
312 elems.push_back(item);
313 }
314 }
315 return;
316 }
317
GetBaseDir(std::string & baseDir)318 bool CJInitialize::GetBaseDir(std::string &baseDir)
319 {
320 auto context = OHOS::AbilityRuntime::Context::GetApplicationContext();
321 if (context == nullptr) {
322 REQUEST_HILOGE("AppContext is null.");
323 return false;
324 }
325
326 baseDir = context->GetBaseDir();
327 if (baseDir.empty()) {
328 REQUEST_HILOGE("Base dir not found.");
329 return false;
330 }
331 return true;
332 }
333
CheckPathBaseDir(const std::string & filepath,std::string & baseDir)334 bool CJInitialize::CheckPathBaseDir(const std::string &filepath, std::string &baseDir)
335 {
336 if (!CJInitialize::GetBaseDir(baseDir)) {
337 return false;
338 }
339
340 if ((filepath.find(AREA1) == 0) || filepath.find(AREA2) == 0 || filepath.find(AREA5) == 0) {
341 return true;
342 }
343
344 REQUEST_HILOGE("File dir not include base dir: %{public}s", baseDir.c_str());
345 return false;
346 }
347
CreateDirs(const std::vector<std::string> & pathDirs)348 bool CJInitialize::CreateDirs(const std::vector<std::string> &pathDirs)
349 {
350 std::string path;
351 for (auto elem : pathDirs) {
352 path += "/" + elem;
353 std::error_code err;
354 if (std::filesystem::exists(path, err)) {
355 continue;
356 }
357 err.clear();
358 // create_directory noexcept.
359 if (!std::filesystem::create_directory(path, err)) {
360 REQUEST_HILOGE("Create Dir Err: %{public}d, %{public}s", err.value(), err.message().c_str());
361 return false;
362 }
363 }
364 return true;
365 }
366
CheckDownloadFilePath(const std::shared_ptr<OHOS::AbilityRuntime::Context> & context,Config & config,std::string & errInfo)367 bool CJInitialize::CheckDownloadFilePath(const std::shared_ptr<OHOS::AbilityRuntime::Context> &context, Config &config,
368 std::string &errInfo)
369 {
370 std::string path = config.saveas;
371 if (!StandardizePath(context, config, path)) {
372 REQUEST_HILOGE("StandardizePath Err: %{public}s", path.c_str());
373 errInfo = "this is fail saveas path";
374 return false;
375 };
376 std::string normalPath;
377 std::vector<std::string> pathVec;
378 if (!WholeToNormal(path, normalPath, pathVec) || pathVec.empty()) {
379 REQUEST_HILOGE("WholeToNormal Err: %{public}s", path.c_str());
380 errInfo = "this is fail saveas path";
381 return false;
382 };
383 std::string baseDir;
384 if (!CheckPathBaseDir(normalPath, baseDir)) {
385 REQUEST_HILOGE("CheckPathBaseDir Err: %{public}s", normalPath.c_str());
386 errInfo = "this is fail saveas path";
387 return false;
388 };
389 // pop filename.
390 pathVec.pop_back();
391 if (!CreateDirs(pathVec)) {
392 REQUEST_HILOGE("CreateDirs Err: %{public}s", normalPath.c_str());
393 errInfo = "this is fail saveas path";
394 return false;
395 }
396 config.saveas = normalPath;
397 return true;
398 }
399
FileToWhole(const std::shared_ptr<OHOS::AbilityRuntime::Context> & context,const Config & config,std::string & path)400 bool CJInitialize::FileToWhole(const std::shared_ptr<OHOS::AbilityRuntime::Context> &context, const Config &config,
401 std::string &path)
402 {
403 std::string bundleName = path.substr(0, path.find("/"));
404 if (bundleName != config.bundleName) {
405 REQUEST_HILOGE("path bundleName error.");
406 return false;
407 }
408 path.erase(0, bundleName.size());
409 return true;
410 }
411
CacheToWhole(const std::shared_ptr<OHOS::AbilityRuntime::Context> & context,std::string & path)412 bool CJInitialize::CacheToWhole(const std::shared_ptr<OHOS::AbilityRuntime::Context> &context, std::string &path)
413 {
414 std::string cache = context->GetCacheDir();
415 if (cache.empty()) {
416 REQUEST_HILOGE("GetCacheDir error.");
417 return false;
418 }
419 path = cache + "/" + path;
420 return true;
421 }
422
StandardizePath(const std::shared_ptr<OHOS::AbilityRuntime::Context> & context,const Config & config,std::string & path)423 bool CJInitialize::StandardizePath(const std::shared_ptr<OHOS::AbilityRuntime::Context> &context, const Config &config,
424 std::string &path)
425 {
426 std::string WHOLE_PREFIX = "/";
427 std::string FILE_PREFIX = "file://";
428 std::string INTERNAL_PREFIX = "internal://cache/";
429 std::string CURRENT_PREFIX = "./";
430
431 if (path.find(WHOLE_PREFIX) == 0) {
432 return true;
433 }
434 if (path.find(FILE_PREFIX) == 0) {
435 path.erase(0, FILE_PREFIX.size());
436 return FileToWhole(context, config, path);
437 }
438 if (path.find(INTERNAL_PREFIX) == 0) {
439 path.erase(0, INTERNAL_PREFIX.size());
440 return CacheToWhole(context, path);
441 }
442 if (path.find(CURRENT_PREFIX) == 0) {
443 path.erase(0, CURRENT_PREFIX.size());
444 return CacheToWhole(context, path);
445 }
446 return CacheToWhole(context, path);
447 }
448
PathVecToNormal(const std::vector<std::string> & in,std::vector<std::string> & out)449 bool CJInitialize::PathVecToNormal(const std::vector<std::string> &in, std::vector<std::string> &out)
450 {
451 for (auto elem : in) {
452 if (elem == "..") {
453 if (out.size() > 0) {
454 out.pop_back();
455 } else {
456 return false;
457 }
458 } else {
459 out.push_back(elem);
460 }
461 }
462 return true;
463 }
464
WholeToNormal(const std::string & wholePath,std::string & normalPath,std::vector<std::string> & out)465 bool CJInitialize::WholeToNormal(const std::string &wholePath, std::string &normalPath, std::vector<std::string> &out)
466 {
467 std::vector<std::string> elems;
468 StringSplit(wholePath, '/', elems);
469 if (!PathVecToNormal(elems, out)) {
470 return false;
471 }
472 for (auto elem : out) {
473 normalPath += "/" + elem;
474 }
475 return true;
476 }
477
UploadBodyFileProc(std::string & fileName,Config & config)478 ExceptionError CJInitialize::UploadBodyFileProc(std::string &fileName, Config &config)
479 {
480 ExceptionError err;
481 int32_t bodyFd = open(fileName.c_str(), O_TRUNC | O_RDWR);
482 if (bodyFd < 0) {
483 bodyFd = open(fileName.c_str(), O_CREAT | O_RDWR, FILE_PERMISSION);
484 if (bodyFd < 0) {
485 err.code = ExceptionErrorCode::E_FILE_IO;
486 err.errInfo = "Failed to open file errno " + std::to_string(errno);
487 return err;
488 }
489 }
490
491 if (bodyFd >= 0) {
492 chmod(fileName.c_str(), S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
493 close(bodyFd);
494 }
495 config.bodyFileNames.push_back(fileName);
496
497 return err;
498 }
499
CheckUploadBodyFiles(Config & config,const std::string & filePath)500 ExceptionError CJInitialize::CheckUploadBodyFiles(Config &config, const std::string &filePath)
501 {
502 size_t len = config.files.size();
503 ExceptionError err;
504 for (size_t i = 0; i < len; i++) {
505 if (filePath.empty()) {
506 REQUEST_HILOGE("internal to cache error");
507 err.code = ExceptionErrorCode::E_PARAMETER_CHECK;
508 err.errInfo = "IsPathValid error empty path";
509 return err;
510 }
511 auto now = std::chrono::high_resolution_clock::now();
512 auto timestamp = std::chrono::duration_cast<std::chrono::nanoseconds>(now.time_since_epoch()).count();
513 std::string fileName = filePath + "/tmp_body_" + std::to_string(i) + "_" + std::to_string(timestamp);
514 REQUEST_HILOGD("Create upload body file, %{public}s", fileName.c_str());
515 if (!IsPathValid(fileName)) {
516 REQUEST_HILOGE("IsPathValid error %{public}s", fileName.c_str());
517 err.code = ExceptionErrorCode::E_PARAMETER_CHECK;
518 err.errInfo = "IsPathValid error fail path";
519 return err;
520 }
521 err = UploadBodyFileProc(fileName, config);
522 if (err.code != ExceptionErrorCode::E_OK) {
523 return err;
524 }
525 }
526 return err;
527 }
528
InterceptData(const std::string & str,const std::string & in,std::string & out)529 bool CJInitialize::InterceptData(const std::string &str, const std::string &in, std::string &out)
530 {
531 std::string tmpStr = std::string(in, 0, in.find_last_not_of(' ') + 1);
532 std::size_t position = tmpStr.find_last_of(str);
533 // when the str at last index, will error.
534 if (position == std::string::npos || position + 1 >= tmpStr.size()) {
535 return false;
536 }
537 out = std::string(tmpStr, position + 1);
538 return true;
539 }
540
GetFD(const std::string & path,const Config & config,int32_t & fd)541 ExceptionError CJInitialize::GetFD(const std::string &path, const Config &config, int32_t &fd)
542 {
543 ExceptionError err;
544 fd = config.action == Action::UPLOAD ? open(path.c_str(), O_RDONLY) : open(path.c_str(), O_TRUNC | O_RDWR);
545 if (fd >= 0) {
546 REQUEST_HILOGD("File already exists");
547 if (config.action == Action::UPLOAD) {
548 chmod(path.c_str(), S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
549 close(fd);
550 return err;
551 } else {
552 chmod(path.c_str(), S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
553 }
554
555 if (config.overwrite) {
556 close(fd);
557 return err;
558 }
559 if (!config.firstInit) {
560 REQUEST_HILOGD("CJRequestTask config is not firstInit");
561 close(fd);
562 return err;
563 }
564 close(fd);
565
566 err.code = ExceptionErrorCode::E_FILE_IO;
567 err.errInfo = "Download File already exists";
568 return err;
569 } else {
570 if (config.action == Action::UPLOAD) {
571 ExceptionErrorCode code = ExceptionErrorCode::E_FILE_IO;
572 err.code = ExceptionErrorCode::E_FILE_IO;
573 err.errInfo = "Failed to open file errno " + std::to_string(errno);
574 return err;
575 }
576 fd = open(path.c_str(), O_CREAT | O_RDWR, FILE_PERMISSION);
577 if (fd < 0) {
578 err.code = ExceptionErrorCode::E_FILE_IO;
579 err.errInfo = "Failed to open file errno " + std::to_string(errno);
580 return err;
581 }
582 chmod(path.c_str(), S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
583 close(fd);
584 }
585 return err;
586 }
587
GetInternalPath(const std::string & fileUri,const std::shared_ptr<OHOS::AbilityRuntime::Context> & context,Config & config,std::string & filePath)588 bool CJInitialize::GetInternalPath(const std::string &fileUri,
589 const std::shared_ptr<OHOS::AbilityRuntime::Context> &context, Config &config,
590 std::string &filePath)
591 {
592 if (config.action == Action::DOWNLOAD && fileUri.find('/') == 0) {
593 filePath = fileUri;
594 return true;
595 }
596 std::string fileName;
597 std::string pattern = "./";
598 size_t pos = fileUri.find(pattern);
599 if (pos != 0) {
600 fileName = fileUri;
601 } else {
602 fileName = fileUri.substr(pattern.size(), fileUri.size());
603 }
604 if (fileName.empty()) {
605 return false;
606 }
607 filePath = context->GetCacheDir();
608 if (filePath.empty()) {
609 REQUEST_HILOGE("internal to cache error");
610 return false;
611 }
612
613 filePath += "/" + fileName;
614 if (!IsPathValid(filePath)) {
615 REQUEST_HILOGE("IsPathValid error %{public}s", filePath.c_str());
616 return false;
617 }
618 return true;
619 }
620
CheckFileSpec(const std::shared_ptr<OHOS::AbilityRuntime::Context> & context,Config & config)621 ExceptionError CJInitialize::CheckFileSpec(const std::shared_ptr<OHOS::AbilityRuntime::Context> &context,
622 Config &config)
623 {
624 ExceptionError err;
625 for (auto &file : config.files) {
626 std::string path;
627 if (!GetInternalPath(file.uri, context, config, path)) {
628 err.code = ExceptionErrorCode::E_PARAMETER_CHECK;
629 err.errInfo = "this is fail path";
630 return err;
631 }
632 file.uri = path;
633 if (file.filename.empty()) {
634 InterceptData("/", file.uri, file.filename);
635 }
636 if (file.type.empty()) {
637 InterceptData(".", file.filename, file.type);
638 }
639 if (file.name.empty()) {
640 file.name = "file";
641 }
642
643 err = GetFD(path, config, file.fd);
644 if (err.code != ExceptionErrorCode::E_OK) {
645 return err;
646 }
647
648 if (!CJRequestTask::SetPathPermission(file.uri)) {
649 err.code = ExceptionErrorCode::E_FILE_IO;
650 err.errInfo = "set path permission fail";
651 return err;
652 }
653 }
654 return err;
655 }
656
CheckFilePath(const std::shared_ptr<OHOS::AbilityRuntime::Context> & context,Config & config)657 ExceptionError CJInitialize::CheckFilePath(const std::shared_ptr<OHOS::AbilityRuntime::Context> &context,
658 Config &config)
659 {
660 ExceptionError err;
661 if (config.action == Action::DOWNLOAD) {
662 if (!CheckDownloadFilePath(context, config, err.errInfo)) {
663 err.code = ExceptionErrorCode::E_PARAMETER_CHECK;
664 return err;
665 }
666
667 FileSpec file = {.uri = config.saveas};
668 config.files.push_back(file);
669 }
670
671 err = CheckFileSpec(context, config);
672 if (err.code != ExceptionErrorCode::E_OK) {
673 return err;
674 }
675
676 if (!CJRequestTask::SetDirsPermission(config.certsPath)) {
677 err.code = ExceptionErrorCode::E_FILE_IO;
678 err.errInfo = "set files of directors permission fail";
679 return err;
680 }
681
682 if (config.action == Action::UPLOAD) {
683 std::string filePath = context->GetCacheDir();
684 err = CheckUploadBodyFiles(config, filePath);
685 }
686
687 return err;
688 }
689
ParseConfig(OHOS::AbilityRuntime::Context * stageContext,const CConfig * ffiConfig,Config & config)690 ExceptionError CJInitialize::ParseConfig(OHOS::AbilityRuntime::Context *stageContext, const CConfig *ffiConfig,
691 Config &config)
692 {
693 config.action = (OHOS::Request::Action)ffiConfig->action;
694 config.withErrCode = true;
695 config.version = Version::API10; // CJ only support API10
696
697 ExceptionError err;
698 if (stageContext == nullptr) {
699 err.code = ExceptionErrorCode::E_PARAMETER_CHECK;
700 err.errInfo = "Get context fail";
701 return err;
702 }
703
704 std::shared_ptr<OHOS::AbilityRuntime::Context> context = stageContext->shared_from_this();
705 err = ParseBundleName(context, config.bundleName);
706 if (err.code != 0) {
707 return err;
708 }
709 err.code = ExceptionErrorCode::E_PARAMETER_CHECK;
710 if (!ParseUrl(config.url)) {
711 err.errInfo = "parse url error";
712 return err;
713 }
714
715 if (!ParseCertsPath(config.url, config.certsPath)) {
716 err.errInfo = "parse certs path error";
717 return err;
718 }
719
720 if (!ParseData(ffiConfig, config)) {
721 err.errInfo = "parse data error";
722 return err;
723 }
724
725 if (!ParseIndex(config)) {
726 err.errInfo = "Index exceeds file list";
727 return err;
728 }
729
730 if (!ParseToken(config, err.errInfo)) {
731 return err;
732 }
733
734 if (!ParseTitle(config) || !ParseDescription(config.description)) {
735 err.errInfo = "Exceeding maximum length";
736 return err;
737 }
738
739 if (!ParseSaveas(config)) {
740 err.errInfo = "parse saveas error";
741 return err;
742 }
743
744 ParseMethod(config);
745 ParseNetwork(config.network);
746 ParseBackGround(config.mode, config.background);
747 config.begins = ParseBegins(config.begins);
748
749 return CheckFilePath(context, config);
750 }
751
FindDir(const std::string & pathDir)752 bool CJInitialize::FindDir(const std::string &pathDir)
753 {
754 std::error_code err;
755 return std::filesystem::exists(pathDir, err);
756 }
757
758 } // namespace OHOS::CJSystemapi::Request
759