• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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