1 /*
2 * Copyright (c) 2022 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 <thread>
17 #include <cstdio>
18 #include "upload_task.h"
19 #include "file_adapter.h"
20
21 using namespace OHOS::AppExecFwk;
22 namespace OHOS::Request::Upload {
ObtainFile()23 ObtainFile::ObtainFile()
24 {
25 fileAdapter_ = std::make_shared<FileAdapter>();
26 }
~ObtainFile()27 ObtainFile::~ObtainFile()
28 {
29 }
30
GetFile(FILE ** file,std::string & fileUri,unsigned int & fileSize,std::shared_ptr<OHOS::AbilityRuntime::Context> & context)31 uint32_t ObtainFile::GetFile(FILE **file, std::string &fileUri,
32 unsigned int& fileSize, std::shared_ptr<OHOS::AbilityRuntime::Context> &context)
33 {
34 uint32_t ret = UPLOAD_OK;
35 std::string dataAbilityHead("dataability");
36 std::string internalHead("internal");
37
38 // file type check
39 if (fileUri.compare(0, dataAbilityHead.size(), dataAbilityHead) == 0) {
40 UPLOAD_HILOGD(UPLOAD_MODULE_FRAMEWORK, "GetDataAbilityFile");
41 ret = GetDataAbilityFile(file, fileUri, fileSize, context);
42 } else if (fileUri.compare(0, internalHead.size(), internalHead) == 0) {
43 UPLOAD_HILOGD(UPLOAD_MODULE_FRAMEWORK, "GetInternalFile");
44 ret = GetInternalFile(file, fileUri, fileSize, context);
45 } else {
46 UPLOAD_HILOGE(UPLOAD_MODULE_FRAMEWORK, "wrong path");
47 ret = UPLOAD_ERRORCODE_UNSUPPORT_URI;
48 *file = nullptr;
49 fileSize = 0;
50 }
51
52 UPLOAD_HILOGD(UPLOAD_MODULE_FRAMEWORK, "get file ret : %{public}d, size : %{public}u", ret, fileSize);
53 return ret;
54 }
55
GetDataAbilityFile(FILE ** file,std::string & fileUri,uint32_t & fileSize,std::shared_ptr<OHOS::AbilityRuntime::Context> & context)56 uint32_t ObtainFile::GetDataAbilityFile(FILE **file, std::string &fileUri,
57 uint32_t& fileSize, std::shared_ptr<OHOS::AbilityRuntime::Context> &context)
58 {
59 uint32_t ret = UPLOAD_OK;
60 FILE *filePtr = nullptr;
61 int32_t fileLength = 0;
62
63 do {
64 int32_t fd = fileAdapter_->DataAbilityOpenFile(fileUri, context);
65 if (fd < 0) {
66 UPLOAD_HILOGE(UPLOAD_MODULE_FRAMEWORK, "ObtainFile::GetDataAbilityFile, open file error.");
67 ret = UPLOAD_ERRORCODE_GET_FILE_ERROR;
68 break;
69 }
70
71 filePtr = fdopen(fd, "r");
72 if (filePtr == nullptr) {
73 UPLOAD_HILOGE(UPLOAD_MODULE_FRAMEWORK, "ObtainFile::GetDataAbilityFile, fdopen error.");
74 ret = UPLOAD_ERRORCODE_GET_FILE_ERROR;
75 break;
76 }
77
78 (void)fseek(filePtr, 0, SEEK_END);
79 fileLength = ftell(filePtr);
80 if (fileLength == -1) {
81 UPLOAD_HILOGE(UPLOAD_MODULE_FRAMEWORK, "ObtainFile::GetDataAbilityFile, ftell error.");
82 ret = UPLOAD_ERRORCODE_GET_FILE_ERROR;
83 break;
84 }
85 (void)fseek(filePtr, 0, SEEK_SET);
86 } while (0);
87
88 *file = filePtr;
89 fileSize = static_cast<uint32_t>(fileLength);
90 return ret;
91 }
92
IsValidPath(const std::string & filePath)93 bool ObtainFile::IsValidPath(const std::string &filePath)
94 {
95 char resolvedPath[PATH_MAX + 1] = { 0 };
96 if (filePath.length() > PATH_MAX || realpath(filePath.c_str(), resolvedPath) == nullptr ||
97 strncmp(resolvedPath, filePath.c_str(), filePath.length()) != 0) {
98 UPLOAD_HILOGE(UPLOAD_MODULE_FRAMEWORK, "filePath error");
99 return false;
100 }
101 return true;
102 }
103
SplitPath(const std::string & fileUri,std::string & fileName)104 bool ObtainFile::SplitPath(const std::string &fileUri, std::string &fileName)
105 {
106 std::string pattern = "internal://cache/";
107 size_t pos = fileUri.find(pattern);
108 if (pos != 0) {
109 UPLOAD_HILOGE(UPLOAD_MODULE_FRAMEWORK, "internal path is invalid");
110 return false;
111 }
112 fileName = fileUri.substr(pattern.size(), fileUri.size());
113 return true;
114 }
115
GetInternalFile(FILE ** file,const std::string & fileUri,uint32_t & fileSize,std::shared_ptr<OHOS::AbilityRuntime::Context> & context)116 uint32_t ObtainFile::GetInternalFile(FILE **file, const std::string &fileUri, uint32_t &fileSize,
117 std::shared_ptr<OHOS::AbilityRuntime::Context> &context)
118 {
119 std::string fileName;
120 if (!SplitPath(fileUri, fileName)) {
121 return UPLOAD_ERRORCODE_UNSUPPORT_URI;
122 }
123 std::string filePath = fileAdapter_->InternalGetFilePath(context);
124 if (filePath.empty()) {
125 UPLOAD_HILOGE(UPLOAD_MODULE_FRAMEWORK, "ObtainFile::GetInternalFile, internal to cache error");
126 return UPLOAD_ERRORCODE_GET_FILE_ERROR;
127 }
128 filePath += "/" + fileName;
129 if (!IsValidPath(filePath)) {
130 return UPLOAD_ERRORCODE_GET_FILE_ERROR;
131 }
132 FILE *filePtr = fopen(filePath.c_str(), "r");
133 if (filePtr == nullptr) {
134 UPLOAD_HILOGE(UPLOAD_MODULE_FRAMEWORK, "open file error, error info : %{public}d.", errno);
135 return UPLOAD_ERRORCODE_GET_FILE_ERROR;
136 }
137 (void)fseek(filePtr, 0, SEEK_END);
138 int32_t fileLength = ftell(filePtr);
139 (void)fseek(filePtr, 0, SEEK_SET);
140
141 *file = filePtr;
142 fileSize = fileLength;
143 return UPLOAD_OK;
144 }
145 } // end of OHOS::Request::Upload