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 "net_http_probe.h"
17
18 #include <cerrno>
19 #include <memory>
20 #include <numeric>
21 #include <unistd.h>
22
23 #include "fwmark_client.h"
24 #include "netsys_controller.h"
25 #include "net_manager_constants.h"
26 #include "net_mgr_log_wrapper.h"
27
28 #define NETPROBE_CURL_EASY_SET_OPTION(handle, opt, data) \
29 do { \
30 CURLcode result = curl_easy_setopt(handle, opt, data); \
31 if (result != CURLE_OK) { \
32 const char *err = curl_easy_strerror(result); \
33 NETMGR_LOG_E("Failed to set curl option: %{public}s, %{public}s %{public}d", #opt, err, result); \
34 return false; \
35 } \
36 } while (0)
37
38 namespace OHOS {
39 namespace NetManagerStandard {
40 namespace {
41 constexpr int PERFORM_POLL_INTERVAL_MS = 50;
42 constexpr int CURL_CONNECT_TIME_OUT_MS = 5000;
43 constexpr int CURL_OPERATE_TIME_OUT_MS = 5000;
44 constexpr int32_t DOMAIN_IP_ADDR_LEN_MAX = 128;
45 constexpr int32_t DEFAULT_HTTP_PORT = 80;
46 constexpr int32_t DEFAULT_HTTPS_PORT = 443;
47 constexpr const char *ADDR_SEPARATOR = ",";
48 constexpr const char *SYMBOL_COLON = ":";
49 } // namespace
50
51 std::mutex NetHttpProbe::initCurlMutex_;
52 int32_t NetHttpProbe::useCurlCount_ = 0;
CurlGlobalInit()53 bool NetHttpProbe::CurlGlobalInit()
54 {
55 NETMGR_LOG_D("curl_global_init() in");
56 std::lock_guard<std::mutex> lock(initCurlMutex_);
57 if (useCurlCount_ == 0) {
58 NETMGR_LOG_I("Call curl_global_init()");
59 if (curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) {
60 NETMGR_LOG_E("curl_global_init() failed");
61 return false;
62 }
63 }
64 useCurlCount_++;
65 NETMGR_LOG_D("curl_global_init() count:[%{public}d]", useCurlCount_);
66 return true;
67 }
68
CurlGlobalCleanup()69 void NetHttpProbe::CurlGlobalCleanup()
70 {
71 NETMGR_LOG_D("CurlGlobalCleanup() in");
72 std::lock_guard<std::mutex> lock(initCurlMutex_);
73 useCurlCount_ = useCurlCount_ > 0 ? (useCurlCount_ - 1) : 0;
74 NETMGR_LOG_D("Curl global used count remain:[%{public}d]", useCurlCount_);
75 if (useCurlCount_ == 0) {
76 NETMGR_LOG_I("Call curl_global_cleanup()");
77 curl_global_cleanup();
78 }
79 }
80
NetHttpProbe(uint32_t netId,NetBearType bearType,const NetLinkInfo & netLinkInfo)81 NetHttpProbe::NetHttpProbe(uint32_t netId, NetBearType bearType, const NetLinkInfo &netLinkInfo)
82 : netId_(netId), netBearType_(bearType), netLinkInfo_(netLinkInfo)
83 {
84 isCurlInit_ = NetHttpProbe::CurlGlobalInit();
85 }
86
~NetHttpProbe()87 NetHttpProbe::~NetHttpProbe()
88 {
89 NetHttpProbe::CurlGlobalCleanup();
90 isCurlInit_ = false;
91 }
92
SendProbe(ProbeType probeType,const std::string & httpUrl,const std::string & httpsUrl)93 int32_t NetHttpProbe::SendProbe(ProbeType probeType, const std::string &httpUrl, const std::string &httpsUrl)
94 {
95 NETMGR_LOG_I("Send net:[%{public}d] %{public}s probe in", netId_,
96 ((probeType == ProbeType::PROBE_HTTP_HTTPS)
97 ? "HTTP&HTTPS"
98 : ((probeType == ProbeType::PROBE_HTTPS) ? "https" : "http")));
99 ClearProbeResult();
100 if (!CheckCurlGlobalInitState()) {
101 return NETMANAGER_ERR_INTERNAL;
102 }
103
104 if (!InitHttpCurl(probeType)) {
105 CleanHttpCurl();
106 return NETMANAGER_ERR_INTERNAL;
107 }
108
109 if (!SetCurlOptions(probeType, httpUrl, httpsUrl)) {
110 NETMGR_LOG_E("Set http/https probe options failed");
111 CleanHttpCurl();
112 return NETMANAGER_ERR_INTERNAL;
113 }
114
115 SendHttpProbeRequest();
116 RecvHttpProbeResponse();
117 CleanHttpCurl();
118 return NETMANAGER_SUCCESS;
119 }
120
GetHttpProbeResult() const121 NetHttpProbeResult NetHttpProbe::GetHttpProbeResult() const
122 {
123 return httpProbeResult_;
124 }
125
GetHttpsProbeResult() const126 NetHttpProbeResult NetHttpProbe::GetHttpsProbeResult() const
127 {
128 return httpsProbeResult_;
129 }
130
UpdateNetLinkInfo(const NetLinkInfo & netLinkInfo)131 void NetHttpProbe::UpdateNetLinkInfo(const NetLinkInfo &netLinkInfo)
132 {
133 netLinkInfo_ = netLinkInfo;
134 }
135
UpdateGlobalHttpProxy(const HttpProxy & httpProxy)136 void NetHttpProbe::UpdateGlobalHttpProxy(const HttpProxy &httpProxy)
137 {
138 std::lock_guard<std::mutex> locker(proxyMtx_);
139 globalHttpProxy_ = httpProxy;
140 }
141
CheckCurlGlobalInitState()142 bool NetHttpProbe::CheckCurlGlobalInitState()
143 {
144 if (!isCurlInit_) {
145 NETMGR_LOG_E("Curl global does not initialized, attempting to reinitialize.");
146 isCurlInit_ = NetHttpProbe::CurlGlobalInit();
147 }
148 return isCurlInit_;
149 }
150
CleanHttpCurl()151 void NetHttpProbe::CleanHttpCurl()
152 {
153 if (httpCurl_) {
154 if (curlMulti_) {
155 curl_multi_remove_handle(curlMulti_, httpCurl_);
156 }
157 curl_easy_cleanup(httpCurl_);
158 httpCurl_ = nullptr;
159 }
160
161 if (httpsCurl_) {
162 if (curlMulti_) {
163 curl_multi_remove_handle(curlMulti_, httpsCurl_);
164 }
165 curl_easy_cleanup(httpsCurl_);
166 httpsCurl_ = nullptr;
167 }
168
169 if (httpResolveList_) {
170 curl_slist_free_all(httpResolveList_);
171 httpResolveList_ = nullptr;
172 }
173
174 if (httpsResolveList_) {
175 curl_slist_free_all(httpsResolveList_);
176 httpsResolveList_ = nullptr;
177 }
178
179 if (curlMulti_) {
180 curl_multi_cleanup(curlMulti_);
181 curlMulti_ = nullptr;
182 }
183 }
184
ClearProbeResult()185 void NetHttpProbe::ClearProbeResult()
186 {
187 httpProbeResult_ = {};
188 httpsProbeResult_ = {};
189 }
190
ExtractDomainFormUrl(const std::string & url)191 std::string NetHttpProbe::ExtractDomainFormUrl(const std::string &url)
192 {
193 if (url.empty()) {
194 return std::string();
195 }
196
197 size_t doubleSlashPos = url.find("//");
198 if (doubleSlashPos == std::string::npos) {
199 return url;
200 }
201
202 std::string domain;
203 size_t domainStartPos = doubleSlashPos + 2;
204 size_t domainEndPos = url.find('/', domainStartPos);
205 if (domainEndPos != std::string::npos) {
206 domain = url.substr(domainStartPos, domainEndPos - domainStartPos);
207 } else {
208 domain = url.substr(domainStartPos);
209 }
210 return domain;
211 }
212
GetAddrInfo(const std::string & domain)213 std::string NetHttpProbe::GetAddrInfo(const std::string &domain)
214 {
215 if (domain.empty()) {
216 NETMGR_LOG_E("domain is empty");
217 return std::string();
218 }
219
220 std::vector<AddrInfo> result;
221 AddrInfo hints = {};
222 std::string serverName;
223 if (NetsysController::GetInstance().GetAddrInfo(domain, serverName, hints, netId_, result) < 0) {
224 NETMGR_LOG_E("Get net[%{public}d] address info failed,errno[%{public}d]:%{public}s", netId_, errno,
225 strerror(errno));
226 return std::string();
227 }
228 if (result.empty()) {
229 NETMGR_LOG_E("Get net[%{public}d] address info return nullptr result", netId_);
230 return std::string();
231 }
232
233 std::string ipAddress;
234 char ip[DOMAIN_IP_ADDR_LEN_MAX] = {0};
235 for (auto &node : result) {
236 errno_t err = memset_s(&ip, sizeof(ip), 0, sizeof(ip));
237 if (err != EOK) {
238 NETMGR_LOG_E("memset_s failed,err:%{public}d", err);
239 return std::string();
240 }
241
242 if (node.aiFamily == AF_INET) {
243 if (!inet_ntop(AF_INET, &node.aiAddr.sin.sin_addr, ip, sizeof(ip))) {
244 continue;
245 }
246 } else if (node.aiFamily == AF_INET6) {
247 if (!inet_ntop(AF_INET6, &node.aiAddr.sin6.sin6_addr, ip, sizeof(ip))) {
248 continue;
249 }
250 }
251 if (ipAddress.find(ip) != std::string::npos) {
252 continue;
253 }
254 ipAddress = ipAddress.empty() ? (ipAddress + ip) : (ipAddress + ADDR_SEPARATOR + ip);
255 }
256 return ipAddress;
257 }
258
HasProbeType(ProbeType inputProbeType,ProbeType hasProbeType)259 bool NetHttpProbe::HasProbeType(ProbeType inputProbeType, ProbeType hasProbeType)
260 {
261 return (inputProbeType & hasProbeType) != 0;
262 }
263
InitHttpCurl(ProbeType probeType)264 bool NetHttpProbe::InitHttpCurl(ProbeType probeType)
265 {
266 curlMulti_ = curl_multi_init();
267 if (curlMulti_ == nullptr) {
268 NETMGR_LOG_E("curl_multi_init() failed.");
269 return false;
270 }
271
272 if (HasProbeType(probeType, ProbeType::PROBE_HTTP)) {
273 httpCurl_ = curl_easy_init();
274 if (!httpCurl_) {
275 NETMGR_LOG_E("httpCurl_ init failed");
276 return false;
277 }
278 }
279
280 if (HasProbeType(probeType, ProbeType::PROBE_HTTPS)) {
281 httpsCurl_ = curl_easy_init();
282 if (!httpsCurl_) {
283 NETMGR_LOG_E("httpsCurl_ init failed");
284 return false;
285 }
286 }
287 return true;
288 }
289
SetCurlOptions(ProbeType probeType,const std::string & httpUrl,const std::string & httpsUrl)290 bool NetHttpProbe::SetCurlOptions(ProbeType probeType, const std::string &httpUrl, const std::string &httpsUrl)
291 {
292 bool useProxy = false;
293 if (!SetProxyOption(probeType, useProxy)) {
294 NETMGR_LOG_E("Set curl proxy option failed.");
295 return false;
296 }
297 if (!SendDnsProbe(probeType, httpUrl, httpsUrl, useProxy)) {
298 NETMGR_LOG_E("Set resolve option failed.");
299 return false;
300 }
301
302 if (HasProbeType(probeType, ProbeType::PROBE_HTTP)) {
303 if (!SetHttpOptions(ProbeType::PROBE_HTTP, httpCurl_, httpUrl)) {
304 return false;
305 }
306 }
307
308 if (HasProbeType(probeType, ProbeType::PROBE_HTTPS)) {
309 if (!SetHttpOptions(ProbeType::PROBE_HTTPS, httpsCurl_, httpsUrl)) {
310 return false;
311 }
312 }
313
314 return true;
315 }
316
SetHttpOptions(ProbeType probeType,CURL * curl,const std::string & url)317 bool NetHttpProbe::SetHttpOptions(ProbeType probeType, CURL *curl, const std::string &url)
318 {
319 if (!curl) {
320 NETMGR_LOG_E("curl is nullptr");
321 return false;
322 }
323 if (url.empty()) {
324 NETMGR_LOG_E("Probe url is empty");
325 return false;
326 }
327
328 NETPROBE_CURL_EASY_SET_OPTION(curl, CURLOPT_VERBOSE, 0L);
329 NETPROBE_CURL_EASY_SET_OPTION(curl, CURLOPT_HEADER, 0L);
330 NETPROBE_CURL_EASY_SET_OPTION(curl, CURLOPT_URL, url.c_str());
331 if (probeType == ProbeType::PROBE_HTTPS) {
332 /* the connection succeeds regardless of the peer certificate validation */
333 NETPROBE_CURL_EASY_SET_OPTION(curl, CURLOPT_SSL_VERIFYPEER, 0L);
334 /* the connection succeeds regardless of the names in the certificate. */
335 NETPROBE_CURL_EASY_SET_OPTION(curl, CURLOPT_SSL_VERIFYHOST, 0L);
336 }
337 NETPROBE_CURL_EASY_SET_OPTION(curl, CURLOPT_NOSIGNAL, 1L);
338 /* connection timeout time */
339 NETPROBE_CURL_EASY_SET_OPTION(curl, CURLOPT_CONNECTTIMEOUT_MS, CURL_CONNECT_TIME_OUT_MS);
340 /* transfer operation timeout time */
341 NETPROBE_CURL_EASY_SET_OPTION(curl, CURLOPT_TIMEOUT_MS, CURL_OPERATE_TIME_OUT_MS);
342 NETPROBE_CURL_EASY_SET_OPTION(curl, CURLOPT_INTERFACE, netLinkInfo_.ifaceName_.c_str());
343
344 CURLMcode code = curl_multi_add_handle(curlMulti_, curl);
345 if (code != CURLM_OK) {
346 NETMGR_LOG_E("curl multi add handle failed, code:[%{public}d]", code);
347 return false;
348 }
349 return true;
350 }
351
SetProxyOption(ProbeType probeType,bool & useHttpProxy)352 bool NetHttpProbe::SetProxyOption(ProbeType probeType, bool &useHttpProxy)
353 {
354 useHttpProxy = false;
355 /* WIFI or Ethernet require the use of proxy for network detection */
356 if (netBearType_ != BEARER_WIFI && netBearType_ != BEARER_ETHERNET) {
357 NETMGR_LOG_W("Net:[%{public}d] bear type:[%{public}d], no proxy probe required.", netId_, probeType);
358 return true;
359 }
360
361 std::string proxyHost;
362 int32_t proxyPort = 0;
363 /* Prioritize the use of global HTTP proxy, if there is no global proxy, use network http proxy */
364 if (!LoadProxy(proxyHost, proxyPort)) {
365 NETMGR_LOG_E("global http proxy or network proxy is empty.");
366 return true;
367 }
368
369 std::string proxyDomain = ExtractDomainFormUrl(proxyHost);
370 if (proxyDomain.empty()) {
371 NETMGR_LOG_E("Extract proxy domain from host return empty.");
372 return true;
373 }
374 std::string proxyIpAddress = GetAddrInfo(proxyDomain);
375
376 NETMGR_LOG_I("Using proxy for http probe on netId:[%{public}d]", netId_);
377 bool ret = false;
378 if (HasProbeType(probeType, ProbeType::PROBE_HTTP)) {
379 if (httpCurl_ == nullptr) {
380 NETMGR_LOG_E("httpCurl_ is nullptr");
381 return false;
382 }
383 NETPROBE_CURL_EASY_SET_OPTION(httpCurl_, CURLOPT_PROXY, proxyHost.c_str());
384 NETPROBE_CURL_EASY_SET_OPTION(httpCurl_, CURLOPT_PROXYPORT, proxyPort);
385 NETPROBE_CURL_EASY_SET_OPTION(httpCurl_, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
386 NETPROBE_CURL_EASY_SET_OPTION(httpCurl_, CURLOPT_HTTPPROXYTUNNEL, 1L);
387 ret = SetResolveOption(ProbeType::PROBE_HTTP, proxyDomain, proxyIpAddress, proxyPort);
388 }
389
390 if (HasProbeType(probeType, ProbeType::PROBE_HTTPS)) {
391 if (httpsCurl_ == nullptr) {
392 NETMGR_LOG_E("httpsCurl_ is nullptr");
393 return false;
394 }
395 NETPROBE_CURL_EASY_SET_OPTION(httpsCurl_, CURLOPT_PROXY, proxyHost.c_str());
396 NETPROBE_CURL_EASY_SET_OPTION(httpsCurl_, CURLOPT_PROXYPORT, proxyPort);
397 NETPROBE_CURL_EASY_SET_OPTION(httpsCurl_, CURLOPT_PROXYTYPE, CURLPROXY_HTTP);
398 NETPROBE_CURL_EASY_SET_OPTION(httpsCurl_, CURLOPT_HTTPPROXYTUNNEL, 1L);
399 ret &= SetResolveOption(ProbeType::PROBE_HTTPS, proxyDomain, proxyIpAddress, proxyPort);
400 }
401 useHttpProxy = true;
402 return ret;
403 }
404
SetResolveOption(ProbeType probeType,const std::string & domain,const std::string & ipAddress,int32_t port)405 bool NetHttpProbe::SetResolveOption(ProbeType probeType, const std::string &domain, const std::string &ipAddress,
406 int32_t port)
407 {
408 if (domain.empty()) {
409 NETMGR_LOG_E("domain is empty");
410 return false;
411 }
412
413 if (ipAddress.empty()) {
414 NETMGR_LOG_E("ipAddress is empty");
415 return false;
416 }
417
418 std::string resolve = domain + SYMBOL_COLON + std::to_string(port) + SYMBOL_COLON + ipAddress;
419 if (probeType == ProbeType::PROBE_HTTP) {
420 httpResolveList_ = curl_slist_append(httpResolveList_, resolve.c_str());
421 NETPROBE_CURL_EASY_SET_OPTION(httpCurl_, CURLOPT_RESOLVE, httpResolveList_);
422 }
423
424 if (probeType == ProbeType::PROBE_HTTPS) {
425 httpsResolveList_ = curl_slist_append(httpsResolveList_, resolve.c_str());
426 NETPROBE_CURL_EASY_SET_OPTION(httpsCurl_, CURLOPT_RESOLVE, httpsResolveList_);
427 }
428 return true;
429 }
430
SendDnsProbe(ProbeType probeType,const std::string & httpUrl,const std::string & httpsUrl,const bool useProxy)431 bool NetHttpProbe::SendDnsProbe(ProbeType probeType, const std::string &httpUrl, const std::string &httpsUrl,
432 const bool useProxy)
433 {
434 if (useProxy) {
435 NETMGR_LOG_W("Net[%{public}d] probe use http proxy,no DNS detection required.", netId_);
436 return true;
437 }
438
439 std::string httpDomain;
440 std::string httpsDomain;
441 if (HasProbeType(probeType, ProbeType::PROBE_HTTP)) {
442 httpDomain = ExtractDomainFormUrl(httpUrl);
443 if (httpDomain.empty()) {
444 NETMGR_LOG_E("The http domain extracted from [%{public}s] is empty", httpUrl.c_str());
445 return false;
446 }
447 }
448
449 if (HasProbeType(probeType, ProbeType::PROBE_HTTPS)) {
450 httpsDomain = ExtractDomainFormUrl(httpsUrl);
451 if (httpsDomain.empty()) {
452 NETMGR_LOG_E("The https domain extracted from [%{public}s] is empty", httpsUrl.c_str());
453 return false;
454 }
455 }
456
457 std::string ipAddress;
458 if (httpDomain == httpsDomain) {
459 NETMGR_LOG_I("Get net[%{public}d] ip addr for HTTP&HTTPS probe url ", netId_);
460 ipAddress = GetAddrInfo(httpDomain);
461 return SetResolveOption(ProbeType::PROBE_HTTP, httpDomain, ipAddress, DEFAULT_HTTP_PORT) &&
462 SetResolveOption(ProbeType::PROBE_HTTPS, httpsDomain, ipAddress, DEFAULT_HTTPS_PORT);
463 }
464
465 if (HasProbeType(probeType, ProbeType::PROBE_HTTP)) {
466 NETMGR_LOG_I("Get net[%{public}d] ip addr for HTTP probe url ", netId_);
467 ipAddress = GetAddrInfo(httpDomain);
468 return SetResolveOption(ProbeType::PROBE_HTTP, httpDomain, ipAddress, DEFAULT_HTTP_PORT);
469 }
470
471 if (HasProbeType(probeType, ProbeType::PROBE_HTTPS)) {
472 NETMGR_LOG_I("Get net[%{public}d] ip addr for HTTPS probe url ", netId_);
473 ipAddress = GetAddrInfo(httpsDomain);
474 return SetResolveOption(ProbeType::PROBE_HTTPS, httpsDomain, ipAddress, DEFAULT_HTTPS_PORT);
475 }
476 return false;
477 }
478
SendHttpProbeRequest()479 void NetHttpProbe::SendHttpProbeRequest()
480 {
481 if (!curlMulti_) {
482 NETMGR_LOG_E("curlMulti_ is nullptr");
483 return;
484 }
485
486 int running = 0;
487 do {
488 CURLMcode result = curl_multi_perform(curlMulti_, &running);
489 if ((result == CURLM_OK) && running) {
490 result = curl_multi_poll(curlMulti_, nullptr, 0, PERFORM_POLL_INTERVAL_MS, nullptr);
491 }
492 if (result != CURLM_OK) {
493 NETMGR_LOG_E("curl_multi_perform() error, error code:[%{public}d]", result);
494 break;
495 }
496 } while (running);
497 }
498
RecvHttpProbeResponse()499 void NetHttpProbe::RecvHttpProbeResponse()
500 {
501 if (!curlMulti_) {
502 NETMGR_LOG_E("curlMulti_ is nullptr");
503 return;
504 }
505 CURLMsg *curlMsg = nullptr;
506 int32_t msgQueue = 0;
507 while ((curlMsg = curl_multi_info_read(curlMulti_, &msgQueue)) != nullptr) {
508 if (curlMsg->msg != CURLMSG_DONE) {
509 NETMGR_LOG_W("curl multi read not done, msg:[%{public}d]", curlMsg->msg);
510 continue;
511 }
512
513 if (!curlMsg->easy_handle) {
514 NETMGR_LOG_E("Read nullptr curl easy handle");
515 continue;
516 }
517
518 int64_t responseCode = 0;
519 curl_easy_getinfo(curlMsg->easy_handle, CURLINFO_RESPONSE_CODE, &responseCode);
520
521 std::string redirectUrl;
522 char* url = nullptr;
523 curl_easy_getinfo(curlMsg->easy_handle, CURLINFO_REDIRECT_URL, &url);
524 if (url != nullptr) {
525 redirectUrl = url;
526 } else {
527 curl_easy_getinfo(curlMsg->easy_handle, CURLINFO_EFFECTIVE_URL, &url);
528 redirectUrl = url;
529 }
530
531 if (curlMsg->easy_handle == httpCurl_) {
532 httpProbeResult_ = {responseCode, redirectUrl};
533 NETMGR_LOG_I("Recv net[%{public}d] http probe response, code:[%{public}d], redirectUrl:[%{public}s]",
534 netId_, httpProbeResult_.GetCode(), httpProbeResult_.GetRedirectUrl().c_str());
535 } else if (curlMsg->easy_handle == httpsCurl_) {
536 httpsProbeResult_ = {responseCode, redirectUrl};
537 NETMGR_LOG_I("Recv net[%{public}d] https probe response, code:[%{public}d], redirectUrl:[%{public}s]",
538 netId_, httpsProbeResult_.GetCode(), httpsProbeResult_.GetRedirectUrl().c_str());
539 } else {
540 NETMGR_LOG_E("Unknown curl handle.");
541 }
542 }
543 }
LoadProxy(std::string & proxyHost,int32_t & proxyPort)544 int32_t NetHttpProbe::LoadProxy(std::string &proxyHost, int32_t &proxyPort)
545 {
546 std::lock_guard<std::mutex> locker(proxyMtx_);
547 if (!globalHttpProxy_.GetHost().empty()) {
548 proxyHost = globalHttpProxy_.GetHost();
549 proxyPort = static_cast<int32_t>(globalHttpProxy_.GetPort());
550 } else if (!netLinkInfo_.httpProxy_.GetHost().empty()) {
551 proxyHost = netLinkInfo_.httpProxy_.GetHost();
552 proxyPort = static_cast<int32_t>(netLinkInfo_.httpProxy_.GetPort());
553 } else {
554 return false;
555 }
556 return true;
557 }
558 } // namespace NetManagerStandard
559 } // namespace OHOS
560