1 /*
2  * Copyright (c) 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 
17 #include "i_network_message.h"
18 
19 #include "netstack_common_utils.h"
20 
21 namespace OHOS::NetStack {
22 namespace {
23 constexpr const size_t STATUS_LINE_SIZE = 3;
24 }
25 
INetworkMessage(std::string requestId)26 INetworkMessage::INetworkMessage(std::string requestId)
27     : requestId_(std::move(requestId)),
28       requestBeginTime_(0) {}
29 
30 INetworkMessage::~INetworkMessage() = default;
31 
SetRequestBeginTime(uint64_t bootTime)32 void INetworkMessage::SetRequestBeginTime(uint64_t bootTime)
33 {
34     requestBeginTime_ = bootTime;
35 }
36 
37 #if HAS_NETMANAGER_BASE
GetIpAddressFromCurlHandle(std::string & ip,CURL * handle)38 uint32_t INetworkMessage::GetIpAddressFromCurlHandle(std::string &ip, CURL *handle)
39 {
40     if (handle == nullptr) {
41         return static_cast<uint32_t>(CURLE_FAILED_INIT);
42     }
43     char *tmp = nullptr;
44     CURL_GET_INFO(handle, CURLINFO_PRIMARY_IP, &tmp);
45     if (tmp != nullptr) {
46         ip.append(tmp);
47     }
48     return static_cast<uint32_t>(CURLE_OK);
49 }
50 
GetEffectiveUrlFromCurlHandle(std::string & effectiveUrl,CURL * handle)51 uint32_t INetworkMessage::GetEffectiveUrlFromCurlHandle(std::string &effectiveUrl, CURL *handle)
52 {
53     if (handle == nullptr) {
54         return static_cast<uint32_t>(CURLE_FAILED_INIT);
55     }
56     char *tmp = nullptr;
57     CURL_GET_INFO(handle, CURLINFO_EFFECTIVE_URL, &tmp);
58     if (tmp != nullptr) {
59         effectiveUrl.append(tmp);
60     }
61     return static_cast<uint32_t>(CURLE_OK);
62 }
63 
GetHttpVersionFromCurlHandle(std::string & httpVersion,CURL * handle)64 uint32_t INetworkMessage::GetHttpVersionFromCurlHandle(std::string &httpVersion, CURL *handle)
65 {
66     if (handle == nullptr) {
67         return static_cast<uint32_t>(CURLE_FAILED_INIT);
68     }
69     long tmp = CURL_HTTP_VERSION_1_1;
70     CURL_GET_INFO(handle, CURLINFO_HTTP_VERSION, &tmp);
71     httpVersion = GetHttpVersion(tmp);
72     return static_cast<uint32_t>(CURLE_OK);
73 }
74 
GetTimeInfoFromCurlHandle(TimeInfo & timeInfo,CURL * handle)75 uint32_t INetworkMessage::GetTimeInfoFromCurlHandle(TimeInfo &timeInfo, CURL *handle)
76 {
77     if (handle == nullptr) {
78         return static_cast<uint32_t>(CURLE_FAILED_INIT);
79     }
80     curl_off_t dnsTime = 0;
81     CURL_GET_TIME_INFO(handle, CURLINFO_NAMELOOKUP_TIME_T, dnsTime, timeInfo);
82     curl_off_t tcpConnectTime = 0;
83     CURL_GET_TIME_INFO(handle, CURLINFO_CONNECT_TIME_T, tcpConnectTime, timeInfo);
84     curl_off_t tlsHandshakeTime = 0;
85     CURL_GET_TIME_INFO(handle, CURLINFO_APPCONNECT_TIME_T, tlsHandshakeTime, timeInfo);
86     curl_off_t firstSendTime = 0;
87     CURL_GET_TIME_INFO(handle, CURLINFO_PRETRANSFER_TIME_T, firstSendTime, timeInfo);
88     curl_off_t firstRecvTime = 0;
89     CURL_GET_TIME_INFO(handle, CURLINFO_STARTTRANSFER_TIME_T, firstRecvTime, timeInfo);
90     curl_off_t redirectTime = 0;
91     CURL_GET_TIME_INFO(handle, CURLINFO_REDIRECT_TIME_T, redirectTime, timeInfo);
92     curl_off_t totalTime = 0;
93     CURL_GET_TIME_INFO(handle, CURLINFO_TOTAL_TIME_T, totalTime, timeInfo);
94     return static_cast<uint32_t>(CURLE_OK);
95 }
96 #endif
97 
GetReasonParse(const std::string & rawHeader)98 std::string INetworkMessage::GetReasonParse(const std::string &rawHeader)
99 {
100     std::vector<std::string> vec = CommonUtils::Split(rawHeader, "\r\n");
101     if (vec.empty()) {
102         return {};
103     }
104     std::vector<std::string> resVec;
105     for (const auto &s: vec) {
106         if (s.find(":") != std::string::npos) {
107             continue;
108         }
109         auto temp = CommonUtils::Split(s, " ");
110         if (temp.size() < STATUS_LINE_SIZE) {
111             continue;
112         }
113         if (temp.size() == STATUS_LINE_SIZE) {
114             resVec.emplace_back(temp[STATUS_LINE_SIZE - 1]);
115         }
116         std::string res;
117         for (size_t i = STATUS_LINE_SIZE - 1; i < temp.size(); ++i) {
118             res += temp[i] + " ";
119         }
120         if (!res.empty()) {
121             res.pop_back();
122         }
123         resVec.emplace_back(res);
124     }
125     if (resVec.empty()) {
126         return {};
127     }
128     return *(resVec.end() - 1);
129 }
130 
GetRawHeader(const std::map<std::string,std::string> & headers)131 std::string INetworkMessage::GetRawHeader(const std::map<std::string, std::string> &headers)
132 {
133     std::string result;
134     std::for_each(headers.begin(), headers.end(), [&result](const auto &item) {
135         result += item.first + ":" + item.second + "\r\n";
136     });
137     return result;
138 }
139 
GetHttpVersion(long httpVersion)140 std::string INetworkMessage::GetHttpVersion(long httpVersion)
141 {
142 #if HAS_NETMANAGER_BASE
143     switch (httpVersion) {
144         case CURL_HTTP_VERSION_1_0:
145             return "1.0";
146         case CURL_HTTP_VERSION_1_1:
147             return "1.1";
148         case CURL_HTTP_VERSION_2:
149             return "2";
150         case CURL_HTTP_VERSION_3:
151             return "3";
152         default:
153             break;
154     }
155 #endif
156     return "unknown";
157 }
158 }