• 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 "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