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 "upload/upload_task.h"
17
18 #include <pthread.h>
19
20 #include <thread>
21
22 #include "curl/curl.h"
23 #include "curl/easy.h"
24
25 namespace OHOS::Request::Upload {
UploadTask(std::shared_ptr<UploadConfig> & uploadConfig)26 UploadTask::UploadTask(std::shared_ptr<UploadConfig> &uploadConfig)
27 {
28 UPLOAD_HILOGD(UPLOAD_MODULE_FRAMEWORK, "UploadTask. In.");
29 uploadConfig_ = uploadConfig;
30 curlAdp_ = nullptr;
31 state_ = STATE_INIT;
32 uploadedSize_ = 0;
33 totalSize_ = 0;
34 context_ = nullptr;
35 isRemoved_ = false;
36 }
37
~UploadTask()38 UploadTask::~UploadTask()
39 {
40 UPLOAD_HILOGD(UPLOAD_MODULE_FRAMEWORK, "~UploadTask. In.");
41 std::lock_guard<std::mutex> guard(mutex_);
42 if (!isRemoved_) {
43 Remove();
44 }
45 }
46
Remove()47 bool UploadTask::Remove()
48 {
49 UPLOAD_HILOGD(UPLOAD_MODULE_FRAMEWORK, "Remove. In.");
50 std::lock_guard<std::mutex> guard(removeMutex_);
51 isRemoved_ = true;
52 if (curlAdp_ != nullptr) {
53 curlAdp_->Remove();
54 }
55 ClearFileArray();
56 return true;
57 }
58
SetContext(std::shared_ptr<OHOS::AbilityRuntime::Context> context)59 void UploadTask::SetContext(std::shared_ptr<OHOS::AbilityRuntime::Context> context)
60 {
61 UPLOAD_HILOGD(UPLOAD_MODULE_FRAMEWORK, "SetContext. In.");
62 context_ = context;
63 }
64
SetUploadProxy(std::shared_ptr<UploadTaskNapiV5> proxy)65 void UploadTask::SetUploadProxy(std::shared_ptr<UploadTaskNapiV5> proxy)
66 {
67 uploadProxy_ = proxy;
68 }
69
Run(std::shared_ptr<Upload::UploadTask> task)70 void UploadTask::Run(std::shared_ptr<Upload::UploadTask> task)
71 {
72 UPLOAD_HILOGD(UPLOAD_MODULE_FRAMEWORK, "Run. In.");
73 pthread_setname_np(pthread_self(), "upload_task");
74 usleep(USLEEP_INTERVAL_BEFORE_RUN);
75 if (task == nullptr) {
76 UPLOAD_HILOGE(UPLOAD_MODULE_FRAMEWORK, "task == nullptr");
77 return;
78 }
79 task->OnRun();
80 std::lock_guard<std::mutex> guard(task->removeMutex_);
81 if (task->isRemoved_) {
82 task->SetUploadProxy(nullptr);
83 return;
84 }
85 if (task->uploadConfig_->protocolVersion == API3) {
86 if (task->uploadConfig_->fcomplete) {
87 task->uploadConfig_->fcomplete();
88 UPLOAD_HILOGD(UPLOAD_MODULE_FRAMEWORK, "Complete.");
89 }
90 }
91 task->SetUploadProxy(nullptr);
92 }
93
InitFileArray()94 uint32_t UploadTask::InitFileArray()
95 {
96 UPLOAD_HILOGD(UPLOAD_MODULE_FRAMEWORK, "InitFileArray. In.");
97 unsigned int fileSize = 0;
98 FileData data;
99 FILE *file;
100 totalSize_ = 0;
101 uint32_t initResult = UPLOAD_OK;
102 ObtainFile obtainFile;
103 uint32_t index = 1;
104 for (auto f : uploadConfig_->files) {
105 UPLOAD_HILOGD(UPLOAD_MODULE_FRAMEWORK, "filename is %{public}s", f.filename.c_str());
106 data.result = UPLOAD_ERRORCODE_UPLOAD_FAIL;
107 uint32_t ret = obtainFile.GetFile(&file, f.uri, fileSize, context_);
108 if (ret != UPLOAD_OK) {
109 initResult = data.result;
110 data.result = ret;
111 }
112
113 data.fp = file;
114 std::size_t position = f.uri.find_last_of("/");
115 if (position != std::string::npos) {
116 data.filename = std::string(f.uri, position + 1);
117 data.filename.erase(data.filename.find_last_not_of(" ") + 1);
118 }
119 data.name = f.name;
120 data.type = f.type;
121 data.fileIndex = index++;
122 data.adp = nullptr;
123 data.upsize = 0;
124 data.totalsize = fileSize;
125 data.list = nullptr;
126 data.headSendFlag = 0;
127 data.httpCode = 0;
128
129 fileDatas_.push_back(data);
130 totalSize_ += static_cast<int64_t>(fileSize);
131 }
132
133 return initResult;
134 }
135
StartUploadFile()136 uint32_t UploadTask::StartUploadFile()
137 {
138 if (isRemoved_) {
139 UPLOAD_HILOGD(UPLOAD_MODULE_FRAMEWORK, "upload task removed");
140 return UPLOAD_TASK_REMOVED;
141 }
142 uint32_t ret = InitFileArray();
143 if (ret != UPLOAD_OK) {
144 return ret;
145 }
146 curlAdp_ = std::make_shared<CUrlAdp>(fileDatas_, uploadConfig_);
147 return curlAdp_->DoUpload(shared_from_this());
148 }
149
OnRun()150 void UploadTask::OnRun()
151 {
152 UPLOAD_HILOGD(UPLOAD_MODULE_FRAMEWORK, "OnRun. In.");
153 state_ = STATE_RUNNING;
154 uint32_t ret = StartUploadFile();
155 std::lock_guard<std::mutex> guard(removeMutex_);
156 if (!isRemoved_) {
157 if (ret != UPLOAD_OK) {
158 UPLOAD_HILOGE(UPLOAD_MODULE_FRAMEWORK, "ret != UPLOAD_OK");
159 state_ = STATE_FAILURE;
160 } else {
161 state_ = STATE_SUCCESS;
162 }
163 ClearFileArray();
164 }
165 totalSize_ = 0;
166 }
167
ExecuteTask()168 void UploadTask::ExecuteTask()
169 {
170 UPLOAD_HILOGD(UPLOAD_MODULE_FRAMEWORK, "ExecuteTask. In.");
171 thread_ = std::make_unique<std::thread>(UploadTask::Run, shared_from_this());
172 thread_handle_ = thread_->native_handle();
173 thread_->detach();
174 }
175
ClearFileArray()176 void UploadTask::ClearFileArray()
177 {
178 UPLOAD_HILOGD(UPLOAD_MODULE_FRAMEWORK, "ClearFileArray()");
179 if (fileDatas_.empty()) {
180 return;
181 }
182 for (auto &file : fileDatas_) {
183 if (file.fp != NULL) {
184 fclose(file.fp);
185 }
186 file.name = "";
187 }
188 fileDatas_.clear();
189 }
190 } // namespace OHOS::Request::Upload