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" 29 namespace 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 95 class URL { 96 public: 97 /** 98 * URI constructor, which is used to instantiate a URI object. 99 * 100 * @param input Constructs a URI by parsing a given string. 101 */ 102 explicit URL(const std::string& input); 103 104 /** 105 * URI constructor, which is used to instantiate a URI object. 106 * 107 * @param input Constructs a URI by parsing a given string. 108 * @param base The input parameter is a character string. 109 */ 110 URL(const std::string& input, const std::string& base); 111 112 /** 113 * URI constructor, which is used to instantiate a URI object. 114 * 115 * @param input Constructs a URI by parsing a given string. 116 * @param base The input parameter is the URL object. 117 */ 118 URL(const std::string& input, const URL& base); 119 120 /** 121 * 122 * @param env NAPI environment parameters. 123 * Gets the host name portion of the URL��not include the port. 124 */ 125 napi_value GetHostname(napi_env env) const; 126 127 /** 128 * Sets the host name portion of the URL��not include the port. 129 * 130 * @param input Constructs a URI by parsing a given string. 131 */ 132 void SetHostname(const std::string& input); 133 134 /** 135 * Sets the username name portion of the URL��not include the port. 136 * 137 * @param input Constructs a URI by parsing a given string. 138 */ 139 void SetUsername(const std::string& input); 140 141 /** 142 * Sets the password portion of the URL��not include the port. 143 * 144 * @param input Constructs a URI by parsing a given string. 145 */ 146 void SetPassword(const std::string& input); 147 148 /** 149 * Sets the scheme portion of the URL��not include the port. 150 * 151 * @param input Constructs a URI by parsing a given string. 152 */ 153 void SetScheme(const std::string& input); 154 155 /** 156 * Sets the fragment portion of the URL��not include the port. 157 * 158 * @param input Constructs a URI by parsing a given string. 159 */ 160 void SetFragment(const std::string& input); 161 162 /** 163 * Sets the search portion of the URL��not include the port. 164 * 165 * @param input Constructs a URI by parsing a given string. 166 */ 167 void SetSearch(const std::string& input); 168 169 /** 170 * Sets the host portion of the URL��not include the port. 171 * 172 * @param input Constructs a URI by parsing a given string. 173 */ 174 void SetHost(const std::string& input); 175 176 /** 177 * Sets the port portion of the URL��not include the port. 178 * 179 * @param input Constructs a URI by parsing a given string. 180 */ 181 void SetPort(const std::string& input); 182 183 /** 184 * Sets the href portion of the URL��not include the port. 185 * 186 * @param input Constructs a URI by parsing a given string. 187 */ 188 void SetHref(const std::string& input); 189 190 /** 191 * Sets the path portion of the URL��not include the port. 192 * 193 * @param input Constructs a URI by parsing a given string. 194 */ 195 void SetPath(const std::string& input); 196 197 /** 198 * Gets the search portion of the URL��not include the port. 199 * 200 * @param env NAPI environment parameters. 201 */ 202 napi_value GetSearch(napi_env env) const; 203 204 /** 205 * Gets the username portion of the URL��not include the port. 206 * 207 * @param env NAPI environment parameters. 208 */ 209 napi_value GetUsername(napi_env env) const; 210 211 /** 212 * Gets the password portion of the URL��not include the port. 213 * 214 * @param env NAPI environment parameters. 215 */ 216 napi_value GetPassword(napi_env env) const; 217 218 /** 219 * Gets the fragment portion of the URL��not include the port. 220 * 221 * @param env NAPI environment parameters. 222 */ 223 napi_value GetFragment(napi_env env) const; 224 225 /** 226 * Gets the scheme portion of the URL��not include the port. 227 * 228 * @param env NAPI environment parameters. 229 */ 230 napi_value GetScheme(napi_env env) const; 231 232 /** 233 * Gets the path portion of the URL��not include the port. 234 * 235 * @param env NAPI environment parameters. 236 */ 237 napi_value GetPath(napi_env env) const; 238 239 /** 240 * Gets the port portion of the URL��not include the port. 241 * 242 * @param env NAPI environment parameters. 243 */ 244 napi_value GetPort(napi_env env) const; 245 246 /** 247 * Judge whether it's on or off. 248 * 249 * @param env NAPI environment parameters. 250 */ 251 napi_value GetOnOrOff(napi_env env) const; 252 253 /** 254 * Judge whether it's Ipv6. 255 * 256 * @param env NAPI environment parameters. 257 */ 258 napi_value GetIsIpv6(napi_env env) const; 259 260 /** 261 * Gets the host name portion of the URL��not include the port. 262 * 263 * @param env NAPI environment parameters. 264 */ 265 napi_value GetHost(napi_env env) const; 266 267 /** 268 * The destructor of the url 269 */ ~URL()270 virtual ~URL() {} 271 272 private: 273 UrlData urlData_; 274 std::bitset<static_cast<size_t>(BitsetStatusFlag::BIT_STATUS_11)> flags_; 275 // bitset<11>:Similar to bool array, each bit status represents the real-time status of current URL parsing 276 }; 277 278 class URLSearchParams { 279 public: 280 /** 281 * A parameterized constructor used to create an URLSearchParams instance. 282 */ URLSearchParams()283 explicit URLSearchParams() {} 284 285 /** 286 * Virtual destructor of URLSearchParams 287 */ ~URLSearchParams()288 virtual ~URLSearchParams() {} 289 290 /** 291 * Returns a Boolean that indicates whether a parameter with the specified name exists. 292 * 293 * @param env NAPI environment parameters. 294 * @param name Specifies the name of a key-value pair. 295 */ 296 napi_value IsHas(napi_env env, napi_value name) const; 297 298 /** 299 * Returns the first value associated to the given search parameter. 300 * 301 * @param env NAPI environment parameters. 302 * @param buffer Returns the first value associated to the given search parameter. 303 */ 304 napi_value Get(napi_env env, napi_value buffer); 305 306 /** 307 * Returns all key-value pairs associated with a given search parameter as an array. 308 * 309 * @param env NAPI environment parameters. 310 * @param buffer Specifies the name of a key value. 311 */ 312 napi_value GetAll(napi_env env, napi_value buffer); 313 314 /** 315 * Appends a specified key/value pair as a new search parameter. 316 * 317 * @param env NAPI environment parameters. 318 * @param buffer Key name of the search parameter to be inserted. 319 * @param temp Values of search parameters to be inserted. 320 */ 321 void Append(napi_env env, napi_value buffer, napi_value temp); 322 323 /** 324 * Deletes the given search parameter and its associated value,from the list of all search parameters. 325 * 326 * @param env NAPI environment parameters. 327 * @param buffer Name of the key-value pair to be deleted. 328 */ 329 void Delete(napi_env env, napi_value buffer); 330 331 /** 332 * Returns an ES6 iterator. Each item of the iterator is a JavaScript Array. 333 * 334 * @param env NAPI environment parameters. 335 */ 336 napi_value Entries(napi_env env) const; 337 338 /** 339 * Sets the value associated with a given search parameter to the 340 * given value. If there were several matching values, this method 341 * deletes the others. If the search parameter doesn't exist, this 342 * method creates it. 343 * 344 * @param env NAPI environment parameters. 345 * @param name Key name of the parameter to be set. 346 * @param value Indicates the parameter value to be set. 347 */ 348 void Set(napi_env env, napi_value name, napi_value value); 349 350 /** 351 * Sort all key/value pairs contained in this object in place and return undefined. 352 */ 353 void Sort(); 354 355 /** 356 * Returns an iterator allowing to go through all keys contained in this object. 357 * 358 * @param env NAPI environment parameters. 359 */ 360 napi_value IterByKeys(napi_env env); 361 362 /** 363 * Returns an iterator allowing to go through all values contained in this object. 364 * 365 * @param env NAPI environment parameters. 366 */ 367 napi_value IterByValues(napi_env env); 368 369 /** 370 * Sets the string array of searchParams. 371 * 372 * @param env NAPI environment parameters. 373 * @param input String array. 374 */ 375 void SetArray(napi_env env, std::vector<std::string> input); 376 377 /** 378 * Gets the string array of searchParams. 379 * 380 * @param env NAPI environment parameters. 381 */ 382 napi_value GetArray(napi_env env) const; 383 384 /** 385 * This function will decode the string and put the parsed key and value values into the 386 * vector container of urlsearchparams class according to the rules. 387 * 388 * @param env NAPI environment parameters. 389 * @param Stringpar The input parameter of urlsearchparams is string. 390 */ 391 std::vector<std::string> StringParmas(napi_env env, std::string Stringpar); 392 393 private: 394 std::string ToUSVString(std::string inputStr); 395 void HandleIllegalChar(std::wstring& inputStr, std::wstring::const_iterator it); 396 std::vector<std::string> searchParams {}; 397 }; 398 } // namespace OHOS::Url 399 #endif // URL_JS_URL_H 400