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) {}
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) : port_(0)
32 {
33 if (host.size() <= MAX_URL_SIZE) {
34 host_ = std::move(host);
35 port_ = port;
36 for (const auto &s : exclusionList) {
37 if (s.size() <= MAX_URL_SIZE) {
38 exclusionList_.push_back(s);
39 }
40 if (exclusionList_.size() >= MAX_EXCLUSION_SIZE) {
41 break;
42 }
43 }
44 } else {
45 NETMGR_LOG_E("HttpProxy: host length is invalid");
46 }
47 }
48
GetHost() const49 std::string HttpProxy::GetHost() const
50 {
51 return host_;
52 }
53
GetPort() const54 uint16_t HttpProxy::GetPort() const
55 {
56 return port_;
57 }
58
GetUsername() const59 SecureData HttpProxy::GetUsername() const
60 {
61 return username_;
62 }
63
GetPassword() const64 SecureData HttpProxy::GetPassword() const
65 {
66 return password_;
67 }
68
GetExclusionList() const69 std::list<std::string> HttpProxy::GetExclusionList() const
70 {
71 return exclusionList_;
72 }
73
operator ==(const HttpProxy & httpProxy) const74 bool HttpProxy::operator==(const HttpProxy &httpProxy) const
75 {
76 return (host_ == httpProxy.host_ && port_ == httpProxy.port_ && exclusionList_ == httpProxy.exclusionList_ &&
77 username_ == httpProxy.username_ && password_ == httpProxy.password_);
78 }
79
operator !=(const HttpProxy & httpProxy) const80 bool HttpProxy::operator!=(const HttpProxy &httpProxy) const
81 {
82 return !(httpProxy == *this);
83 }
84
Marshalling(Parcel & parcel) const85 bool HttpProxy::Marshalling(Parcel &parcel) const
86 {
87 if (!parcel.WriteString(host_)) {
88 return false;
89 }
90
91 if (!parcel.WriteUint16(port_)) {
92 return false;
93 }
94
95 if (!parcel.WriteUint32(static_cast<uint32_t>(std::min(MAX_EXCLUSION_SIZE, exclusionList_.size())))) {
96 return false;
97 }
98
99 uint32_t size = 0;
100 for (const auto &s : exclusionList_) {
101 if (!parcel.WriteString(s)) {
102 return false;
103 }
104 ++size;
105 if (size >= MAX_EXCLUSION_SIZE) {
106 return true;
107 }
108 }
109 parcel.WriteString(username_);
110 parcel.WriteString(password_);
111 return true;
112 }
113
Unmarshalling(Parcel & parcel,HttpProxy & httpProxy)114 bool HttpProxy::Unmarshalling(Parcel &parcel, HttpProxy &httpProxy)
115 {
116 std::string host;
117 if (!parcel.ReadString(host)) {
118 return false;
119 }
120 if (host.size() > MAX_URL_SIZE) {
121 NETMGR_LOG_E("HttpProxy: Unmarshalling: host length is invalid");
122 return false;
123 }
124
125 uint16_t port = 0;
126 if (!parcel.ReadUint16(port)) {
127 return false;
128 }
129
130 uint32_t size = 0;
131 if (!parcel.ReadUint32(size)) {
132 return false;
133 }
134
135 if (size == 0) {
136 httpProxy = {host, port, {}};
137 return true;
138 }
139
140 if (size > static_cast<uint32_t>(MAX_EXCLUSION_SIZE)) {
141 size = MAX_EXCLUSION_SIZE;
142 }
143
144 std::list<std::string> exclusionList;
145 for (uint32_t i = 0; i < size; ++i) {
146 std::string s;
147 if (!parcel.ReadString(s)) {
148 return false;
149 }
150 if (s.size() <= MAX_URL_SIZE) {
151 exclusionList.push_back(s);
152 }
153 }
154
155 httpProxy = {host, port, exclusionList};
156 parcel.ReadString(httpProxy.username_);
157 parcel.ReadString(httpProxy.password_);
158 return true;
159 }
160
ToString() const161 std::string HttpProxy::ToString() const
162 {
163 std::string s;
164 std::string tab = "\t";
165 s.append(host_);
166 s.append(tab);
167 s.append(std::to_string(port_));
168 s.append(tab);
169 for (const auto &e : exclusionList_) {
170 s.append(e);
171 s.append(",");
172 }
173 return s;
174 }
175
176 struct Parser {
ParserOHOS::NetManagerStandard::Parser177 Parser(std::string::const_iterator begin, std::string::const_iterator end) : begin(begin), end(end) {}
178
ParsePortOHOS::NetManagerStandard::Parser179 static std::optional<uint16_t> ParsePort(const std::string &portStr)
180 {
181 char *strEnd = nullptr;
182 auto port = std::strtol(portStr.c_str(), &strEnd, BASE_DEC);
183 if (strEnd == portStr.c_str() || port < 0 || port > std::numeric_limits<uint16_t>::max()) {
184 return std::nullopt;
185 }
186 return static_cast<uint16_t>(port);
187 }
188
ParseProxyExclusionListOHOS::NetManagerStandard::Parser189 static std::list<std::string> ParseProxyExclusionList(const std::string &exclusionList)
190 {
191 std::list<std::string> exclusionItems;
192 std::stringstream ss(exclusionList);
193 std::string item;
194
195 while (std::getline(ss, item, ',')) {
196 size_t start = item.find_first_not_of(" \t");
197 size_t end = item.find_last_not_of(" \t");
198 if (start != std::string::npos && end != std::string::npos) {
199 item = item.substr(start, end - start + 1);
200 }
201 exclusionItems.push_back(item);
202 }
203 return exclusionItems;
204 }
205
GetHostOHOS::NetManagerStandard::Parser206 std::optional<std::string> GetHost()
207 {
208 if (auto hostEnd = std::find(begin, end, '\t'); hostEnd != end) {
209 auto host = std::string(begin, hostEnd);
210 begin = hostEnd + 1;
211 return host;
212 }
213 return std::nullopt;
214 }
215
GetPortOHOS::NetManagerStandard::Parser216 std::optional<uint16_t> GetPort()
217 {
218 if (auto portEnd = std::find(begin, end, '\t'); portEnd != end) {
219 auto host = std::string(begin, portEnd);
220 auto port = ParsePort(std::string(begin, portEnd));
221 begin = portEnd + 1;
222 return port;
223 }
224 return std::nullopt;
225 }
226
GetExclusionListOHOS::NetManagerStandard::Parser227 std::list<std::string> GetExclusionList()
228 {
229 if (begin != end) {
230 auto list = ParseProxyExclusionList(std::string(begin, end));
231 begin = end;
232 return list;
233 }
234 return {};
235 }
236
237 std::string::const_iterator begin;
238 std::string::const_iterator end;
239 };
240
FromString(const std::string & str)241 std::optional<HttpProxy> HttpProxy::FromString(const std::string &str)
242 {
243 Parser parser(str.cbegin(), str.cend());
244 auto host = parser.GetHost();
245 auto port = parser.GetPort();
246 if (!host || !port) {
247 return std::nullopt;
248 }
249 return NetManagerStandard::HttpProxy(*host, *port, parser.GetExclusionList());
250 }
251 } // namespace NetManagerStandard
252 } // namespace OHOS
253