• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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 <iostream>
17 #include <memory>
18 
19 #include "http_client_task.h"
20 #include "http_client.h"
21 #include "http_client_constant.h"
22 #include "http_client_time.h"
23 #include "netstack_common_utils.h"
24 #include "netstack_log.h"
25 
26 #define NETSTACK_CURL_EASY_SET_OPTION(handle, opt, data)                                                 \
27     do {                                                                                                 \
28         CURLcode result = curl_easy_setopt(handle, opt, data);                                           \
29         if (result != CURLE_OK) {                                                                        \
30             const char *err = curl_easy_strerror(result);                                                \
31             error_.SetCURLResult(result);                                                                \
32             NETSTACK_LOGE("Failed to set option: %{public}s, %{public}s %{public}d", #opt, err, result); \
33             return false;                                                                                \
34         }                                                                                                \
35     } while (0)
36 
37 namespace OHOS {
38 namespace NetStack {
39 namespace HttpClient {
40 
41 static constexpr size_t MAX_LIMIT = 5 * 1024 * 1024;
42 std::atomic<uint32_t> HttpClientTask::nextTaskId_(0);
43 
CheckFilePath(const std::string & fileName,std::string & realPath)44 bool CheckFilePath(const std::string &fileName, std::string &realPath)
45 {
46     char tmpPath[PATH_MAX] = {0};
47     if (!realpath(static_cast<const char *>(fileName.c_str()), tmpPath)) {
48         NETSTACK_LOGE("file name is error");
49         return false;
50     }
51 
52     realPath = tmpPath;
53     return true;
54 }
55 
HttpClientTask(const HttpClientRequest & request)56 HttpClientTask::HttpClientTask(const HttpClientRequest &request)
57     : request_(request),
58       type_(DEFAULT),
59       status_(IDLE),
60       taskId_(nextTaskId_++),
61       curlHeaderList_(nullptr),
62       canceled_(false),
63       file_(nullptr)
64 {
65     NETSTACK_LOGI("HttpClientTask::HttpClientTask() taskId_=%{public}d URL=%{public}s", taskId_,
66                   request_.GetURL().c_str());
67 
68     curlHandle_ = curl_easy_init();
69     if (!curlHandle_) {
70         NETSTACK_LOGE("Failed to create task!");
71         return;
72     }
73 
74     SetCurlOptions();
75 }
76 
HttpClientTask(const HttpClientRequest & request,TaskType type,const std::string & filePath)77 HttpClientTask::HttpClientTask(const HttpClientRequest &request, TaskType type, const std::string &filePath)
78     : request_(request),
79       type_(type),
80       status_(IDLE),
81       taskId_(nextTaskId_++),
82       curlHeaderList_(nullptr),
83       canceled_(false),
84       filePath_(filePath),
85       file_(nullptr)
86 {
87     NETSTACK_LOGI(
88         "HttpClientTask::HttpClientTask() taskId_=%{public}d URL=%{public}s type=%{public}d filePath=%{public}s",
89         taskId_, request_.GetURL().c_str(), type_, filePath_.c_str());
90 
91     curlHandle_ = curl_easy_init();
92     if (!curlHandle_) {
93         NETSTACK_LOGE("Failed to create task!");
94         return;
95     }
96 
97     SetCurlOptions();
98 }
99 
~HttpClientTask()100 HttpClientTask::~HttpClientTask()
101 {
102     NETSTACK_LOGD("HttpClientTask::~HttpClientTask()");
103     if (curlHeaderList_ != nullptr) {
104         curl_slist_free_all(curlHeaderList_);
105         curlHeaderList_ = nullptr;
106     }
107 
108     if (curlHandle_) {
109         curl_easy_cleanup(curlHandle_);
110         curlHandle_ = nullptr;
111     }
112 
113     if (file_ != nullptr) {
114         fclose(file_);
115         file_ = nullptr;
116     }
117 }
118 
GetHttpVersion(HttpProtocol ptcl) const119 uint32_t HttpClientTask::GetHttpVersion(HttpProtocol ptcl) const
120 {
121     if (ptcl == HttpProtocol::HTTP1_1) {
122         NETSTACK_LOGD("CURL_HTTP_VERSION_1_1");
123         return CURL_HTTP_VERSION_1_1;
124     } else if (ptcl == HttpProtocol::HTTP2) {
125         NETSTACK_LOGD("CURL_HTTP_VERSION_2_0");
126         return CURL_HTTP_VERSION_2_0;
127     }
128     return CURL_HTTP_VERSION_NONE;
129 }
130 
GetHttpProxyInfo(std::string & host,int32_t & port,std::string & exclusions,std::string & userpwd,bool & tunnel)131 void HttpClientTask::GetHttpProxyInfo(std::string &host, int32_t &port, std::string &exclusions, std::string &userpwd,
132                                       bool &tunnel)
133 {
134     if (request_.GetHttpProxyType() == HttpProxyType::USE_SPECIFIED) {
135         HttpProxy proxy = request_.GetHttpProxy();
136         host = proxy.host;
137         port = proxy.port;
138         exclusions = proxy.exclusions;
139         userpwd = proxy.userpwd;
140         tunnel = proxy.tunnel;
141     }
142 }
143 
SetOtherCurlOption(CURL * handle)144 bool HttpClientTask::SetOtherCurlOption(CURL *handle)
145 {
146     // set proxy
147     std::string host, exclusions, userpwd;
148     int32_t port = 0;
149     bool tunnel = false;
150     GetHttpProxyInfo(host, port, exclusions, userpwd, tunnel);
151     if (!host.empty()) {
152         NETSTACK_CURL_EASY_SET_OPTION(handle, CURLOPT_PROXY, host.c_str());
153         NETSTACK_CURL_EASY_SET_OPTION(handle, CURLOPT_PROXYPORT, port);
154         NETSTACK_CURL_EASY_SET_OPTION(handle, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
155         if (!exclusions.empty()) {
156             NETSTACK_CURL_EASY_SET_OPTION(handle, CURLOPT_NOPROXY, exclusions.c_str());
157         }
158         if (!userpwd.empty()) {
159             NETSTACK_CURL_EASY_SET_OPTION(handle, CURLOPT_PROXYUSERPWD, userpwd.c_str());
160         }
161         if (tunnel) {
162             NETSTACK_CURL_EASY_SET_OPTION(handle, CURLOPT_HTTPPROXYTUNNEL, 1L);
163         }
164     }
165 
166 #ifdef NO_SSL_CERTIFICATION
167     // in real life, you should buy a ssl certification and rename it to /etc/ssl/cert.pem
168     NETSTACK_CURL_EASY_SET_OPTION(curlHandle_, CURLOPT_SSL_VERIFYHOST, 0L);
169     NETSTACK_CURL_EASY_SET_OPTION(curlHandle_, CURLOPT_SSL_VERIFYPEER, 0L);
170 #else
171 #ifndef WINDOWS_PLATFORM
172     NETSTACK_CURL_EASY_SET_OPTION(handle, CURLOPT_CAINFO, request_.GetCaPath().c_str());
173 #endif // WINDOWS_PLATFORM
174 #endif // NO_SSL_CERTIFICATION
175 
176 #ifdef HTTP_CURL_PRINT_VERBOSE
177     NETSTACK_CURL_EASY_SET_OPTION(curlHandle_, CURLOPT_VERBOSE, 1L);
178 #endif
179 
180 #ifndef WINDOWS_PLATFORM
181     NETSTACK_CURL_EASY_SET_OPTION(handle, CURLOPT_ACCEPT_ENCODING, HttpConstant::HTTP_CONTENT_ENCODING_GZIP);
182 #endif
183 
184     return true;
185 }
186 
SetUploadOptions(CURL * handle)187 bool HttpClientTask::SetUploadOptions(CURL *handle)
188 {
189     if (filePath_.empty()) {
190         NETSTACK_LOGE("HttpClientTask::SetUploadOptions() filePath_ is empty");
191         error_.SetErrorCode(HttpErrorCode::HTTP_UPLOAD_FAILED);
192         return false;
193     }
194 
195     std::string realPath;
196     if (!CheckFilePath(filePath_, realPath)) {
197         NETSTACK_LOGE("filePath_ does not exist! ");
198         error_.SetErrorCode(HttpErrorCode::HTTP_UPLOAD_FAILED);
199         return false;
200     }
201 
202     file_ = fopen(realPath.c_str(), "rb");
203     if (file_ == nullptr) {
204         NETSTACK_LOGE("HttpClientTask::SetUploadOptions() Failed to open file %{public}s", realPath.c_str());
205         error_.SetErrorCode(HttpErrorCode::HTTP_UPLOAD_FAILED);
206         return false;
207     }
208 
209     NETSTACK_LOGI("HttpClientTask::SetUploadOptions() filePath_=%{public}s", realPath.c_str());
210     fseek(file_, 0, SEEK_END);
211     long size = ftell(file_);
212     rewind(file_);
213 
214     // Set the file data and file size to upload
215     NETSTACK_CURL_EASY_SET_OPTION(curlHandle_, CURLOPT_READDATA, file_);
216     NETSTACK_LOGI("HttpClientTask::SetUploadOptions() CURLOPT_INFILESIZE=%{public}ld", size);
217     NETSTACK_CURL_EASY_SET_OPTION(curlHandle_, CURLOPT_INFILESIZE, size);
218     NETSTACK_CURL_EASY_SET_OPTION(curlHandle_, CURLOPT_UPLOAD, 1L);
219 
220     return true;
221 }
222 
SetCurlOptions()223 bool HttpClientTask::SetCurlOptions()
224 {
225     auto method = request_.GetMethod();
226     if (method == HttpConstant::HTTP_METHOD_HEAD) {
227         NETSTACK_CURL_EASY_SET_OPTION(curlHandle_, CURLOPT_NOBODY, 1L);
228     }
229 
230     NETSTACK_CURL_EASY_SET_OPTION(curlHandle_, CURLOPT_URL, request_.GetURL().c_str());
231 
232     if (type_ == TaskType::UPLOAD) {
233         if (!SetUploadOptions(curlHandle_)) {
234             return false;
235         }
236     } else {
237         NETSTACK_CURL_EASY_SET_OPTION(curlHandle_, CURLOPT_CUSTOMREQUEST, request_.GetMethod().c_str());
238 
239         if ((method == HttpConstant::HTTP_METHOD_POST || method == HttpConstant::HTTP_METHOD_PUT) &&
240             !request_.GetBody().empty()) {
241             NETSTACK_CURL_EASY_SET_OPTION(curlHandle_, CURLOPT_POST, 1L);
242             NETSTACK_CURL_EASY_SET_OPTION(curlHandle_, CURLOPT_POSTFIELDS, request_.GetBody().c_str());
243             NETSTACK_CURL_EASY_SET_OPTION(curlHandle_, CURLOPT_POSTFIELDSIZE, request_.GetBody().size());
244         }
245     }
246 
247     NETSTACK_CURL_EASY_SET_OPTION(curlHandle_, CURLOPT_XFERINFOFUNCTION, ProgressCallback);
248     NETSTACK_CURL_EASY_SET_OPTION(curlHandle_, CURLOPT_XFERINFODATA, &taskId_);
249     NETSTACK_CURL_EASY_SET_OPTION(curlHandle_, CURLOPT_NOPROGRESS, 0L);
250 
251     NETSTACK_CURL_EASY_SET_OPTION(curlHandle_, CURLOPT_WRITEFUNCTION, DataReceiveCallback);
252     NETSTACK_CURL_EASY_SET_OPTION(curlHandle_, CURLOPT_WRITEDATA, &taskId_);
253 
254     NETSTACK_CURL_EASY_SET_OPTION(curlHandle_, CURLOPT_HEADERFUNCTION, HeaderReceiveCallback);
255     NETSTACK_CURL_EASY_SET_OPTION(curlHandle_, CURLOPT_HEADERDATA, &taskId_);
256 
257     if (curlHeaderList_ != nullptr) {
258         curl_slist_free_all(curlHeaderList_);
259         curlHeaderList_ = nullptr;
260     }
261     for (const auto &header : request_.GetHeaders()) {
262         std::string headerStr = header.first + HttpConstant::HTTP_HEADER_SEPARATOR + header.second;
263         curlHeaderList_ = curl_slist_append(curlHeaderList_, headerStr.c_str());
264     }
265     NETSTACK_CURL_EASY_SET_OPTION(curlHandle_, CURLOPT_HTTPHEADER, curlHeaderList_);
266 
267     // Some servers don't like requests that are made without a user-agent field, so we provide one
268     NETSTACK_CURL_EASY_SET_OPTION(curlHandle_, CURLOPT_USERAGENT, HttpConstant::HTTP_DEFAULT_USER_AGENT);
269 
270     NETSTACK_CURL_EASY_SET_OPTION(curlHandle_, CURLOPT_FOLLOWLOCATION, 1L);
271 
272     /* first #undef CURL_DISABLE_COOKIES in curl config */
273     NETSTACK_CURL_EASY_SET_OPTION(curlHandle_, CURLOPT_COOKIEFILE, "");
274 
275     NETSTACK_CURL_EASY_SET_OPTION(curlHandle_, CURLOPT_NOSIGNAL, 1L);
276 
277     NETSTACK_CURL_EASY_SET_OPTION(curlHandle_, CURLOPT_TIMEOUT_MS, request_.GetTimeout());
278     NETSTACK_CURL_EASY_SET_OPTION(curlHandle_, CURLOPT_CONNECTTIMEOUT_MS, request_.GetConnectTimeout());
279 
280     NETSTACK_CURL_EASY_SET_OPTION(curlHandle_, CURLOPT_HTTP_VERSION, GetHttpVersion(request_.GetHttpProtocol()));
281 
282     if (!SetOtherCurlOption(curlHandle_)) {
283         return false;
284     }
285 
286     return true;
287 }
288 
Start()289 bool HttpClientTask::Start()
290 {
291     auto task = shared_from_this();
292     if (task->GetStatus() != TaskStatus::IDLE) {
293         NETSTACK_LOGI("HttpClientTask::Start() task is running, taskId_=%{public}d", task->GetTaskId());
294         return false;
295     }
296 
297     if (!CommonUtils::HasInternetPermission()) {
298         NETSTACK_LOGE("HttpClientTask::Start() Don't Has Internet Permission()");
299         error_.SetErrorCode(HttpErrorCode::HTTP_PERMISSION_DENIED_CODE);
300         return false;
301     }
302 
303     if (error_.GetErrorCode() != HttpErrorCode::HTTP_NONE_ERR) {
304         NETSTACK_LOGE("HttpClientTask::Start() error_.GetErrorCode()=%{public}d", error_.GetErrorCode());
305         return false;
306     }
307 
308     request_.SetRequestTime(HttpTime::GetNowTimeGMT());
309 
310     HttpSession &session = HttpSession::GetInstance();
311     NETSTACK_LOGD("HttpClientTask::Start() taskId_=%{public}d", taskId_);
312     task->canceled_ = false;
313 
314     response_.SetRequestTime(HttpTime::GetNowTimeGMT());
315     session.StartTask(task);
316 
317     return true;
318 }
319 
Cancel()320 void HttpClientTask::Cancel()
321 {
322     canceled_ = true;
323 }
324 
SetStatus(TaskStatus status)325 void HttpClientTask::SetStatus(TaskStatus status)
326 {
327     status_ = status;
328 }
329 
GetStatus()330 TaskStatus HttpClientTask::GetStatus()
331 {
332     return status_;
333 }
334 
GetType()335 TaskType HttpClientTask::GetType()
336 {
337     return type_;
338 }
339 
GetFilePath()340 const std::string &HttpClientTask::GetFilePath()
341 {
342     return filePath_;
343 }
344 
GetTaskId()345 unsigned int HttpClientTask::GetTaskId()
346 {
347     return taskId_;
348 }
349 
OnSuccess(const std::function<void (const HttpClientRequest & request,const HttpClientResponse & response)> & onSucceeded)350 void HttpClientTask::OnSuccess(
351     const std::function<void(const HttpClientRequest &request, const HttpClientResponse &response)> &onSucceeded)
352 {
353     onSucceeded_ = onSucceeded;
354 }
355 
OnCancel(const std::function<void (const HttpClientRequest & request,const HttpClientResponse & response)> & onCanceled)356 void HttpClientTask::OnCancel(
357     const std::function<void(const HttpClientRequest &request, const HttpClientResponse &response)> &onCanceled)
358 {
359     onCanceled_ = onCanceled;
360 }
361 
OnFail(const std::function<void (const HttpClientRequest & request,const HttpClientResponse & response,const HttpClientError & error)> & onFailed)362 void HttpClientTask::OnFail(
363     const std::function<void(const HttpClientRequest &request, const HttpClientResponse &response,
364                              const HttpClientError &error)> &onFailed)
365 {
366     onFailed_ = onFailed;
367 }
368 
OnDataReceive(const std::function<void (const HttpClientRequest & request,const uint8_t * data,size_t length)> & onDataReceive)369 void HttpClientTask::OnDataReceive(
370     const std::function<void(const HttpClientRequest &request, const uint8_t *data, size_t length)> &onDataReceive)
371 {
372     onDataReceive_ = onDataReceive;
373 }
374 
OnProgress(const std::function<void (const HttpClientRequest & request,u_long dlTotal,u_long dlNow,u_long ulTotal,u_long ulNow)> & onProgress)375 void HttpClientTask::OnProgress(const std::function<void(const HttpClientRequest &request, u_long dlTotal, u_long dlNow,
376                                                          u_long ulTotal, u_long ulNow)> &onProgress)
377 {
378     onProgress_ = onProgress;
379 }
380 
DataReceiveCallback(const void * data,size_t size,size_t memBytes,void * userData)381 size_t HttpClientTask::DataReceiveCallback(const void *data, size_t size, size_t memBytes, void *userData)
382 {
383     unsigned int taskId = *reinterpret_cast<unsigned int *>(userData);
384     NETSTACK_LOGD("HttpClientTask::DataReceiveCallback() taskId=%{public}d size=%{public}zu memBytes=%{public}zu",
385                   taskId, size, memBytes);
386 
387     auto task = HttpSession::GetInstance().GetTaskById(taskId);
388     if (task == nullptr) {
389         NETSTACK_LOGE("HttpClientTask::DataReceiveCallback() task == nullptr");
390         return 0;
391     }
392 
393     if (task->canceled_) {
394         NETSTACK_LOGD("HttpClientTask::DataReceiveCallback() canceled");
395         return 0;
396     }
397 
398     if (task->onDataReceive_) {
399         HttpClientRequest request = task->request_;
400         task->onDataReceive_(request, static_cast<const uint8_t *>(data), size * memBytes);
401     }
402 
403     if (task->response_.GetResult().size() < MAX_LIMIT) {
404         task->response_.AppendResult(data, size * memBytes);
405     }
406 
407     return size * memBytes;
408 }
409 
ProgressCallback(void * userData,curl_off_t dltotal,curl_off_t dlnow,curl_off_t ultotal,curl_off_t ulnow)410 int HttpClientTask::ProgressCallback(void *userData, curl_off_t dltotal, curl_off_t dlnow, curl_off_t ultotal,
411                                      curl_off_t ulnow)
412 {
413     unsigned int taskId = *reinterpret_cast<unsigned int *>(userData);
414     NETSTACK_LOGD("HttpClientTask::ProgressCallback() taskId=%{public}d dltotal=%{public}" CURL_FORMAT_CURL_OFF_T
415                   " dlnow=%{public}" CURL_FORMAT_CURL_OFF_T " ultotal=%{public}" CURL_FORMAT_CURL_OFF_T
416                   " ulnow=%{public}" CURL_FORMAT_CURL_OFF_T,
417                   taskId, dltotal, dlnow, ultotal, ulnow);
418 
419     auto task = HttpSession::GetInstance().GetTaskById(taskId);
420     if (task == nullptr) {
421         NETSTACK_LOGE("HttpClientTask::ProgressCallback() task == nullptr");
422         return 0;
423     }
424 
425     if (task->canceled_) {
426         NETSTACK_LOGI("HttpClientTask::ProgressCallback() canceled");
427         return CURLE_ABORTED_BY_CALLBACK;
428     }
429 
430     if (task->onProgress_) {
431         task->onProgress_(task->request_, dltotal, dlnow, ultotal, ulnow);
432     }
433 
434     return 0;
435 }
436 
HeaderReceiveCallback(const void * data,size_t size,size_t memBytes,void * userData)437 size_t HttpClientTask::HeaderReceiveCallback(const void *data, size_t size, size_t memBytes, void *userData)
438 {
439     unsigned int taskId = *reinterpret_cast<unsigned int *>(userData);
440     NETSTACK_LOGD("HttpClientTask::HeaderReceiveCallback() taskId=%{public}d size=%{public}zu memBytes=%{public}zu",
441                   taskId, size, memBytes);
442 
443     if (size * memBytes > MAX_LIMIT) {
444         NETSTACK_LOGE("HttpClientTask::HeaderReceiveCallback() size * memBytes(%{public}zu) > MAX_LIMIT(%{public}zu)",
445                       size * memBytes, MAX_LIMIT);
446         return 0;
447     }
448 
449     auto task = HttpSession::GetInstance().GetTaskById(taskId);
450     if (task == nullptr) {
451         NETSTACK_LOGE("HttpClientTask::HeaderReceiveCallback() task == nullptr");
452         return 0;
453     }
454 
455     NETSTACK_LOGD("HttpClientTask::HeaderReceiveCallback() (const char *)data=%{public}s",
456                   static_cast<const char *>(data));
457     task->response_.AppendHeader(static_cast<const char *>(data), size * memBytes);
458 
459     return size * memBytes;
460 }
461 
ProcessCookie(CURL * handle)462 void HttpClientTask::ProcessCookie(CURL *handle)
463 {
464     struct curl_slist *cookies = nullptr;
465     if (handle == nullptr) {
466         NETSTACK_LOGE("HttpClientTask::ProcessCookie() handle == nullptr");
467         return;
468     }
469 
470     CURLcode res = curl_easy_getinfo(handle, CURLINFO_COOKIELIST, &cookies);
471     if (res != CURLE_OK) {
472         NETSTACK_LOGE("HttpClientTask::ProcessCookie() curl_easy_getinfo() error! res = %{public}d", res);
473         return;
474     }
475 
476     while (cookies) {
477         response_.AppendCookies(cookies->data, strlen(cookies->data));
478         if (cookies->next != nullptr) {
479             response_.AppendCookies(HttpConstant::HTTP_LINE_SEPARATOR, strlen(HttpConstant::HTTP_LINE_SEPARATOR));
480         }
481         cookies = cookies->next;
482     }
483 
484     NETSTACK_LOGD("ProcessCookie() GetCookies() = %{public}s", response_.GetCookies().c_str());
485     NETSTACK_LOGD("ProcessCookie() GetHeader() = %{public}s", response_.GetHeader().c_str());
486 }
487 
ProcessResponseCode()488 bool HttpClientTask::ProcessResponseCode()
489 {
490     CURLcode code = CURLE_OK;
491     ResponseCode responseCode = ResponseCode::NONE;
492     code = curl_easy_getinfo(curlHandle_, CURLINFO_RESPONSE_CODE, &responseCode);
493     if (code != CURLE_OK) {
494         error_.SetCURLResult(code);
495         return false;
496     }
497     NETSTACK_LOGI("HttpClientTask::ProcessResponseCode() responseCode=%{public}d", responseCode);
498     response_.SetResponseCode(responseCode);
499 
500     return true;
501 }
502 
ProcessResponse(CURLMsg * msg)503 void HttpClientTask::ProcessResponse(CURLMsg *msg)
504 {
505     CURLcode code = msg->data.result;
506     NETSTACK_LOGI("HttpClientTask::ProcessResponse() taskid=%{public}d code=%{public}d", taskId_, code);
507     error_.SetCURLResult(code);
508     response_.SetResponseTime(HttpTime::GetNowTimeGMT());
509 
510     if (CURLE_ABORTED_BY_CALLBACK == code) {
511         (void)ProcessResponseCode();
512         if (onCanceled_) {
513             onCanceled_(request_, response_);
514         }
515         return;
516     }
517 
518     if (code != CURLE_OK) {
519         if (onFailed_) {
520             onFailed_(request_, response_, error_);
521         }
522         return;
523     }
524 
525     ProcessCookie(curlHandle_);
526     response_.ParseHeaders();
527 
528     if (ProcessResponseCode()) {
529         if (onSucceeded_) {
530             onSucceeded_(request_, response_);
531         }
532     } else if (onFailed_) {
533         onFailed_(request_, response_, error_);
534     }
535 }
536 
SetResponse(const HttpClientResponse & response)537 void HttpClientTask::SetResponse(const HttpClientResponse &response)
538 {
539     response_ = response;
540 }
541 } // namespace HttpClient
542 } // namespace NetStack
543 } // namespace OHOS
544