1 /*
2 * Copyright (c) 2022-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 #include "net_mgr_log_wrapper.h"
17 #include "http_proxy.h"
18
19 #include <cstdint>
20 #include <cstdlib>
21 #include <sstream>
22
23 namespace OHOS {
24 namespace NetManagerStandard {
25 static const size_t MAX_EXCLUSION_SIZE = 500;
26 static const size_t MAX_URL_SIZE = 2048;
27 static const size_t BASE_DEC = 10;
28
HttpProxy()29 HttpProxy::HttpProxy() : port_(0), userId_(-1) {}
30
HttpProxy(std::string host,uint16_t port,const std::list<std::string> & exclusionList)31 HttpProxy::HttpProxy(std::string host, uint16_t port, const std::list<std::string> &exclusionList)
32 : port_(0), userId_(-1)
33 {
34 if (host.size() <= MAX_URL_SIZE) {
35 host_ = std::move(host);
36 port_ = port;
37 for (const auto &s : exclusionList) {
38 if (s.size() <= MAX_URL_SIZE) {
39 exclusionList_.push_back(s);
40 }
41 if (exclusionList_.size() >= MAX_EXCLUSION_SIZE) {
42 break;
43 }
44 }
45 } else {
46 NETMGR_LOG_E("HttpProxy: host length is invalid");
47 }
48 }
49
GetHost() const50 std::string HttpProxy::GetHost() const
51 {
52 return host_;
53 }
54
GetPort() const55 uint16_t HttpProxy::GetPort() const
56 {
57 return port_;
58 }
59
GetUsername() const60 SecureData HttpProxy::GetUsername() const
61 {
62 return username_;
63 }
64
GetPassword() const65 SecureData HttpProxy::GetPassword() const
66 {
67 return password_;
68 }
69
GetExclusionList() const70 std::list<std::string> HttpProxy::GetExclusionList() const
71 {
72 return exclusionList_;
73 }
74
GetUserId() const75 int32_t HttpProxy::GetUserId() const
76 {
77 return userId_;
78 }
79
operator ==(const HttpProxy & httpProxy) const80 bool HttpProxy::operator==(const HttpProxy &httpProxy) const
81 {
82 return (host_ == httpProxy.host_ && port_ == httpProxy.port_ && exclusionList_ == httpProxy.exclusionList_ &&
83 username_ == httpProxy.username_ && password_ == httpProxy.password_);
84 }
85
operator !=(const HttpProxy & httpProxy) const86 bool HttpProxy::operator!=(const HttpProxy &httpProxy) const
87 {
88 return !(httpProxy == *this);
89 }
90
Marshalling(Parcel & parcel) const91 bool HttpProxy::Marshalling(Parcel &parcel) const
92 {
93 if (!parcel.WriteString(host_)) {
94 return false;
95 }
96
97 if (!parcel.WriteUint16(port_)) {
98 return false;
99 }
100
101 if (!parcel.WriteInt32(userId_)) {
102 return false;
103 }
104
105 if (!parcel.WriteUint32(static_cast<uint32_t>(std::min(MAX_EXCLUSION_SIZE, exclusionList_.size())))) {
106 return false;
107 }
108
109 uint32_t size = 0;
110 for (const auto &s : exclusionList_) {
111 if (!parcel.WriteString(s)) {
112 return false;
113 }
114 ++size;
115 if (size >= MAX_EXCLUSION_SIZE) {
116 return true;
117 }
118 }
119 parcel.WriteString(username_);
120 parcel.WriteString(password_);
121 return true;
122 }
123
Unmarshalling(Parcel & parcel,HttpProxy & httpProxy)124 bool HttpProxy::Unmarshalling(Parcel &parcel, HttpProxy &httpProxy)
125 {
126 std::string host;
127 if (!parcel.ReadString(host)) {
128 return false;
129 }
130 if (host.size() > MAX_URL_SIZE) {
131 NETMGR_LOG_E("HttpProxy: Unmarshalling: host length is invalid");
132 return false;
133 }
134
135 uint16_t port = 0;
136 if (!parcel.ReadUint16(port)) {
137 return false;
138 }
139
140 int32_t userId = -1;
141 if (!parcel.ReadInt32(userId)) {
142 return false;
143 }
144
145 uint32_t size = 0;
146 if (!parcel.ReadUint32(size)) {
147 return false;
148 }
149
150 if (size > static_cast<uint32_t>(MAX_EXCLUSION_SIZE)) {
151 size = MAX_EXCLUSION_SIZE;
152 }
153
154 std::list<std::string> exclusionList;
155 for (uint32_t i = 0; i < size; ++i) {
156 std::string s;
157 if (!parcel.ReadString(s)) {
158 return false;
159 }
160 if (s.size() <= MAX_URL_SIZE) {
161 exclusionList.push_back(s);
162 }
163 }
164
165 httpProxy = {host, port, exclusionList};
166 httpProxy.SetUserId(userId);
167 parcel.ReadString(httpProxy.username_);
168 parcel.ReadString(httpProxy.password_);
169 return true;
170 }
171
ToString() const172 std::string HttpProxy::ToString() const
173 {
174 std::string s;
175 std::string tab = "\t";
176 s.append(host_);
177 s.append(tab);
178 s.append(std::to_string(port_));
179 s.append(tab);
180 for (const auto &e : exclusionList_) {
181 s.append(e);
182 s.append(",");
183 }
184 return s;
185 }
186
187 struct Parser {
ParserOHOS::NetManagerStandard::Parser188 Parser(std::string::const_iterator begin, std::string::const_iterator end) : begin(begin), end(end) {}
189
ParsePortOHOS::NetManagerStandard::Parser190 static std::optional<uint16_t> ParsePort(const std::string &portStr)
191 {
192 char *strEnd = nullptr;
193 auto port = std::strtol(portStr.c_str(), &strEnd, BASE_DEC);
194 if (strEnd == portStr.c_str() || port < 0 || port > std::numeric_limits<uint16_t>::max()) {
195 return std::nullopt;
196 }
197 return static_cast<uint16_t>(port);
198 }
199
ParseProxyExclusionListOHOS::NetManagerStandard::Parser200 static std::list<std::string> ParseProxyExclusionList(const std::string &exclusionList)
201 {
202 std::list<std::string> exclusionItems;
203 std::stringstream ss(exclusionList);
204 std::string item;
205
206 while (std::getline(ss, item, ',')) {
207 size_t start = item.find_first_not_of(" \t");
208 size_t end = item.find_last_not_of(" \t");
209 if (start != std::string::npos && end != std::string::npos) {
210 item = item.substr(start, end - start + 1);
211 }
212 exclusionItems.push_back(item);
213 }
214 return exclusionItems;
215 }
216
GetHostOHOS::NetManagerStandard::Parser217 std::optional<std::string> GetHost()
218 {
219 if (auto hostEnd = std::find(begin, end, '\t'); hostEnd != end) {
220 auto host = std::string(begin, hostEnd);
221 begin = hostEnd + 1;
222 return host;
223 }
224 return std::nullopt;
225 }
226
GetPortOHOS::NetManagerStandard::Parser227 std::optional<uint16_t> GetPort()
228 {
229 if (auto portEnd = std::find(begin, end, '\t'); portEnd != end) {
230 auto host = std::string(begin, portEnd);
231 auto port = ParsePort(std::string(begin, portEnd));
232 begin = portEnd + 1;
233 return port;
234 }
235 return std::nullopt;
236 }
237
GetExclusionListOHOS::NetManagerStandard::Parser238 std::list<std::string> GetExclusionList()
239 {
240 if (begin != end) {
241 auto list = ParseProxyExclusionList(std::string(begin, end));
242 begin = end;
243 return list;
244 }
245 return {};
246 }
247
248 std::string::const_iterator begin;
249 std::string::const_iterator end;
250 };
251
FromString(const std::string & str)252 std::optional<HttpProxy> HttpProxy::FromString(const std::string &str)
253 {
254 Parser parser(str.cbegin(), str.cend());
255 auto host = parser.GetHost();
256 auto port = parser.GetPort();
257 if (!host || !port) {
258 return std::nullopt;
259 }
260 return NetManagerStandard::HttpProxy(*host, *port, parser.GetExclusionList());
261 }
262 } // namespace NetManagerStandard
263 } // namespace OHOS
264