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