• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2025 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 <dlfcn.h>
17 #include "http_handover_handler.h"
18 #include "netstack_log.h"
19 #include "request_info.h"
20 #include "request_context.h"
21 
22 namespace OHOS::NetStack::HttpOverCurl {
23 
24 constexpr const char *const METHOD_GET = "GET";
25 constexpr const char *const METHOD_HEAD = "HEAD";
26 constexpr const char *const METHOD_OPTIONS = "OPTIONS";
27 constexpr const char *const METHOD_TRACE = "TRACE";
28 constexpr const long TIMEOUT_IMMEDIATE_NS = 1000;
29 
HttpHandoverHandler()30 HttpHandoverHandler::HttpHandoverHandler()
31     : handOverEvent_(std::make_unique<ManualResetEvent>(true)),
32       handOverTimerEvent_(std::make_unique<HttpOverCurl::TimeoutTimer>())
33 {
34     initsuccess_ = Initialize();
35 }
36 
HandoverCallback(void * user)37 void HandoverCallback(void *user)
38 {
39     if (user == nullptr) {
40         NETSTACK_LOGE("handover callback user is nullptr");
41         return;
42     }
43 
44     HttpHandoverHandler* const handoverhandler = reinterpret_cast<HttpHandoverHandler*>(user);
45     handoverhandler->SetHandoverEvent();
46 }
47 
HandoverTimerCallback(void * user,long timeoutMs)48 void HandoverTimerCallback(void *user, long timeoutMs)
49 {
50     NETSTACK_LOGD("HandoverTimerCallback enter, set timeout %{public}ld ms.", timeoutMs);
51     if (user == nullptr) {
52         NETSTACK_LOGE("timer callback user is nullptr");
53         return;
54     }
55 
56     HttpHandoverHandler* const handoverHandler = reinterpret_cast<HttpHandoverHandler*>(user);
57     handoverHandler->SetHandoverTimeoutEvent(timeoutMs);
58 }
59 
CheckSocketTime(void * user,curl_socket_t fd)60 bool CheckSocketTime(void *user, curl_socket_t fd)
61 {
62     auto handover = static_cast<HttpHandoverHandler *>(user);
63     if (handover && handover->CheckSocketOpentimeLessThanEndTime(fd)) {
64         return false;
65     }
66     return true;
67 }
68 
OpenSocket(void * user,curlsocktype purpose,struct curl_sockaddr * addr)69 curl_socket_t OpenSocket(void *user, curlsocktype purpose, struct curl_sockaddr *addr)
70 {
71     curl_socket_t sockfd = socket(addr->family, addr->socktype, addr->protocol);
72     if (sockfd < 0) {
73         NETSTACK_LOGE("Failed to open socket: %{public}d, errno: %{public}d", sockfd, errno);
74         return -1;
75     }
76     auto handover = static_cast<HttpHandoverHandler *>(user);
77     if (handover) {
78         handover->SetSocketOpenTime(sockfd);
79     }
80     return sockfd;
81 }
82 
CloseSocketCallback(void * user,curl_socket_t fd)83 int CloseSocketCallback(void *user, curl_socket_t fd)
84 {
85     auto handover = static_cast<HttpHandoverHandler *>(user);
86     if (handover) {
87         handover->EraseFd(fd);
88     }
89     int ret = close(fd);
90     if (ret < 0) {
91         NETSTACK_LOGE("Failed to close socket: %{public}d, errno: %{public}d", fd, errno);
92         return ret;
93     }
94     return 0;
95 }
96 
IsIoError(CURLcode result)97 static bool IsIoError(CURLcode result)
98 {
99     if (result == CURLE_SEND_ERROR || result == CURLE_RECV_ERROR) {
100         return true;
101     }
102     return false;
103 }
104 
IsConnectError(CURLcode result)105 static bool IsConnectError(CURLcode result)
106 {
107     if (result == CURLE_COULDNT_RESOLVE_HOST || result == CURLE_COULDNT_CONNECT ||
108         result == CURLE_SSL_CONNECT_ERROR || result == CURLE_QUIC_CONNECT_ERROR) {
109         return true;
110     }
111     return false;
112 }
113 
IsNetworkErrorTypeCorrect(CURLcode result)114 bool HttpHandoverHandler::IsNetworkErrorTypeCorrect(CURLcode result)
115 {
116     if (IsIoError(result) || IsConnectError(result)) {
117         return true;
118     }
119     return false;
120 }
121 
IsInitSuccess()122 bool HttpHandoverHandler::IsInitSuccess()
123 {
124     return initsuccess_;
125 }
126 
Initialize()127 bool HttpHandoverHandler::Initialize()
128 {
129     const std::string HTTP_HANDOVER_WRAPPER_PATH = "/system/lib64/libhttp_handover.z.so";
130     netHandoverHandler_ = dlopen(HTTP_HANDOVER_WRAPPER_PATH.c_str(), RTLD_NOW);
131     if (netHandoverHandler_ == nullptr) {
132         NETSTACK_LOGE("libhttp_handover.z.so was not loaded, error: %{public}s", dlerror());
133         return false;
134     }
135     httpHandoverInit_ = (HTTP_HAND_OVER_INIT)dlsym(netHandoverHandler_, "HMS_NetworkBoost_HttpHandoverManagerInit");
136     httpHandoverUninit_ =
137         (HTTP_HAND_OVER_UNINIT)dlsym(netHandoverHandler_, "HMS_NetworkBoost_HttpHandoverManagerUninit");
138     httpHandoverQuery_ =
139         (HTTP_HAND_OVER_QUERY)dlsym(netHandoverHandler_, "HMS_NetworkBoost_HttpHandoverManagerQuery");
140     httpHandoverAddRequest_ =
141         (HTTP_HAND_OVER_ADD)dlsym(netHandoverHandler_, "HMS_NetworkBoost_HttpHandoverManagerAddRequest");
142     httpHandoverDelRequest_ =
143         (HTTP_HAND_OVER_DEL)dlsym(netHandoverHandler_, "HMS_NetworkBoost_HttpHandoverManagerDelRequest");
144     httpHandoverQueryRequest_ =
145         (HTTP_HAND_OVER_QUERY_REQUEST)dlsym(netHandoverHandler_, "HMS_NetworkBoost_HttpHandoverManagerQueryRequest");
146     httpHandoverReportTimeout_ =
147         (HTTP_HAND_OVER_REPORT_TIMEOUT)dlsym(netHandoverHandler_, "HMS_NetworkBoost_HttpHandoverManagerReportTimeout");
148     bool hasFuncNull = (httpHandoverInit_ == nullptr || httpHandoverUninit_ == nullptr ||
149         httpHandoverQuery_ == nullptr || httpHandoverAddRequest_ == nullptr || httpHandoverDelRequest_ == nullptr ||
150         httpHandoverQueryRequest_ == nullptr || httpHandoverReportTimeout_ == nullptr);
151     if (hasFuncNull) {
152         NETSTACK_LOGE("http handover wrapper symbol failed, error: %{public}s", dlerror());
153         dlclose(netHandoverHandler_);
154         netHandoverHandler_ = nullptr;
155         return false;
156     }
157     NETSTACK_LOGD("NetHandover enabled");
158     httpHandoverManager_ = httpHandoverInit_(this, HandoverCallback, HandoverTimerCallback, HTTP_STACK_NAME);
159     if (httpHandoverManager_ == nullptr) {
160         NETSTACK_LOGE("http handover manager init fail");
161         dlclose(netHandoverHandler_);
162         netHandoverHandler_ = nullptr;
163         return false;
164     }
165     return true;
166 }
167 
~HttpHandoverHandler()168 HttpHandoverHandler::~HttpHandoverHandler()
169 {
170     NETSTACK_LOGD("start httpHandoverUninit_");
171     if (httpHandoverManager_ != nullptr) {
172         httpHandoverUninit_(httpHandoverManager_);
173     }
174     if (netHandoverHandler_ != nullptr) {
175         dlclose(netHandoverHandler_);
176     }
177     httpHandoverManager_ = nullptr;
178     netHandoverHandler_ = nullptr;
179     httpHandoverInit_ = nullptr;
180     httpHandoverUninit_ = nullptr;
181     httpHandoverQuery_ = nullptr;
182     httpHandoverAddRequest_ = nullptr;
183     httpHandoverDelRequest_ = nullptr;
184     httpHandoverQueryRequest_ = nullptr;
185     httpHandoverReportTimeout_ = nullptr;
186 }
187 
RegisterForPolling(Epoller & poller) const188 void HttpHandoverHandler::RegisterForPolling(Epoller &poller) const
189 {
190     handOverEvent_->RegisterForPolling(poller);
191     handOverTimerEvent_->RegisterForPolling(poller);
192 }
193 
IsItHandoverEvent(FileDescriptor descriptor) const194 bool HttpHandoverHandler::IsItHandoverEvent(FileDescriptor descriptor) const
195 {
196     return handOverEvent_->IsItYours(descriptor);
197 }
198 
IsItHandoverTimeoutEvent(FileDescriptor descriptor) const199 bool HttpHandoverHandler::IsItHandoverTimeoutEvent(FileDescriptor descriptor) const
200 {
201     return handOverTimerEvent_->IsItYours(descriptor);
202 }
203 
SetHandoverEvent()204 void HttpHandoverHandler::SetHandoverEvent()
205 {
206     handOverEvent_->Set();
207 }
208 
SetHandoverTimeoutEvent(long timeoutMs)209 void HttpHandoverHandler::SetHandoverTimeoutEvent(long timeoutMs)
210 {
211     if (timeoutMs > 0) {
212         handOverTimerEvent_->SetTimeoutMs(timeoutMs);
213     } else if (timeoutMs == 0) {  // set a very small time means immediately trigger timeout timer
214         handOverTimerEvent_->SetTimeoutNs(TIMEOUT_IMMEDIATE_NS);
215     } else {  // timeoutMs < 0 means stop timeout timer
216         handOverTimerEvent_->Stop();
217     }
218 }
219 
HandoverQuery()220 void HttpHandoverHandler::HandoverQuery()
221 {
222     if (httpHandoverQuery_ == nullptr || httpHandoverManager_ == nullptr) {
223         NETSTACK_LOGE("nullptr param error");
224         return;
225     }
226     httpHandoverQuery_(httpHandoverManager_, &status_, &netId_);
227 }
228 
CheckSocketOpentimeLessThanEndTime(curl_socket_t fd)229 bool HttpHandoverHandler::CheckSocketOpentimeLessThanEndTime(curl_socket_t fd)
230 {
231     if (socketopentime_.count(fd) == 0) {
232         return false;
233     }
234     bool ret = socketopentime_[fd] < endTime_;
235     if (ret) {
236         NETSTACK_LOGD("Old fd:%{public}d fdtime:%{public}d endTime:%{public}d", (int)fd, socketopentime_[fd], endTime_);
237     }
238     return ret;
239 }
240 
SetSocketOpenTime(curl_socket_t fd)241 void HttpHandoverHandler::SetSocketOpenTime(curl_socket_t fd)
242 {
243     socketopentime_[fd] = endTime_;
244 }
245 
EraseFd(curl_socket_t fd)246 void HttpHandoverHandler::EraseFd(curl_socket_t fd)
247 {
248     if (socketopentime_.count(fd) == 0) {
249         return;
250     }
251     socketopentime_.erase(fd);
252 }
253 
SetCallback(RequestInfo * request)254 void HttpHandoverHandler::SetCallback(RequestInfo *request)
255 {
256     curl_easy_setopt(request->easyHandle, CURLOPT_CONNREUSEDATA, this);
257     curl_easy_setopt(request->easyHandle, CURLOPT_CONNREUSEFUNCTION, CheckSocketTime);
258 
259     curl_easy_setopt(request->easyHandle, CURLOPT_OPENSOCKETDATA, this);
260     curl_easy_setopt(request->easyHandle, CURLOPT_OPENSOCKETFUNCTION, OpenSocket);
261 
262     curl_easy_setopt(request->easyHandle, CURLOPT_CLOSESOCKETDATA, this);
263     curl_easy_setopt(request->easyHandle, CURLOPT_CLOSESOCKETFUNCTION, CloseSocketCallback);
264 }
265 
TryFlowControl(RequestInfo * requestInfo,int32_t requestType)266 bool HttpHandoverHandler::TryFlowControl(RequestInfo *requestInfo, int32_t requestType)
267 {
268     HandoverQuery();
269     if (GetStatus() == HttpHandoverHandler::FATAL) {
270         NETSTACK_LOGE("Handover status fatal, feature disable.");
271         return false;
272     }
273 
274     SetCallback(requestInfo);
275     if (GetStatus() == HttpHandoverHandler::START) {
276         handoverQueue_.insert(requestInfo);
277         std::string reason;
278         if (requestType == HandoverRequestType::INCOMING) {
279             reason = "incoming request";
280         } else if (requestType == HandoverRequestType::NETWORKERROR) {
281             reason = "network error";
282         }
283         HttpHandoverStackInfo httpHandoverStackInfo =
284             requestInfo->callbacks.handoverInfoCallback(requestInfo->opaqueData);
285         NETSTACK_LOGD("taskid=%{public}d, FlowControl reason:%{public}s", httpHandoverStackInfo.taskId, reason.c_str());
286         AddRequest(requestInfo, requestType);
287         return true;
288     }
289     AddRequest(requestInfo, HandoverRequestType::OLD);
290     return false;
291 }
292 
RetransRequest(std::map<CURL *,RequestInfo * > & ongoingRequests,CURLM * multi,RequestInfo * request)293 bool HttpHandoverHandler::RetransRequest(std::map<CURL *, RequestInfo *> &ongoingRequests,
294     CURLM *multi, RequestInfo *request)
295 {
296     auto ret = curl_multi_add_handle(multi, request->easyHandle);
297     if (ret != CURLM_OK) {
298         NETSTACK_LOGD("curl_multi_add_handle err, ret = %{public}d %{public}s", ret, curl_multi_strerror(ret));
299         return false;
300     }
301     ongoingRequests[request->easyHandle] = request;
302     return true;
303 }
304 
CheckRequestCanRetrans(RequestInfo * request,int32_t requestType,CURLcode result)305 bool HttpHandoverHandler::CheckRequestCanRetrans(RequestInfo *request, int32_t requestType, CURLcode result)
306 {
307     if (request == nullptr) {
308         return false;
309     }
310     time_t recvtime = 0;
311     time_t sendtime = 0;
312     int32_t readFlag = IsRequestRead(request->easyHandle, recvtime, sendtime);
313     if (readFlag == -1) {
314         return false;
315     }
316     HttpHandoverStackInfo httpHandoverStackInfo = request->callbacks.handoverInfoCallback(request->opaqueData);
317     bool isSafe = (httpHandoverStackInfo.method == METHOD_GET || httpHandoverStackInfo.method == METHOD_HEAD ||
318                    httpHandoverStackInfo.method == METHOD_OPTIONS || httpHandoverStackInfo.method == METHOD_TRACE);
319     bool ret = false;
320     if (IsConnectError(result) || sendtime == 0 || (isSafe && (!httpHandoverStackInfo.isInStream || readFlag == 0))) {
321         ret = true;
322     }
323     if (requestType == HandoverRequestType::INCOMING || requestType == HandoverRequestType::NETWORKERROR) {
324         return ret;
325     }
326     std::string type;
327     if (requestType == HandoverRequestType::OLD) {
328         type = "old request";
329     } else {
330         type = "undone request";
331     }
332     NETSTACK_LOGI(
333         "taskid=%{public}d,requestType:%{public}s,canRetrans:%{public}d,"
334         "method:%{public}s,isInStream:%{public}d,recvtime:%{public}d,sendtime:%{public}d,readTimeout:%{public}u,"
335         "connecttimeout:%{public}u,url:%{public}s ",
336         httpHandoverStackInfo.taskId, type.c_str(), (int)ret, httpHandoverStackInfo.method.c_str(),
337         httpHandoverStackInfo.isInStream, (int)recvtime, (int)sendtime, httpHandoverStackInfo.readTimeout,
338         httpHandoverStackInfo.connectTimeout, httpHandoverStackInfo.requestUrl.c_str());
339     return ret;
340 }
341 
UndoneRequestHandle(std::map<CURL *,RequestInfo * > & ongoingRequests,CURLM * multi)342 void HttpHandoverHandler::UndoneRequestHandle(std::map<CURL *, RequestInfo *> &ongoingRequests, CURLM *multi)
343 {
344     for (auto it = ongoingRequests.begin(); it != ongoingRequests.end();) {
345         auto handle = it->first;
346         auto requestInfo = it->second;
347         if (CheckRequestCanRetrans(requestInfo, HandoverRequestType::UNDONE, CURLE_OK)) {
348             curl_multi_remove_handle(multi, handle);
349             if (RetransRequest(ongoingRequests, multi, requestInfo)) {
350                 ++retrans_;
351                 AddRequest(requestInfo, HandoverRequestType::UNDONE);
352                 ++it;
353                 continue;
354             }
355             if (requestInfo != nullptr && requestInfo->callbacks.doneCallback) {
356                 CURLMsg message;
357                 message.msg = CURLMSG_DONE;
358                 message.data.result = CURLE_SEND_ERROR;
359                 requestInfo->callbacks.doneCallback(&message, requestInfo->opaqueData);
360             }
361             it = ongoingRequests.erase(it);
362         } else {
363             ++it;
364         }
365     }
366 }
367 
HandoverRequestCallback(std::map<CURL *,RequestInfo * > & ongoingRequests,CURLM * multi)368 void HttpHandoverHandler::HandoverRequestCallback(std::map<CURL *, RequestInfo *> &ongoingRequests, CURLM *multi)
369 {
370     handOverEvent_->Reset();
371     HandoverQuery();
372     NETSTACK_LOGD("Enter HandoverRequestCallback status %{public}d", GetStatus());
373     if (GetStatus() == HttpHandoverHandler::START) {
374         NETSTACK_LOGD("start ongoingRequests:%{public}d", (int)ongoingRequests.size());
375         for (auto &request : ongoingRequests) {
376             if (requestEndtime_.count(request.second) == 0) {
377                 requestEndtime_[request.second] = endTime_;
378             }
379             (void)CheckRequestCanRetrans(request.second, HandoverRequestType::OLD, CURLE_OK);
380         }
381     } else if (GetStatus() == HttpHandoverHandler::END || GetStatus() == HttpHandoverHandler::TIMEOUT) {
382         (GetStatus() == HttpHandoverHandler::END) ? ++endTime_ : ++timeoutTime_;
383         NETSTACK_LOGD("endTime:%{public}d, timeoutTime: %{public}d, ongoingRequests:%{public}d, retrans count before "
384                       "end:%{public}d", endTime_, timeoutTime_, (int)ongoingRequests.size(), retrans_);
385         UndoneRequestHandle(ongoingRequests, multi);
386 
387         NETSTACK_LOGD("handoverQueue_:%{public}d, retrans total count:%{public}d",
388             (int)handoverQueue_.size(), retrans_);
389         for (auto &request : handoverQueue_) {
390             (void)RetransRequest(ongoingRequests, multi, request);
391         }
392         handoverQueue_.clear();
393         retrans_ = 0;
394     } else if (GetStatus() == HttpHandoverHandler::FATAL) {
395         NETSTACK_LOGE("Handover status is FATAL, feature disable.");
396     }
397     return;
398 }
399 
HandoverTimeoutCallback()400 void HttpHandoverHandler::HandoverTimeoutCallback()
401 {
402     handOverTimerEvent_->ResetEvent();
403     handOverTimerEvent_->Stop();
404     HandoverQuery();
405     if (GetStatus() == HttpHandoverHandler::END) {
406         return;
407     }
408     if (httpHandoverManager_ == nullptr) {
409         NETSTACK_LOGE("httpHandoverManager_ nullptr error");
410         return;
411     }
412     httpHandoverReportTimeout_(httpHandoverManager_);
413 }
414 
IsRequestRead(CURL * easyHandle)415 int32_t HttpHandoverHandler::IsRequestRead(CURL *easyHandle)
416 {
417     time_t recvtime = 0;
418     time_t sendtime = 0;
419     return IsRequestRead(easyHandle, recvtime, sendtime);
420 }
421 
IsRequestRead(CURL * easyHandle,time_t & recvtime,time_t & sendtime)422 int32_t HttpHandoverHandler::IsRequestRead(CURL *easyHandle, time_t &recvtime, time_t &sendtime)
423 {
424     CURLcode result = curl_easy_getinfo(easyHandle, CURLINFO_STARTTRANSFER_TIME_T, &recvtime);
425     if (result != CURLE_OK) {
426         NETSTACK_LOGD("get recv time failed:%{public}s", curl_easy_strerror(result));
427         return -1;
428     }
429     result = curl_easy_getinfo(easyHandle, CURLINFO_PRETRANSFER_TIME_T, &sendtime);
430     if (result != CURLE_OK) {
431         NETSTACK_LOGD("get send time failed:%{public}s", curl_easy_strerror(result));
432         return -1;
433     }
434     return (recvtime == 0 || sendtime == recvtime) ? 0 : 1;
435 }
436 
ProcessRequestErr(std::map<CURL *,RequestInfo * > & ongoingRequests,CURLM * multi,RequestInfo * requestInfo,CURLMsg * msg)437 bool HttpHandoverHandler::ProcessRequestErr(std::map<CURL *, RequestInfo *> &ongoingRequests,
438     CURLM *multi, RequestInfo *requestInfo, CURLMsg *msg)
439 {
440     if (ProcessRequestNetError(ongoingRequests, multi, requestInfo, msg)) {
441         return true;
442     }
443     SetHandoverInfo(requestInfo);
444     return false;
445 }
446 
SetHandoverInfo(RequestInfo * requestInfo)447 void HttpHandoverHandler::SetHandoverInfo(RequestInfo *requestInfo)
448 {
449     if (requestInfo != nullptr) {
450         int32_t handoverReason = 0;
451         double flowControlTime = 0;
452         int32_t readFlag = 0;
453         int32_t handOverNum =
454             QueryRequest(requestInfo->opaqueData, handoverReason, flowControlTime, readFlag);
455         HttpHandoverInfo httpHandoverInfo;
456         httpHandoverInfo.handoverNum = handOverNum;
457         httpHandoverInfo.handoverReason = handoverReason;
458         httpHandoverInfo.flowControlTime = flowControlTime;
459         httpHandoverInfo.readFlag = readFlag;
460         requestInfo->callbacks.setHandoverInfoCallback(httpHandoverInfo, requestInfo->opaqueData);
461         DelRequest(requestInfo);
462     }
463 }
464 
ProcessRequestNetError(std::map<CURL *,RequestInfo * > & ongoingRequests,CURLM * multi,RequestInfo * requestInfo,CURLMsg * msg)465 bool HttpHandoverHandler::ProcessRequestNetError(std::map<CURL *, RequestInfo *> &ongoingRequests, CURLM *multi,
466     RequestInfo *requestInfo, CURLMsg *msg)
467 {
468     if (!requestInfo || requestEndtime_.count(requestInfo) == 0) {
469         return false;
470     }
471     int endTime = requestEndtime_[requestInfo];
472     requestEndtime_.erase(requestInfo);
473     if (!msg || !IsNetworkErrorTypeCorrect(msg->data.result)) {
474         return false;
475     }
476     if (!CheckRequestCanRetrans(requestInfo, HandoverRequestType::NETWORKERROR, msg->data.result)) {
477         return false;
478     }
479     if (TryFlowControl(requestInfo, HandoverRequestType::NETWORKERROR)) {
480         ++retrans_;
481         return true;
482     }
483     if (endTime == endTime_ - 1) {
484         NETSTACK_LOGD("networkerror after end status");
485         AddRequest(requestInfo, HandoverRequestType::NETWORKERROR);
486         return RetransRequest(ongoingRequests, multi, requestInfo);
487     }
488     return false;
489 }
490 
AddRequest(RequestInfo * requestInfo,int32_t type)491 void HttpHandoverHandler::AddRequest(RequestInfo *requestInfo, int32_t type)
492 {
493     if (httpHandoverManager_ == nullptr) {
494         NETSTACK_LOGE("httpHandoverManager_ nullptr error");
495         return;
496     }
497     httpHandoverAddRequest_(httpHandoverManager_, requestInfo->opaqueData, type,
498         IsRequestRead(requestInfo->easyHandle));
499 }
500 
DelRequest(RequestInfo * requestInfo)501 void HttpHandoverHandler::DelRequest(RequestInfo *requestInfo)
502 {
503     if (httpHandoverManager_ == nullptr) {
504         NETSTACK_LOGE("httpHandoverManager_ nullptr error");
505         return;
506     }
507     HttpHandoverStackInfo httpHandoverStackInfo = requestInfo->callbacks.handoverInfoCallback(requestInfo->opaqueData);
508     httpHandoverDelRequest_(httpHandoverManager_, requestInfo->opaqueData, httpHandoverStackInfo.isSuccess);
509 }
510 
QueryRequest(void * userp,int32_t & handOverReason,double & flowControlTime,int32_t & readFlag)511 int32_t HttpHandoverHandler::QueryRequest(void *userp, int32_t &handOverReason, double &flowControlTime,
512     int32_t &readFlag)
513 {
514     if (httpHandoverManager_ == nullptr) {
515         NETSTACK_LOGE("httpHandoverManager_ nullptr error");
516         return -1;
517     }
518     return httpHandoverQueryRequest_(httpHandoverManager_, userp, &handOverReason, &flowControlTime, &readFlag);
519 }
520 
GetStatus()521 int32_t HttpHandoverHandler::GetStatus()
522 {
523     return status_;
524 }
525 
SetStatus(int32_t status)526 void HttpHandoverHandler::SetStatus(int32_t status)
527 {
528     status_ = status;
529 }
530 
GetNetId()531 int32_t HttpHandoverHandler::GetNetId()
532 {
533     return netId_;
534 }
535 
SetNetId(int32_t netId)536 void HttpHandoverHandler::SetNetId(int32_t netId)
537 {
538     netId_ = netId;
539 }
540 }