1 /*
2 * Copyright (C) 2021-2022 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 <arpa/inet.h>
17 #include <cstring>
18 #include <fcntl.h>
19 #include <fstream>
20 #include <future>
21 #include <list>
22 #include <memory>
23 #include <netdb.h>
24 #include <regex>
25 #include <securec.h>
26 #include <sys/socket.h>
27 #include <thread>
28 #include <unistd.h>
29 #include "dns_config_client.h"
30
31 #include "event_report.h"
32 #include "fwmark_client.h"
33 #include "netmanager_base_common_utils.h"
34 #include "netsys_controller.h"
35 #include "net_mgr_log_wrapper.h"
36 #include "net_monitor.h"
37
38 namespace OHOS {
39 namespace NetManagerStandard {
40 static constexpr int32_t INIT_DETECTION_DELAY_MS = 8 * 1000;
41 static constexpr int32_t MAX_FAILED_DETECTION_DELAY_MS = 5 * 60 * 1000;
42 static constexpr int32_t SUCCESSED_DETECTION_DELAY_MS = 30 * 1000;
43 static constexpr int32_t CAPTIVE_PORTAL_DETECTION_DELAY_MS = 60 * 1000;
44 static constexpr int32_t DOUBLE = 2;
45 static constexpr int32_t DOMAINIPADDR = 128;
46 static constexpr int32_t PORTAL_CONTENT_LENGTH_MIN = 4;
47 static constexpr int32_t NET_CONTENT_LENGTH = 6;
48 static constexpr uint16_t DEFAULT_PORT = 80;
49 static constexpr int32_t MAX_RECIVE_SIZE = 2048;
50 static constexpr int32_t DOMAIN_POSITION = 3;
51 static constexpr int32_t URLPATH_POSITION = 4;
52 static constexpr int32_t SOCKET_TIMEOUT = 2;
53 static constexpr int32_t MAX_SEND_RETRY = 4;
54 static constexpr uint8_t SOCKET_NOT_READY = 0;
55 static constexpr uint8_t SOCKET_READY = 1;
56 constexpr const char *PORTAL_URL_REDIRECT_FIRST_CASE = "Location: ";
57 constexpr const char *PORTAL_URL_REDIRECT_SECOND_CASE = "http";
58 constexpr const char *CONTENT_STR = "Content-Length:";
59 constexpr const char *PORTAL_END_STR = ".com";
60 constexpr const char SPACE_STR = ' ';
61 constexpr const char NEW_LINE_STR = '\n';
62 constexpr const char *URL_CFG_FILE = "/system/etc/netdetectionurl.conf";
63 constexpr const char *DEF_NETDETECT_URL = "http://connectivitycheck.platform.hicloud.com/generate_204";
64
NetDetectThread(const std::shared_ptr<NetMonitor> & netMonitor)65 static void NetDetectThread(const std::shared_ptr<NetMonitor> &netMonitor)
66 {
67 if (netMonitor == nullptr) {
68 NETMGR_LOG_E("netMonitor is nullptr");
69 return;
70 }
71 while (netMonitor->IsDetecting()) {
72 netMonitor->Detection();
73 }
74 }
75
NetMonitor(uint32_t netId,const std::weak_ptr<INetMonitorCallback> & callback)76 NetMonitor::NetMonitor(uint32_t netId, const std::weak_ptr<INetMonitorCallback> &callback)
77 : netId_(netId), netMonitorCallback_(callback)
78 {
79 }
80
Start()81 void NetMonitor::Start()
82 {
83 NETMGR_LOG_I("Start net[%{public}d] monitor in", netId_);
84 if (isDetecting_) {
85 NETMGR_LOG_W("Net[%{public}d] monitor is detecting, no need to start", netId_);
86 return;
87 }
88 isDetecting_ = true;
89 std::shared_ptr<NetMonitor> netMonitor = shared_from_this();
90 std::thread([netMonitor] { return NetDetectThread(netMonitor); }).detach();
91 }
92
Stop()93 void NetMonitor::Stop()
94 {
95 NETMGR_LOG_I("Stop net[%{public}d] monitor in", netId_);
96 isDetecting_ = false;
97 detectionCond_.notify_all();
98 NETMGR_LOG_I("Stop net[%{public}d] monitor out", netId_);
99 }
100
IsDetecting()101 bool NetMonitor::IsDetecting()
102 {
103 return isDetecting_.load();
104 }
105
Detection()106 void NetMonitor::Detection()
107 {
108 NetDetectionStatus result = SendParallelHttpProbes();
109 struct EventInfo eventInfo = {.monitorStatus = static_cast<int32_t>(result)};
110 EventReport::SendMonitorBehaviorEvent(eventInfo);
111 if (isDetecting_) {
112 if (result == CAPTIVE_PORTAL_STATE) {
113 NETMGR_LOG_I("currentNetMonitor[%{public}d] need portal", netId_);
114 detectionDelay_ = CAPTIVE_PORTAL_DETECTION_DELAY_MS;
115 } else if (result == VERIFICATION_STATE) {
116 NETMGR_LOG_I("currentNetMonitor[%{public}d] evaluation success", netId_);
117 detectionDelay_ = SUCCESSED_DETECTION_DELAY_MS;
118 detectionSteps_ = 0;
119 } else {
120 NETMGR_LOG_I("currentNetMonitor[%{public}d] evaluation failed", netId_);
121 detectionDelay_ = static_cast<uint32_t>(INIT_DETECTION_DELAY_MS * DOUBLE * detectionSteps_);
122 if (detectionDelay_ == 0) {
123 detectionDelay_ = INIT_DETECTION_DELAY_MS;
124 } else if (detectionDelay_ >= MAX_FAILED_DETECTION_DELAY_MS) {
125 detectionDelay_ = MAX_FAILED_DETECTION_DELAY_MS;
126 }
127 detectionSteps_++;
128 }
129 auto monitorCallback = netMonitorCallback_.lock();
130 if (monitorCallback) {
131 monitorCallback->OnHandleNetMonitorResult(result, portalUrlRedirect_);
132 }
133 if (isDetecting_) {
134 std::unique_lock<std::mutex> locker(detectionMtx_);
135 detectionCond_.wait_for(locker, std::chrono::milliseconds(detectionDelay_));
136 }
137 }
138 }
139
SendParallelHttpProbes()140 NetDetectionStatus NetMonitor::SendParallelHttpProbes()
141 {
142 std::string url;
143 if (GetDefaultNetDetectionUrlFromCfg(url) != 0) {
144 NETMGR_LOG_I("GetDefaultNetDetectionUrlFromCfg failed, use default url");
145 url = DEF_NETDETECT_URL;
146 }
147 std::string domain;
148 std::string urlPath;
149 if (ParseUrl(url, domain, urlPath)) {
150 NETMGR_LOG_E("Parse net[%{public}d] url:%{public}s error", netId_, url.c_str());
151 return INVALID_DETECTION_STATE;
152 }
153 return SendHttpProbe(domain, urlPath, DEFAULT_PORT);
154 }
155
SendHttpProbe(const std::string & defaultDomain,const std::string & defaultUrl,const uint16_t defaultPort)156 NetDetectionStatus NetMonitor::SendHttpProbe(const std::string &defaultDomain, const std::string &defaultUrl,
157 const uint16_t defaultPort)
158 {
159 int socketType = AF_INET;
160 std::string ipAddr;
161 if (GetIpAddr(defaultDomain, ipAddr, socketType)) {
162 NETMGR_LOG_E("NetMonitor::Error at GetIpAddr");
163 return INVALID_DETECTION_STATE;
164 }
165 int32_t sockFd = socket(socketType, SOCK_STREAM | SOCK_NONBLOCK, IPPROTO_TCP);
166 if (sockFd < 0) {
167 NETMGR_LOG_E("Create net[%{public}d] socket failed,errno[%{public}d]:%{public}s", netId_, errno,
168 strerror(errno));
169 return INVALID_DETECTION_STATE;
170 }
171 if (SetSocketParameter(sockFd)) {
172 close(sockFd);
173 NETMGR_LOG_E("Set net[%{public}d] socket parameter error", netId_);
174 return INVALID_DETECTION_STATE;
175 }
176 if (Connect(sockFd, socketType, defaultPort, ipAddr) < 0) {
177 NETMGR_LOG_E("Connect net[%{public}d] nonblock socket:%{public}d failed", netId_, sockFd);
178 close(sockFd);
179 return INVALID_DETECTION_STATE;
180 }
181 if (Send(sockFd, defaultDomain, defaultUrl) < 0) {
182 NETMGR_LOG_E("Send http probe data to net[%{public}d] socket:%{public}d failed", netId_, sockFd);
183 close(sockFd);
184 return INVALID_DETECTION_STATE;
185 }
186 std::string probeResult;
187 if (Receive(sockFd, probeResult) < 0) {
188 NETMGR_LOG_E("Recevie probe result from net[%{public}d] socket:%{public}d failed", netId_, sockFd);
189 close(sockFd);
190 return INVALID_DETECTION_STATE;
191 }
192 close(sockFd);
193 return dealRecvResult(probeResult);
194 }
195
Connect(int32_t sockFd,int socketType,const uint16_t port,const std::string & ipAddr)196 int32_t NetMonitor::Connect(int32_t sockFd, int socketType, const uint16_t port, const std::string &ipAddr)
197 {
198 int flags = fcntl(sockFd, F_GETFL, 0);
199 if (flags == -1 && errno == EINTR) {
200 flags = fcntl(sockFd, F_GETFL, 0);
201 if (flags == -1) {
202 NETMGR_LOG_E("Make net[%{public}d] socket:%{public}d non block failed,error[%{public}d]: %s", netId_,
203 sockFd, errno, strerror(errno));
204 return -1;
205 }
206 }
207 uint32_t tempFlags = (uint32_t)flags | O_NONBLOCK;
208 int32_t ret = fcntl(sockFd, F_SETFL, tempFlags);
209 if (ret == -1 && errno == EINTR) {
210 ret = fcntl(sockFd, F_SETFL, tempFlags);
211 if (ret == -1) {
212 NETMGR_LOG_E("Make net[%{public}d] socket:%{public}d non block failed,error[%{public}d]: %s", netId_,
213 sockFd, errno, strerror(errno));
214 return -1;
215 }
216 }
217 if (socketType == AF_INET6) {
218 return ConnectIpv6(sockFd, port, ipAddr);
219 } else {
220 return ConnectIpv4(sockFd, port, ipAddr);
221 }
222 }
223
ConnectIpv4(int32_t sockFd,const uint16_t port,const std::string & ipAddr)224 int32_t NetMonitor::ConnectIpv4(int32_t sockFd, const uint16_t port, const std::string &ipAddr)
225 {
226 NETMGR_LOG_D("Net[%{public}d] connect ipv4 ip:[%{public}s] socket:%{public}d in", netId_,
227 CommonUtils::ToAnonymousIp(ipAddr).c_str(), sockFd);
228 sockaddr_in serverAddr;
229 bzero(&serverAddr, sizeof(serverAddr));
230 serverAddr.sin_family = AF_INET;
231 serverAddr.sin_port = htons(port);
232 serverAddr.sin_addr.s_addr = inet_addr(ipAddr.c_str());
233 int32_t ret = connect(sockFd, (struct sockaddr *)&serverAddr, sizeof(serverAddr));
234 if (ret < 0) {
235 if (errno != EINPROGRESS) {
236 NETMGR_LOG_E("Connect net[%{public}d] ipv4 ip:%{public}s failed,error[%{public}d]:%{public}s", netId_,
237 CommonUtils::ToAnonymousIp(ipAddr).c_str(), errno, strerror(errno));
238 return -1;
239 }
240 }
241 return 0;
242 }
243
ConnectIpv6(int32_t sockFd,const uint16_t port,const std::string & ipAddr)244 int32_t NetMonitor::ConnectIpv6(int32_t sockFd, const uint16_t port, const std::string &ipAddr)
245 {
246 NETMGR_LOG_D("Net[%{public}d] connect ipv6 ip:[%{public}s] socket:%{public}d in", netId_,
247 CommonUtils::ToAnonymousIp(ipAddr).c_str(), sockFd);
248 sockaddr_in6 serverAddr;
249 bzero(&serverAddr, sizeof(serverAddr));
250 serverAddr.sin6_family = AF_INET6;
251 serverAddr.sin6_port = htons(port);
252 inet_pton(AF_INET6, ipAddr.c_str(), &serverAddr.sin6_addr);
253 int32_t ret = connect(sockFd, (struct sockaddr *)&serverAddr, sizeof(serverAddr));
254 if (ret < 0) {
255 if (errno != EINPROGRESS) {
256 NETMGR_LOG_E("Connect net[%{public}d] ipv6 ip:%{public}s failed,error[%{public}d]:%{public}s", netId_,
257 CommonUtils::ToAnonymousIp(ipAddr).c_str(), errno, strerror(errno));
258 return -1;
259 }
260 }
261 return 0;
262 }
263
Wait(int32_t sockFd,uint8_t * canRead,uint8_t * canWrite)264 int32_t NetMonitor::Wait(int32_t sockFd, uint8_t *canRead, uint8_t *canWrite)
265 {
266 fd_set writeFds, readFds;
267 FD_ZERO(&readFds);
268 FD_ZERO(&writeFds);
269 if (canRead) {
270 FD_SET(sockFd, &readFds);
271 }
272 if (canWrite) {
273 FD_SET(sockFd, &writeFds);
274 }
275 struct timeval tval = {tval.tv_sec = 8, tval.tv_usec = 0};
276 int ret = select((sockFd + 1), &readFds, &writeFds, nullptr, &tval);
277 if (ret <= 0) {
278 NETMGR_LOG_E("Select net[%{public}d] failed,errno[%{public}d]:%{public}s", netId_, errno, strerror(errno));
279 return -1;
280 }
281 if (FD_ISSET(sockFd, &readFds) && canRead) {
282 *canRead = SOCKET_READY;
283 }
284 if (FD_ISSET(sockFd, &writeFds) && canWrite) {
285 *canWrite = SOCKET_READY;
286 }
287 return 0;
288 }
289
Send(int32_t sockFd,const std::string & domain,const std::string & url)290 int32_t NetMonitor::Send(int32_t sockFd, const std::string &domain, const std::string &url)
291 {
292 uint8_t canWrite = SOCKET_NOT_READY;
293 int32_t ret = Wait(sockFd, nullptr, &canWrite);
294 if (ret < 0 || canWrite != SOCKET_READY) {
295 NETMGR_LOG_E("Net[%{public}d] socket not ready to send data,ret:%{public}d, canWrite:%{public}d", netId_, ret,
296 canWrite);
297 return -1;
298 }
299 std::string sendData = "GET /" + url + " HTTP/1.1\r\n";
300 sendData.append("Host: " + domain + "\r\n\r\n");
301 const char *writeBuf = sendData.c_str();
302 int32_t bufSize = static_cast<int32_t>(sendData.size());
303 int32_t written = 0;
304 int32_t retry = 0;
305 while (bufSize > 0) {
306 written = send(sockFd, writeBuf, bufSize, 0);
307 if (written < 0) {
308 if (errno == EAGAIN && retry < MAX_SEND_RETRY) {
309 ++retry;
310 NETMGR_LOG_W("Net[%{public}d] try to resend the data to sokcet:%{public}d for the :%{public}d times",
311 netId_, sockFd, retry);
312 continue;
313 }
314 NETMGR_LOG_E("Net[%{public}d] Send data to socket:%{public}d failed, errno[%{public}d]:%{public}s", netId_,
315 sockFd, errno, strerror(errno));
316 return -1;
317 }
318 if (written == 0) {
319 break;
320 }
321 writeBuf += written;
322 bufSize -= written;
323 }
324 return 0;
325 }
326
Receive(int32_t sockFd,std::string & probResult)327 int32_t NetMonitor::Receive(int32_t sockFd, std::string &probResult)
328 {
329 uint8_t canRead = SOCKET_NOT_READY;
330 int32_t ret = Wait(sockFd, &canRead, nullptr);
331 if (ret < 0 || canRead != SOCKET_READY) {
332 NETMGR_LOG_E("Net[%{public}d] socket not ready to read data, ret:%{public}d, canRead:%{public}d", netId_, ret,
333 canRead);
334 return -1;
335 }
336 char buff[MAX_RECIVE_SIZE] = {0};
337 int32_t recvBytes = recv(sockFd, buff, MAX_RECIVE_SIZE, 0);
338 if (recvBytes <= 0) {
339 NETMGR_LOG_E("Receive net[%{public}d] data from socket failed,errno[%{public}d]:%{public}s", netId_, errno,
340 strerror(errno));
341 return -1;
342 }
343 probResult = std::string(buff, recvBytes);
344 return 0;
345 }
346
SetSocketParameter(int32_t sockFd)347 int32_t NetMonitor::SetSocketParameter(int32_t sockFd)
348 {
349 std::unique_ptr<nmd::FwmarkClient> fwmarkClient = std::make_unique<nmd::FwmarkClient>();
350 if (fwmarkClient->BindSocket(sockFd, netId_) < 0) {
351 NETMGR_LOG_E("Error at bind net[%{public}d] socket", netId_);
352 struct EventInfo eventInfo = {.socketFd = sockFd,
353 .errorType = static_cast<int32_t>(FAULT_BIND_SOCKET_FAILED),
354 .errorMsg =
355 std::string("Bind socket:").append(std::to_string(sockFd)).append(" failed")};
356 EventReport::SendMonitorFaultEvent(eventInfo);
357 return -1;
358 }
359 struct timeval timeout;
360 timeout.tv_sec = SOCKET_TIMEOUT;
361 timeout.tv_usec = 0;
362 if (setsockopt(sockFd, SOL_SOCKET, SO_SNDTIMEO, &timeout, sizeof(timeout)) ||
363 setsockopt(sockFd, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof(timeout))) {
364 NETMGR_LOG_E("Error at set net[%{public}d] socket timeout,error[%{public}d]:%{public}s", netId_, errno,
365 strerror(errno));
366 return -1;
367 }
368 return 0;
369 }
370
dealRecvResult(const std::string & strResponse)371 NetDetectionStatus NetMonitor::dealRecvResult(const std::string &strResponse)
372 {
373 std::string urlRedirect = "";
374 int32_t retCode = GetUrlRedirectFromResponse(strResponse, urlRedirect);
375 int32_t statusCode = GetStatusCodeFromResponse(strResponse);
376 portalUrlRedirect_ = urlRedirect;
377 NETMGR_LOG_D("statusCode[%{public}d], retCode[%{public}d]", statusCode, retCode);
378 if ((statusCode == OK || (statusCode >= BAD_REQUEST && statusCode <= CLIENT_ERROR_MAX)) &&
379 retCode > PORTAL_CONTENT_LENGTH_MIN) {
380 if (retCode > -1) {
381 return CAPTIVE_PORTAL_STATE;
382 }
383 return INVALID_DETECTION_STATE;
384 } else if (statusCode == NO_CONTENT) {
385 return VERIFICATION_STATE;
386 } else if ((statusCode != NO_CONTENT) && (statusCode >= CREATED) && (statusCode <= URL_REDIRECT_MAX)) {
387 if (retCode > -1) {
388 return CAPTIVE_PORTAL_STATE;
389 }
390 return INVALID_DETECTION_STATE;
391 }
392 return INVALID_DETECTION_STATE;
393 }
394
GetStatusCodeFromResponse(const std::string & strResponse)395 int32_t NetMonitor::GetStatusCodeFromResponse(const std::string &strResponse)
396 {
397 if (strResponse.empty()) {
398 NETMGR_LOG_E("strResponse is empty");
399 return -1;
400 }
401
402 std::string::size_type newLinePos = strResponse.find("\r\n");
403 if (newLinePos == std::string::npos) {
404 NETMGR_LOG_E("StrResponse did not find the response line!");
405 return -1;
406 }
407 std::string statusLine = strResponse.substr(0, newLinePos);
408 std::string::size_type spacePos = statusLine.find(" ");
409 if (spacePos == std::string::npos) {
410 NETMGR_LOG_E("No spaces found in the response line!");
411 return -1;
412 }
413 std::string strStatusCode = statusLine.substr(spacePos + 1, statusLine.length() - 1);
414 std::string::size_type pos = strStatusCode.find(" ");
415 if (pos == std::string::npos) {
416 NETMGR_LOG_E("No other space was found in the response line!");
417 return -1;
418 }
419 strStatusCode.resize(pos);
420 if (strStatusCode.empty()) {
421 NETMGR_LOG_E("String status code is empty!");
422 return -1;
423 }
424
425 int32_t statusCode = std::stoi(strStatusCode);
426 return statusCode;
427 }
428
GetUrlRedirectFromResponse(const std::string & strResponse,std::string & urlRedirect)429 int32_t NetMonitor::GetUrlRedirectFromResponse(const std::string &strResponse, std::string &urlRedirect)
430 {
431 if (strResponse.empty()) {
432 NETMGR_LOG_E("strResponse is empty");
433 return -1;
434 }
435
436 std::string::size_type startPos = strResponse.find(PORTAL_URL_REDIRECT_FIRST_CASE);
437 if (startPos != std::string::npos) {
438 startPos += strlen(PORTAL_URL_REDIRECT_FIRST_CASE);
439 std::string::size_type endPos = strResponse.find(PORTAL_END_STR, startPos);
440 if (endPos != std::string::npos) {
441 urlRedirect = strResponse.substr(startPos, endPos - startPos + strlen(PORTAL_END_STR));
442 }
443 return 0;
444 }
445
446 startPos = strResponse.find(PORTAL_URL_REDIRECT_SECOND_CASE);
447 if (startPos != std::string::npos) {
448 startPos += strlen(PORTAL_URL_REDIRECT_SECOND_CASE);
449 std::string::size_type endPos = strResponse.find(PORTAL_END_STR, startPos);
450 if (endPos != std::string::npos) {
451 urlRedirect = strResponse.substr(startPos, endPos - startPos + strlen(PORTAL_END_STR));
452 }
453 startPos = strResponse.find(CONTENT_STR);
454 return std::atoi(strResponse.substr(startPos + strlen(CONTENT_STR), NET_CONTENT_LENGTH).c_str());
455 }
456 return -1;
457 }
458
GetIpAddr(const std::string & domain,std::string & ip_addr,int & socketType)459 int32_t NetMonitor::GetIpAddr(const std::string &domain, std::string &ip_addr, int &socketType)
460 {
461 std::vector<AddrInfo> result;
462 AddrInfo hints = {};
463 std::string serverName;
464 if (NetsysController::GetInstance().GetAddrInfo(domain, serverName, hints, netId_, result) < 0) {
465 NETMGR_LOG_E("Get net[%{public}d] address info failed,errno[%{public}d]:%{public}s", netId_, errno,
466 strerror(errno));
467 return -1;
468 }
469 if (result.empty()) {
470 NETMGR_LOG_E("Get net[%{public}d] address info return nullptr result", netId_);
471 return -1;
472 }
473 char ip[DOMAINIPADDR] = {0};
474 for (auto &node : result) {
475 if (node.aiFamily != AF_INET) {
476 continue;
477 }
478 if (!inet_ntop(AF_INET, &node.aiAddr.sin.sin_addr, ip, sizeof(ip))) {
479 continue;
480 }
481 ip_addr = ip;
482 socketType = AF_INET;
483 NETMGR_LOG_D("Get net[%{public}d] monitor ip:%{public}s", netId_, CommonUtils::ToAnonymousIp(ip_addr).c_str());
484 return 0;
485 }
486 if (result[0].aiFamily == AF_INET6) {
487 inet_ntop(AF_INET6, &result[0].aiAddr.sin6.sin6_addr, ip, sizeof(ip));
488 ip_addr = ip;
489 socketType = AF_INET6;
490 }
491 NETMGR_LOG_D("Get net[%{public}d] monitor ip:%{public}s", netId_, CommonUtils::ToAnonymousIp(ip_addr).c_str());
492 return 0;
493 }
494
GetDefaultNetDetectionUrlFromCfg(std::string & strUrl)495 int32_t NetMonitor::GetDefaultNetDetectionUrlFromCfg(std::string &strUrl)
496 {
497 int32_t ret = 0;
498 std::ifstream file(URL_CFG_FILE);
499 if (!file.is_open()) {
500 NETMGR_LOG_E("Open file failed (%{public}s)", strerror(errno));
501 ret = -1;
502 return ret;
503 }
504
505 std::ostringstream oss;
506 oss << file.rdbuf();
507 std::string content = oss.str();
508 auto index = content.find_last_of(SPACE_STR);
509 strUrl = content.substr(index + 1);
510 if (strUrl.empty()) {
511 NETMGR_LOG_E("get netdetectionurl is empty");
512 ret = -1;
513 }
514 strUrl.erase(std::remove(strUrl.begin(), strUrl.end(), NEW_LINE_STR), strUrl.end());
515 NETMGR_LOG_D("GetDefaultNetDetectionUrl is : %{public}s", strUrl.c_str());
516 return ret;
517 }
518
ParseUrl(const std::string & url,std::string & domain,std::string & urlPath)519 int32_t NetMonitor::ParseUrl(const std::string &url, std::string &domain, std::string &urlPath)
520 {
521 std::regex reg_domain_port("/");
522 std::cregex_token_iterator itrBegin(url.c_str(), url.c_str() + url.size(), reg_domain_port, -1);
523 std::cregex_token_iterator itrEnd;
524 int32_t i = 0;
525 for (std::cregex_token_iterator itr = itrBegin; itr != itrEnd; ++itr) {
526 i++;
527 if (i == DOMAIN_POSITION) {
528 domain = *itr;
529 } else if (i == URLPATH_POSITION) {
530 urlPath = *itr;
531 }
532 }
533 return (domain.empty() || urlPath.empty()) ? -1 : 0;
534 }
535 } // namespace NetManagerStandard
536 } // namespace OHOS
537