• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 #include "request_tracer.h"
24 #include "trace_events.h"
25 #include "http_client.h"
26 #include "netstack_log.h"
27 #ifdef HTTP_HANDOVER_FEATURE
28 #include "http_handover_info.h"
29 #endif
30 
31 namespace OHOS {
32 namespace NetStack {
33 namespace HttpClient {
34 class HttpGlobal {
35 public:
HttpGlobal()36     HttpGlobal()
37     {
38         if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
39             NETSTACK_LOGE("Failed to initialize 'curl'");
40         }
41     }
~HttpGlobal()42     ~HttpGlobal()
43     {
44         NETSTACK_LOGD("Deinit curl_global_cleanup()");
45         curl_global_cleanup();
46     }
47 };
48 static HttpGlobal g_httpGlobal;
49 
50 HttpSession::HttpSession() = default;
51 
~HttpSession()52 HttpSession::~HttpSession()
53 {
54     NETSTACK_LOGD("~HttpSession::enter");
55 }
56 
GetInstance()57 HttpSession &HttpSession::GetInstance()
58 {
59     static HttpSession gInstance;
60     return gInstance;
61 }
62 
CreateTask(const HttpClientRequest & request)63 std::shared_ptr<HttpClientTask> HttpSession::CreateTask(const HttpClientRequest &request)
64 {
65     std::shared_ptr<HttpClientTask> ptr = std::make_shared<HttpClientTask>(request);
66     if (ptr->GetCurlHandle() == nullptr) {
67         NETSTACK_LOGE("CreateTask A error!");
68         return nullptr;
69     }
70 
71     return ptr;
72 }
73 
CreateTask(const HttpClientRequest & request,TaskType type,const std::string & filePath)74 std::shared_ptr<HttpClientTask> HttpSession::CreateTask(const HttpClientRequest &request, TaskType type,
75                                                         const std::string &filePath)
76 {
77     std::shared_ptr<HttpClientTask> ptr = std::make_shared<HttpClientTask>(request, type, filePath);
78     if (ptr->GetCurlHandle() == nullptr) {
79         NETSTACK_LOGE("CreateTask B error!");
80         return nullptr;
81     }
82     return ptr;
83 }
84 
SetRequestInfoCallbacks(HttpOverCurl::TransferCallbacks & callbacks,const std::shared_ptr<HttpClientTask> & ptr)85 void HttpSession::SetRequestInfoCallbacks(
86     HttpOverCurl::TransferCallbacks &callbacks, const std::shared_ptr<HttpClientTask> &ptr)
87 {
88     if (nullptr == ptr) {
89         return;
90     }
91     auto startedCallback = [ptr](CURL *, void *) {
92         ptr->GetTrace().Tracepoint(TraceEvents::QUEUE);
93     };
94     auto responseCallback = [ptr](CURLMsg *curlMessage, void *) {
95         ptr->GetTrace().Tracepoint(TraceEvents::NATIVE);
96         ptr->ProcessResponse(curlMessage);
97         ptr->SetStatus(TaskStatus::IDLE);
98     };
99     callbacks.startedCallback = startedCallback;
100     callbacks.doneCallback = responseCallback;
101 
102 #ifdef HTTP_HANDOVER_FEATURE
103     auto handoverInfoCallback = [ptr](void *) {
104         HttpHandoverStackInfo httpHandoverStackInfo;
105         httpHandoverStackInfo.taskId = ptr->GetTaskId();
106         httpHandoverStackInfo.readTimeout = ptr->GetRequest().GetTimeout();
107         httpHandoverStackInfo.connectTimeout = ptr->GetRequest().GetConnectTimeout();
108         httpHandoverStackInfo.method = ptr->GetRequest().GetMethod();
109         httpHandoverStackInfo.requestUrl = ptr->GetRequest().GetURL();
110         httpHandoverStackInfo.isInStream = ptr->onDataReceive_ ? true : false;
111         httpHandoverStackInfo.isSuccess = ptr->IsSuccess();
112         return httpHandoverStackInfo;
113     };
114     static auto setHandoverInfoCallback = [ptr](HttpHandoverInfo httpHandoverInfo, void *) {
115         ptr->SetRequestHandoverInfo(httpHandoverInfo.handoverNum,
116             httpHandoverInfo.handoverReason,
117             httpHandoverInfo.flowControlTime,
118             httpHandoverInfo.readFlag);
119     };
120     callbacks.handoverInfoCallback = handoverInfoCallback;
121     callbacks.setHandoverInfoCallback = setHandoverInfoCallback;
122 #endif
123 }
124 
StartTask(const std::shared_ptr<HttpClientTask> & ptr)125 void HttpSession::StartTask(const std::shared_ptr<HttpClientTask> &ptr)
126 {
127     if (nullptr == ptr) {
128         NETSTACK_LOGE("HttpSession::StartTask  shared_ptr = nullptr! Error!");
129         return;
130     }
131 
132     static HttpOverCurl::EpollRequestHandler requestHandler;
133 
134     ptr->SetStatus(TaskStatus::RUNNING);
135 
136     HttpOverCurl::TransferCallbacks callbacks;
137     SetRequestInfoCallbacks(callbacks, ptr);
138 #ifdef HTTP_HANDOVER_FEATURE
139     requestHandler.Process(ptr->GetCurlHandle(), callbacks, &ptr->GetRequest());
140 #else
141     requestHandler.Process(ptr->GetCurlHandle(), callbacks);
142 #endif
143 }
144 
145 } // namespace HttpClient
146 } // namespace NetStack
147 } // namespace OHOS
148