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 }