1 /* 2 * Copyright (c) 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#ifndef URL_JS_URL_H 17#define URL_JS_URL_H 18 19#include <algorithm> 20#include <bitset> 21#include <cmath> 22#include <cstdio> 23#include <cstdlib> 24#include <map> 25#include <string> 26#include <vector> 27#include "napi/native_api.h" 28#include "napi/native_node_api.h" 29namespace OHOS::Url { 30 enum class BitsetStatusFlag { 31 BIT0 = 0, // 0:Bit 0 Set to true,The URL analysis failed 32 BIT1 = 1, // 1:Bit 1 Set to true,The protocol is the default protocol 33 BIT2 = 2, // 2:Bit 2 Set to true,The URL has username 34 BIT3 = 3, // 3:Bit 3 Set to true,The URL has password 35 BIT4 = 4, // 4:Bit 4 Set to true,The URL has hostname 36 BIT5 = 5, // 5:Bit 5 Set to true,The URL Port is the specially 37 BIT6 = 6, // 6:Bit 6 Set to true,The URL has pathname 38 BIT7 = 7, // 7:Bit 7 Set to true,The URL has query 39 BIT8 = 8, // 8:Bit 8 Set to true,The URL has fragment 40 BIT9 = 9, // 9:Bit 9 Set to true,The URL Can not be base 41 BIT10 = 10, // 10:Bit 10 Set to true,The host is IPV6 42 BIT_STATUS_11 = 11, // 11:Each bit of a BIT represents a different parsing state. 43 BIT_ASCII_32 = 32, // 32:32-bit previously invalid control characters in ascii 44 BIT_ASCII_127 = 127, // 127:127 bits in ascii are DEL characters 45 MAX_BIT_SIZE = 128 // 128:ascii max range 46 }; 47 48 struct UrlData { 49 int port = -1; 50 bool isSpecialPath = false; 51 std::vector<std::string> path; 52 std::string password = ""; 53 std::string scheme = ""; 54 std::string query = ""; 55 std::string username = ""; 56 std::string fragment = ""; 57 std::string host = ""; 58 }; 59 60 bool IsHexDigit(const char& ch); 61 std::string DecodeSpecialChars(std::string input); 62 void DeleteC0OrSpace(std::string& str); 63 void DeleteTabOrNewline(std::string& str1); 64 std::string DealIpv4(std::string str); 65 std::string SplitNum(std::string num, size_t& number); 66 void FormatIpv6(std::string& str); 67 bool ISFileNohost(const std::string& input); 68 bool AnalysisScheme(std::string& input, std::string& scheme, 69 std::bitset<static_cast<size_t>(BitsetStatusFlag::BIT_STATUS_11)>& flags); 70 void AnalysisUsernameAndPasswd(std::string& input, std::string& username, std::string& password, 71 std::bitset<static_cast<size_t>(BitsetStatusFlag::BIT_STATUS_11)>& flags); 72 void AnalysisPath(std::string& input, std::vector<std::string>& path, 73 std::bitset<static_cast<size_t>(BitsetStatusFlag::BIT_STATUS_11)>& flags, bool isSpecial); 74 void AnalysisOpaqueHost(std::string input, std::string& host, 75 std::bitset<static_cast<size_t>(BitsetStatusFlag::BIT_STATUS_11)>& flags); 76 void AnalyseIPv4(const std::string& input, std::string& host, 77 std::bitset<static_cast<size_t>(BitsetStatusFlag::BIT_STATUS_11)>& flags); 78 void AnalysisHost(std::string& input, std::string& host, 79 std::bitset<static_cast<size_t>(BitsetStatusFlag::BIT_STATUS_11)>& flags, bool special); 80 void AnalysisFilePath(std::string& input, UrlData& urlinfo, 81 std::bitset<static_cast<size_t>(BitsetStatusFlag::BIT_STATUS_11)>& flags); 82 void AnalysisFilescheme(const std::string& input, UrlData& urlinfo, 83 std::bitset<static_cast<size_t>(BitsetStatusFlag::BIT_STATUS_11)>& flags); 84 void AnalyInfoPath(std::bitset<static_cast<size_t>(BitsetStatusFlag::BIT_STATUS_11)> &flags, 85 UrlData& urlinfo, const std::string& input); 86 void AnalyHostPath(std::string &strHost, std::bitset<static_cast<size_t>(BitsetStatusFlag::BIT_STATUS_11)>& flags, 87 UrlData& urlinfo); 88 void AnalyStrHost(std::string &strHost, UrlData& urlinfo, 89 std::bitset<static_cast<size_t>(BitsetStatusFlag::BIT_STATUS_11)> &flags); 90 void AnalysisNoDefaultProtocol(std::string& input, UrlData& urlinfo, 91 std::bitset<static_cast<size_t>(BitsetStatusFlag::BIT_STATUS_11)>& flags); 92 void AnalysisOnlyHost(const std::string& input, UrlData& urlinfo, 93 std::bitset<static_cast<size_t>(BitsetStatusFlag::BIT_STATUS_11)>& flags, size_t pos); 94 void FormatIpv4(std::vector<std::string> nums, std::string& host, 95 std::bitset<static_cast<size_t>(BitsetStatusFlag::BIT_STATUS_11)> &flags); 96 void AnalysisSpecialFile(std::string& temp, size_t pos, UrlData& urlinfo, 97 std::bitset<static_cast<size_t>(BitsetStatusFlag::BIT_STATUS_11)>& flags); 98 void AnalysisFile(std::string& input, UrlData& urlinfo, 99 std::bitset<static_cast<size_t>(BitsetStatusFlag::BIT_STATUS_11)>& flags); 100 void ParsingHostAndPath(std::string& input, UrlData& urlinfo, size_t& pos, 101 std::bitset<static_cast<size_t>(BitsetStatusFlag::BIT_STATUS_11)>& flags); 102 void ShorteningPath(UrlData& urlData, UrlData& baseData, bool isFile); 103 void RemoveLeadingZeros(std::vector<std::string> &ipv6); 104 void IPv6Host(std::string& input, std::string& host, 105 std::bitset<static_cast<size_t>(BitsetStatusFlag::BIT_STATUS_11)>& flags); 106 std::string BasePathToStr(UrlData& urlData); 107 class URL { 108 public: 109 /** 110 * URI constructor, which is used to instantiate a URI object. 111 * 112 * @param input Constructs a URI by parsing a given string. 113 */ 114 explicit URL(const std::string& input); 115 116 /** 117 * URI constructor, which is used to instantiate a URI object. 118 * 119 * @param input Constructs a URI by parsing a given string. 120 * @param base The input parameter is a character string. 121 */ 122 URL(const std::string& input, const std::string& base); 123 124 /** 125 * URI constructor, which is used to instantiate a URI object. 126 * 127 * @param input Constructs a URI by parsing a given string. 128 * @param base The input parameter is the URL object. 129 */ 130 URL(const std::string& input, const URL& base); 131 132 /** 133 * 134 * @param env NAPI environment parameters. 135 * Gets the host name portion of the URL��not include the port. 136 */ 137 napi_value GetHostname(napi_env env) const; 138 139 /** 140 * Sets the host name portion of the URL��not include the port. 141 * 142 * @param input Constructs a URI by parsing a given string. 143 */ 144 void SetHostname(const std::string& input); 145 146 /** 147 * Sets the username name portion of the URL��not include the port. 148 * 149 * @param input Constructs a URI by parsing a given string. 150 */ 151 void SetUsername(const std::string& input); 152 153 /** 154 * Sets the password portion of the URL��not include the port. 155 * 156 * @param input Constructs a URI by parsing a given string. 157 */ 158 void SetPassword(const std::string& input); 159 160 /** 161 * Sets the scheme portion of the URL��not include the port. 162 * 163 * @param input Constructs a URI by parsing a given string. 164 */ 165 void SetScheme(const std::string& input); 166 167 /** 168 * Sets the fragment portion of the URL��not include the port. 169 * 170 * @param input Constructs a URI by parsing a given string. 171 */ 172 void SetFragment(const std::string& input); 173 174 /** 175 * Sets the search portion of the URL��not include the port. 176 * 177 * @param input Constructs a URI by parsing a given string. 178 */ 179 void SetSearch(const std::string& input); 180 181 /** 182 * Sets the host portion of the URL��not include the port. 183 * 184 * @param input Constructs a URI by parsing a given string. 185 */ 186 void SetHost(const std::string& input); 187 188 /** 189 * Sets the port portion of the URL��not include the port. 190 * 191 * @param input Constructs a URI by parsing a given string. 192 */ 193 void SetPort(const std::string& input); 194 195 /** 196 * Sets the href portion of the URL��not include the port. 197 * 198 * @param input Constructs a URI by parsing a given string. 199 */ 200 void SetHref(const std::string& input); 201 202 /** 203 * Sets the path portion of the URL��not include the port. 204 * 205 * @param input Constructs a URI by parsing a given string. 206 */ 207 void SetPath(const std::string& input); 208 209 /** 210 * Gets the search portion of the URL��not include the port. 211 * 212 * @param env NAPI environment parameters. 213 */ 214 napi_value GetSearch(napi_env env) const; 215 216 /** 217 * Gets the username portion of the URL��not include the port. 218 * 219 * @param env NAPI environment parameters. 220 */ 221 napi_value GetUsername(napi_env env) const; 222 223 /** 224 * Gets the password portion of the URL��not include the port. 225 * 226 * @param env NAPI environment parameters. 227 */ 228 napi_value GetPassword(napi_env env) const; 229 230 /** 231 * Gets the fragment portion of the URL��not include the port. 232 * 233 * @param env NAPI environment parameters. 234 */ 235 napi_value GetFragment(napi_env env) const; 236 237 /** 238 * Gets the scheme portion of the URL��not include the port. 239 * 240 * @param env NAPI environment parameters. 241 */ 242 napi_value GetScheme(napi_env env) const; 243 244 /** 245 * Gets the path portion of the URL��not include the port. 246 * 247 * @param env NAPI environment parameters. 248 */ 249 napi_value GetPath(napi_env env) const; 250 251 /** 252 * Gets the port portion of the URL��not include the port. 253 * 254 * @param env NAPI environment parameters. 255 */ 256 napi_value GetPort(napi_env env) const; 257 258 /** 259 * Judge whether it's on or off. 260 * 261 * @param env NAPI environment parameters. 262 */ 263 napi_value GetOnOrOff(napi_env env) const; 264 265 /** 266 * Judge whether it's Ipv6. 267 * 268 * @param env NAPI environment parameters. 269 */ 270 napi_value GetIsIpv6(napi_env env) const; 271 272 /** 273 * Gets the host name portion of the URL��not include the port. 274 * 275 * @param env NAPI environment parameters. 276 */ 277 napi_value GetHost(napi_env env) const; 278 279 /** 280 * The destructor of the url 281 */ 282 virtual ~URL() {} 283 284 private: 285 UrlData urlData_; 286 std::bitset<static_cast<size_t>(BitsetStatusFlag::BIT_STATUS_11)> flags_; 287 // bitset<11>:Similar to bool array, each bit status represents the real-time status of current URL parsing 288 }; 289 290 class URLSearchParams { 291 public: 292 /** 293 * A parameterized constructor used to create an URLSearchParams instance. 294 */ 295 explicit URLSearchParams() {} 296 297 /** 298 * Virtual destructor of URLSearchParams 299 */ 300 virtual ~URLSearchParams() {} 301 302 /** 303 * Returns a Boolean that indicates whether a parameter with the specified name exists. 304 * 305 * @param env NAPI environment parameters. 306 * @param name Specifies the name of a key-value pair. 307 */ 308 napi_value IsHas(napi_env env, napi_value name) const; 309 310 /** 311 * Returns the first value associated to the given search parameter. 312 * 313 * @param env NAPI environment parameters. 314 * @param buffer Returns the first value associated to the given search parameter. 315 */ 316 napi_value Get(napi_env env, napi_value buffer); 317 318 /** 319 * Returns all key-value pairs associated with a given search parameter as an array. 320 * 321 * @param env NAPI environment parameters. 322 * @param buffer Specifies the name of a key value. 323 */ 324 napi_value GetAll(napi_env env, napi_value buffer); 325 326 /** 327 * Appends a specified key/value pair as a new search parameter. 328 * 329 * @param env NAPI environment parameters. 330 * @param buffer Key name of the search parameter to be inserted. 331 * @param temp Values of search parameters to be inserted. 332 */ 333 void Append(napi_env env, napi_value buffer, napi_value temp); 334 335 /** 336 * Deletes the given search parameter and its associated value,from the list of all search parameters. 337 * 338 * @param env NAPI environment parameters. 339 * @param buffer Name of the key-value pair to be deleted. 340 */ 341 void Delete(napi_env env, napi_value buffer); 342 343 /** 344 * Returns an ES6 iterator. Each item of the iterator is a JavaScript Array. 345 * 346 * @param env NAPI environment parameters. 347 */ 348 napi_value Entries(napi_env env) const; 349 350 /** 351 * Sets the value associated with a given search parameter to the 352 * given value. If there were several matching values, this method 353 * deletes the others. If the search parameter doesn't exist, this 354 * method creates it. 355 * 356 * @param env NAPI environment parameters. 357 * @param name Key name of the parameter to be set. 358 * @param value Indicates the parameter value to be set. 359 */ 360 void Set(napi_env env, napi_value name, napi_value value); 361 362 /** 363 * Sort all key/value pairs contained in this object in place and return undefined. 364 */ 365 void Sort(); 366 367 /** 368 * Returns an iterator allowing to go through all keys contained in this object. 369 * 370 * @param env NAPI environment parameters. 371 */ 372 napi_value IterByKeys(napi_env env); 373 374 /** 375 * Returns an iterator allowing to go through all values contained in this object. 376 * 377 * @param env NAPI environment parameters. 378 */ 379 napi_value IterByValues(napi_env env); 380 381 /** 382 * Sets the string array of searchParams. 383 * 384 * @param env NAPI environment parameters. 385 * @param input String array. 386 */ 387 void SetArray(napi_env env, std::vector<std::string> input); 388 389 /** 390 * Gets the string array of searchParams. 391 * 392 * @param env NAPI environment parameters. 393 */ 394 napi_value GetArray(napi_env env) const; 395 396 /** 397 * This function will decode the string and put the parsed key and value values into the 398 * vector container of urlsearchparams class according to the rules. 399 * 400 * @param env NAPI environment parameters. 401 * @param Stringpar The input parameter of urlsearchparams is string. 402 */ 403 std::vector<std::string> StringParmas(napi_env env, std::string Stringpar); 404 405 private: 406 std::string ToUSVString(std::string inputStr); 407 void HandleIllegalChar(std::wstring& inputStr, std::wstring::const_iterator it); 408 std::vector<std::string> searchParams {}; 409 }; 410} // namespace OHOS::Url 411#endif // URL_JS_URL_H 412