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 "log.h"
29 #include "network_security_config.h"
30 #include "request_common.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::NetworkSecurityConfig::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 if (config->data.str == nullptr && config->data.formItems.size <= 0) {
191 return true;
192 }
193
194 if (out.action == Action::UPLOAD && config->data.formItems.size > 0) {
195 return ParseFormItems(&config->data.formItems, out.forms, out.files);
196 } else if (out.action == Action::DOWNLOAD && config->data.str != nullptr) {
197 out.data = config->data.str;
198 } else {
199 REQUEST_HILOGE("data type is error");
200 return false;
201 }
202
203 return true;
204 }
205
ParseIndex(Config & config)206 bool CJInitialize::ParseIndex(Config &config)
207 {
208 if (config.action == Action::DOWNLOAD) {
209 config.index = 0;
210 return true;
211 }
212 if (config.files.size() <= config.index) {
213 REQUEST_HILOGE("files.size is %{public}zu, index is %{public}d", config.files.size(), config.index);
214 return false;
215 }
216 return true;
217 }
218
ParseBegins(int64_t & begins)219 int64_t CJInitialize::ParseBegins(int64_t &begins)
220 {
221 return begins >= 0 ? begins : 0;
222 }
223
ParseTitle(Config & config)224 bool CJInitialize::ParseTitle(Config &config)
225 {
226 if (config.title.size() > TITLE_MAXIMUM) {
227 return false;
228 }
229
230 if (config.title.empty()) {
231 config.title = config.action == Action::UPLOAD ? "upload" : "download";
232 }
233
234 return true;
235 }
236
ParseToken(Config & config,std::string & errInfo)237 bool CJInitialize::ParseToken(Config &config, std::string &errInfo)
238 {
239 if (config.token.empty()) {
240 config.token = "null";
241 return true;
242 }
243 size_t len = config.token.length();
244 if (len < TOKEN_MIN_BYTES || len > TOKEN_MAX_BYTES) {
245 errInfo = "Parameter verification failed, the length of token should between 8 and 2048 bytes";
246 return false;
247 }
248
249 config.token = SHA256(config.token.c_str(), len);
250 return true;
251 }
252
ParseDescription(std::string & description)253 bool CJInitialize::ParseDescription(std::string &description)
254 {
255 return description.size() <= DESCRIPTION_MAXIMUM;
256 }
257
ParseSaveas(Config & config)258 bool CJInitialize::ParseSaveas(Config &config)
259 {
260 if (config.action != Action::DOWNLOAD) {
261 config.saveas = "";
262 return true;
263 }
264
265 std::string temp = config.saveas;
266 if (temp.empty() || temp == "./") {
267 return InterceptData("/", config.url, config.saveas);
268 }
269 temp = std::string(temp, 0, temp.find_last_not_of(' ') + 1);
270 if (temp.size() == 0 || temp[temp.size() - 1] == '/') {
271 return false;
272 }
273 config.saveas = temp;
274 return true;
275 }
276
ParseMethod(Config & config)277 void CJInitialize::ParseMethod(Config &config)
278 {
279 std::string method = config.method;
280 config.method = config.action == Action::UPLOAD ? "PUT" : "GET";
281 if (!method.empty()) {
282 transform(method.begin(), method.end(), method.begin(), ::toupper);
283 if (config.action == Action::UPLOAD && (method == "POST" || method == "PUT")) {
284 config.method = method;
285 }
286 if (config.action == Action::DOWNLOAD && (method == "POST" || method == "GET")) {
287 config.method = method;
288 }
289 }
290 }
291
ParseNetwork(Network & network)292 void CJInitialize::ParseNetwork(Network &network)
293 {
294 if (network != Network::ANY && network != Network::WIFI && network != Network::CELLULAR) {
295 network = Network::ANY;
296 }
297 }
298
ParseBackGround(Mode mode,bool & background)299 void CJInitialize::ParseBackGround(Mode mode, bool &background)
300 {
301 background = mode == Mode::BACKGROUND;
302 }
303
StringSplit(const std::string & str,const char delim,std::vector<std::string> & elems)304 void CJInitialize::StringSplit(const std::string &str, const char delim, std::vector<std::string> &elems)
305 {
306 std::stringstream stream(str);
307 std::string item;
308 while (std::getline(stream, item, delim)) {
309 if (!item.empty()) {
310 elems.push_back(item);
311 }
312 }
313 return;
314 }
315
GetBaseDir(std::string & baseDir)316 bool CJInitialize::GetBaseDir(std::string &baseDir)
317 {
318 auto context = OHOS::AbilityRuntime::Context::GetApplicationContext();
319 if (context == nullptr) {
320 REQUEST_HILOGE("AppContext is null.");
321 return false;
322 }
323
324 baseDir = context->GetBaseDir();
325 if (baseDir.empty()) {
326 REQUEST_HILOGE("Base dir not found.");
327 return false;
328 }
329 return true;
330 }
331
CheckPathBaseDir(const std::string & filepath,std::string & baseDir)332 bool CJInitialize::CheckPathBaseDir(const std::string &filepath, std::string &baseDir)
333 {
334 if (!CJInitialize::GetBaseDir(baseDir)) {
335 return false;
336 }
337
338 if ((filepath.find(AREA1) == 0) || filepath.find(AREA2) == 0 || filepath.find(AREA5) == 0) {
339 return true;
340 }
341
342 REQUEST_HILOGE("File dir not include base dir: %{public}s", baseDir.c_str());
343 return false;
344 }
345
CreateDirs(const std::vector<std::string> & pathDirs)346 bool CJInitialize::CreateDirs(const std::vector<std::string> &pathDirs)
347 {
348 std::string path;
349 for (auto elem : pathDirs) {
350 path += "/" + elem;
351 std::error_code err;
352 if (std::filesystem::exists(path, err)) {
353 continue;
354 }
355 err.clear();
356 // create_directory noexcept.
357 if (!std::filesystem::create_directory(path, err)) {
358 REQUEST_HILOGE("Create Dir Err: %{public}d, %{public}s", err.value(), err.message().c_str());
359 return false;
360 }
361 }
362 return true;
363 }
364
CheckDownloadFilePath(const std::shared_ptr<OHOS::AbilityRuntime::Context> & context,Config & config,std::string & errInfo)365 bool CJInitialize::CheckDownloadFilePath(const std::shared_ptr<OHOS::AbilityRuntime::Context> &context, Config &config,
366 std::string &errInfo)
367 {
368 std::string path = config.saveas;
369 if (!StandardizePath(context, config, path)) {
370 REQUEST_HILOGE("StandardizePath Err: %{public}s", path.c_str());
371 errInfo = "this is fail saveas path";
372 return false;
373 };
374 std::string normalPath;
375 std::vector<std::string> pathVec;
376 if (!WholeToNormal(path, normalPath, pathVec) || pathVec.empty()) {
377 REQUEST_HILOGE("WholeToNormal Err: %{public}s", path.c_str());
378 errInfo = "this is fail saveas path";
379 return false;
380 };
381 std::string baseDir;
382 if (!CheckPathBaseDir(normalPath, baseDir)) {
383 REQUEST_HILOGE("CheckPathBaseDir Err: %{public}s", normalPath.c_str());
384 errInfo = "this is fail saveas path";
385 return false;
386 };
387 // pop filename.
388 pathVec.pop_back();
389 if (!CreateDirs(pathVec)) {
390 REQUEST_HILOGE("CreateDirs Err: %{public}s", normalPath.c_str());
391 errInfo = "this is fail saveas path";
392 return false;
393 }
394 config.saveas = normalPath;
395 return true;
396 }
397
FileToWhole(const std::shared_ptr<OHOS::AbilityRuntime::Context> & context,const Config & config,std::string & path)398 bool CJInitialize::FileToWhole(const std::shared_ptr<OHOS::AbilityRuntime::Context> &context, const Config &config,
399 std::string &path)
400 {
401 std::string bundleName = path.substr(0, path.find("/"));
402 if (bundleName != config.bundleName) {
403 REQUEST_HILOGE("path bundleName error.");
404 return false;
405 }
406 path.erase(0, bundleName.size());
407 return true;
408 }
409
CacheToWhole(const std::shared_ptr<OHOS::AbilityRuntime::Context> & context,std::string & path)410 bool CJInitialize::CacheToWhole(const std::shared_ptr<OHOS::AbilityRuntime::Context> &context, std::string &path)
411 {
412 std::string cache = context->GetCacheDir();
413 if (cache.empty()) {
414 REQUEST_HILOGE("GetCacheDir error.");
415 return false;
416 }
417 path = cache + "/" + path;
418 return true;
419 }
420
StandardizePath(const std::shared_ptr<OHOS::AbilityRuntime::Context> & context,const Config & config,std::string & path)421 bool CJInitialize::StandardizePath(const std::shared_ptr<OHOS::AbilityRuntime::Context> &context, const Config &config,
422 std::string &path)
423 {
424 std::string WHOLE_PREFIX = "/";
425 std::string FILE_PREFIX = "file://";
426 std::string INTERNAL_PREFIX = "internal://cache/";
427 std::string CURRENT_PREFIX = "./";
428
429 if (path.find(WHOLE_PREFIX) == 0) {
430 return true;
431 }
432 if (path.find(FILE_PREFIX) == 0) {
433 path.erase(0, FILE_PREFIX.size());
434 return FileToWhole(context, config, path);
435 }
436 if (path.find(INTERNAL_PREFIX) == 0) {
437 path.erase(0, INTERNAL_PREFIX.size());
438 return CacheToWhole(context, path);
439 }
440 if (path.find(CURRENT_PREFIX) == 0) {
441 path.erase(0, CURRENT_PREFIX.size());
442 return CacheToWhole(context, path);
443 }
444 return CacheToWhole(context, path);
445 }
446
PathVecToNormal(const std::vector<std::string> & in,std::vector<std::string> & out)447 bool CJInitialize::PathVecToNormal(const std::vector<std::string> &in, std::vector<std::string> &out)
448 {
449 for (auto elem : in) {
450 if (elem == "..") {
451 if (out.size() > 0) {
452 out.pop_back();
453 } else {
454 return false;
455 }
456 } else {
457 out.push_back(elem);
458 }
459 }
460 return true;
461 }
462
WholeToNormal(const std::string & wholePath,std::string & normalPath,std::vector<std::string> & out)463 bool CJInitialize::WholeToNormal(const std::string &wholePath, std::string &normalPath, std::vector<std::string> &out)
464 {
465 std::vector<std::string> elems;
466 StringSplit(wholePath, '/', elems);
467 if (!PathVecToNormal(elems, out)) {
468 return false;
469 }
470 for (auto elem : out) {
471 normalPath += "/" + elem;
472 }
473 return true;
474 }
475
UploadBodyFileProc(std::string & fileName,Config & config)476 ExceptionError CJInitialize::UploadBodyFileProc(std::string &fileName, Config &config)
477 {
478 ExceptionError err;
479 int32_t bodyFd = open(fileName.c_str(), O_TRUNC | O_RDWR);
480 if (bodyFd < 0) {
481 bodyFd = open(fileName.c_str(), O_CREAT | O_RDWR, FILE_PERMISSION);
482 if (bodyFd < 0) {
483 err.code = ExceptionErrorCode::E_FILE_IO;
484 err.errInfo = "Failed to open file errno " + std::to_string(errno);
485 return err;
486 }
487 }
488
489 if (bodyFd >= 0) {
490 chmod(fileName.c_str(), S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
491 close(bodyFd);
492 }
493 config.bodyFileNames.push_back(fileName);
494
495 return err;
496 }
497
CheckUploadBodyFiles(Config & config,const std::string & filePath)498 ExceptionError CJInitialize::CheckUploadBodyFiles(Config &config, const std::string &filePath)
499 {
500 size_t len = config.files.size();
501 ExceptionError err;
502 for (size_t i = 0; i < len; i++) {
503 if (filePath.empty()) {
504 REQUEST_HILOGE("internal to cache error");
505 err.code = ExceptionErrorCode::E_PARAMETER_CHECK;
506 err.errInfo = "IsPathValid error empty path";
507 return err;
508 }
509 auto now = std::chrono::high_resolution_clock::now();
510 auto timestamp = std::chrono::duration_cast<std::chrono::nanoseconds>(now.time_since_epoch()).count();
511 std::string fileName = filePath + "/tmp_body_" + std::to_string(i) + "_" + std::to_string(timestamp);
512 REQUEST_HILOGD("Create upload body file, %{public}s", fileName.c_str());
513 if (!IsPathValid(fileName)) {
514 REQUEST_HILOGE("IsPathValid error %{public}s", fileName.c_str());
515 err.code = ExceptionErrorCode::E_PARAMETER_CHECK;
516 err.errInfo = "IsPathValid error fail path";
517 return err;
518 }
519 err = UploadBodyFileProc(fileName, config);
520 if (err.code != ExceptionErrorCode::E_OK) {
521 return err;
522 }
523 }
524 return err;
525 }
526
InterceptData(const std::string & str,const std::string & in,std::string & out)527 bool CJInitialize::InterceptData(const std::string &str, const std::string &in, std::string &out)
528 {
529 std::string tmpStr = std::string(in, 0, in.find_last_not_of(' ') + 1);
530 std::size_t position = tmpStr.find_last_of(str);
531 // when the str at last index, will error.
532 if (position == std::string::npos || position + 1 >= tmpStr.size()) {
533 return false;
534 }
535 out = std::string(tmpStr, position + 1);
536 return true;
537 }
538
GetFD(const std::string & path,const Config & config,int32_t & fd)539 ExceptionError CJInitialize::GetFD(const std::string &path, const Config &config, int32_t &fd)
540 {
541 ExceptionError err;
542 fd = config.action == Action::UPLOAD ? open(path.c_str(), O_RDONLY) : open(path.c_str(), O_TRUNC | O_RDWR);
543 if (fd >= 0) {
544 REQUEST_HILOGD("File already exists");
545 if (config.action == Action::UPLOAD) {
546 chmod(path.c_str(), S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
547 close(fd);
548 return err;
549 } else {
550 chmod(path.c_str(), S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
551 }
552
553 if (config.overwrite) {
554 close(fd);
555 return err;
556 }
557 if (!config.firstInit) {
558 REQUEST_HILOGD("CJRequestTask config is not firstInit");
559 close(fd);
560 return err;
561 }
562 close(fd);
563 err.code = ExceptionErrorCode::E_FILE_IO;
564 err.errInfo = "Download File already exists";
565 return err;
566 } else {
567 if (config.action == Action::UPLOAD) {
568 ExceptionErrorCode code = ExceptionErrorCode::E_FILE_IO;
569 err.code = ExceptionErrorCode::E_FILE_IO;
570 err.errInfo = "Failed to open file errno " + std::to_string(errno);
571 return err;
572 }
573 fd = open(path.c_str(), O_CREAT | O_RDWR, FILE_PERMISSION);
574 if (fd < 0) {
575 err.code = ExceptionErrorCode::E_FILE_IO;
576 err.errInfo = "Failed to open file errno " + std::to_string(errno);
577 return err;
578 }
579 chmod(path.c_str(), S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
580 close(fd);
581 }
582 return err;
583 }
584
GetInternalPath(const std::string & fileUri,const std::shared_ptr<OHOS::AbilityRuntime::Context> & context,Config & config,std::string & filePath)585 bool CJInitialize::GetInternalPath(const std::string &fileUri,
586 const std::shared_ptr<OHOS::AbilityRuntime::Context> &context, Config &config,
587 std::string &filePath)
588 {
589 if (config.action == Action::DOWNLOAD && fileUri.find('/') == 0) {
590 filePath = fileUri;
591 return true;
592 }
593 std::string fileName;
594 std::string pattern = "./";
595 size_t pos = fileUri.find(pattern);
596 if (pos != 0) {
597 fileName = fileUri;
598 } else {
599 fileName = fileUri.substr(pattern.size(), fileUri.size());
600 }
601 if (fileName.empty()) {
602 return false;
603 }
604 filePath = context->GetCacheDir();
605 if (filePath.empty()) {
606 REQUEST_HILOGE("internal to cache error");
607 return false;
608 }
609
610 filePath += "/" + fileName;
611 if (!IsPathValid(filePath)) {
612 REQUEST_HILOGE("IsPathValid error %{public}s", filePath.c_str());
613 return false;
614 }
615 return true;
616 }
617
CheckFileSpec(const std::shared_ptr<OHOS::AbilityRuntime::Context> & context,Config & config)618 ExceptionError CJInitialize::CheckFileSpec(const std::shared_ptr<OHOS::AbilityRuntime::Context> &context,
619 Config &config)
620 {
621 ExceptionError err;
622 for (auto &file : config.files) {
623 std::string path;
624 if (!GetInternalPath(file.uri, context, config, path)) {
625 err.code = ExceptionErrorCode::E_PARAMETER_CHECK;
626 err.errInfo = "this is fail path";
627 return err;
628 }
629 file.uri = path;
630 if (file.filename.empty()) {
631 InterceptData("/", file.uri, file.filename);
632 }
633 if (file.type.empty()) {
634 InterceptData(".", file.filename, file.type);
635 }
636 if (file.name.empty()) {
637 file.name = "file";
638 }
639
640 err = GetFD(path, config, file.fd);
641 if (err.code != ExceptionErrorCode::E_OK) {
642 return err;
643 }
644
645 if (!CJRequestTask::SetPathPermission(file.uri)) {
646 err.code = ExceptionErrorCode::E_FILE_IO;
647 err.errInfo = "set path permission fail";
648 return err;
649 }
650 }
651 return err;
652 }
653
CheckFilePath(const std::shared_ptr<OHOS::AbilityRuntime::Context> & context,Config & config)654 ExceptionError CJInitialize::CheckFilePath(const std::shared_ptr<OHOS::AbilityRuntime::Context> &context,
655 Config &config)
656 {
657 ExceptionError err;
658 if (config.action == Action::DOWNLOAD) {
659 if (!CheckDownloadFilePath(context, config, err.errInfo)) {
660 err.code = ExceptionErrorCode::E_PARAMETER_CHECK;
661 return err;
662 }
663
664 FileSpec file = {.uri = config.saveas};
665 config.files.push_back(file);
666 }
667
668 err = CheckFileSpec(context, config);
669 if (err.code != ExceptionErrorCode::E_OK) {
670 return err;
671 }
672
673 if (!CJRequestTask::SetDirsPermission(config.certsPath)) {
674 err.code = ExceptionErrorCode::E_FILE_IO;
675 err.errInfo = "set files of directors permission fail";
676 return err;
677 }
678
679 if (config.action == Action::UPLOAD) {
680 std::string filePath = context->GetCacheDir();
681 err = CheckUploadBodyFiles(config, filePath);
682 }
683
684 return err;
685 }
686
ParseConfig(OHOS::AbilityRuntime::Context * stageContext,const CConfig * ffiConfig,Config & config)687 ExceptionError CJInitialize::ParseConfig(OHOS::AbilityRuntime::Context *stageContext, const CConfig *ffiConfig,
688 Config &config)
689 {
690 config.action = (OHOS::Request::Action)ffiConfig->action;
691 config.withErrCode = true;
692 config.version = Version::API10; // CJ only support API10
693
694 ExceptionError err;
695 if (stageContext == nullptr) {
696 err.code = ExceptionErrorCode::E_PARAMETER_CHECK;
697 err.errInfo = "Get context fail";
698 return err;
699 }
700
701 std::shared_ptr<OHOS::AbilityRuntime::Context> context = stageContext->shared_from_this();
702 err = ParseBundleName(context, config.bundleName);
703 if (err.code != 0) {
704 return err;
705 }
706 err.code = ExceptionErrorCode::E_PARAMETER_CHECK;
707 if (!ParseUrl(config.url)) {
708 err.errInfo = "parse url error";
709 return err;
710 }
711
712 if (!ParseCertsPath(config.url, config.certsPath)) {
713 err.errInfo = "parse certs path error";
714 return err;
715 }
716
717 if (!ParseData(ffiConfig, config)) {
718 err.errInfo = "parse data error";
719 return err;
720 }
721
722 if (!ParseIndex(config)) {
723 err.errInfo = "Index exceeds file list";
724 return err;
725 }
726
727 if (!ParseToken(config, err.errInfo)) {
728 return err;
729 }
730
731 if (!ParseTitle(config) || !ParseDescription(config.description)) {
732 err.errInfo = "Exceeding maximum length";
733 return err;
734 }
735
736 if (!ParseSaveas(config)) {
737 err.errInfo = "parse saveas error";
738 return err;
739 }
740
741 ParseMethod(config);
742 ParseNetwork(config.network);
743 ParseBackGround(config.mode, config.background);
744 config.begins = ParseBegins(config.begins);
745
746 return CheckFilePath(context, config);
747 }
748
FindDir(const std::string & pathDir)749 bool CJInitialize::FindDir(const std::string &pathDir)
750 {
751 std::error_code err;
752 return std::filesystem::exists(pathDir, err);
753 }
754
755 } // namespace OHOS::CJSystemapi::Request
756