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