1 /*
2  * Copyright (c) 2023-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 <atomic>
17 #include <curl/curl.h>
18 #include <functional>
19 #include <iostream>
20 #include <sstream>
21 
22 #include "epoll_request_handler.h"
23 #if !defined(_WIN32) && !defined(__APPLE__)
24 #include "hitrace_meter.h"
25 #endif
26 #include "http_client.h"
27 #include "netstack_log.h"
28 
29 namespace OHOS {
30 namespace NetStack {
31 namespace HttpClient {
32 #if !defined(_WIN32) && !defined(__APPLE__)
33 static constexpr const char *HTTP_REQ_TRACE_NAME = "HttpRequestInner";
34 #endif
35 
36 class HttpGlobal {
37 public:
HttpGlobal()38     HttpGlobal()
39     {
40         if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
41             NETSTACK_LOGE("Failed to initialize 'curl'");
42         }
43     }
~HttpGlobal()44     ~HttpGlobal()
45     {
46         NETSTACK_LOGD("Deinit curl_global_cleanup()");
47         curl_global_cleanup();
48     }
49 };
50 static HttpGlobal g_httpGlobal;
51 
52 HttpSession::HttpSession() = default;
53 
~HttpSession()54 HttpSession::~HttpSession()
55 {
56     NETSTACK_LOGD("~HttpSession::enter");
57 }
58 
GetInstance()59 HttpSession &HttpSession::GetInstance()
60 {
61     static HttpSession gInstance;
62     return gInstance;
63 }
64 
CreateTask(const HttpClientRequest & request)65 std::shared_ptr<HttpClientTask> HttpSession::CreateTask(const HttpClientRequest &request)
66 {
67     std::shared_ptr<HttpClientTask> ptr = std::make_shared<HttpClientTask>(request);
68     if (ptr->GetCurlHandle() == nullptr) {
69         NETSTACK_LOGE("CreateTask A error!");
70         return nullptr;
71     }
72 
73     return ptr;
74 }
75 
CreateTask(const HttpClientRequest & request,TaskType type,const std::string & filePath)76 std::shared_ptr<HttpClientTask> HttpSession::CreateTask(const HttpClientRequest &request, TaskType type,
77                                                         const std::string &filePath)
78 {
79     std::shared_ptr<HttpClientTask> ptr = std::make_shared<HttpClientTask>(request, type, filePath);
80     if (ptr->GetCurlHandle() == nullptr) {
81         NETSTACK_LOGE("CreateTask B error!");
82         return nullptr;
83     }
84     return ptr;
85 }
86 
StartTask(const std::shared_ptr<HttpClientTask> & ptr)87 void HttpSession::StartTask(const std::shared_ptr<HttpClientTask> &ptr)
88 {
89     if (nullptr == ptr) {
90         NETSTACK_LOGE("HttpSession::StartTask  shared_ptr = nullptr! Error!");
91         return;
92     }
93 
94     static HttpOverCurl::EpollRequestHandler requestHandler;
95 
96     ptr->SetStatus(TaskStatus::RUNNING);
97 
98     auto startedCallback = [ptr](CURL *, void *) {};
99 #if !defined(_WIN32) && !defined(__APPLE__)
100     std::stringstream name;
101     name << HTTP_REQ_TRACE_NAME << "_" << std::this_thread::get_id();
102     std::string traceName = name.str();
103     StartAsyncTrace(HITRACE_TAG_NET, traceName, ptr->GetTaskId());
104 
105     auto responseCallback = [ptr, traceName](CURLMsg *curlMessage, void *) {
106         FinishAsyncTrace(HITRACE_TAG_NET, traceName, ptr->GetTaskId());
107         ptr->ProcessResponse(curlMessage);
108         ptr->SetStatus(TaskStatus::IDLE);
109     };
110 #else
111     auto responseCallback = [ptr](CURLMsg *curlMessage, void *) {
112         ptr->ProcessResponse(curlMessage);
113         ptr->SetStatus(TaskStatus::IDLE);
114     };
115 #endif
116     requestHandler.Process(ptr->GetCurlHandle(), startedCallback, responseCallback);
117 }
118 
119 } // namespace HttpClient
120 } // namespace NetStack
121 } // namespace OHOS
122