14d6c458bSopenharmony_ci/* 24d6c458bSopenharmony_ci * Copyright (c) 2022 Huawei Device Co., Ltd. 34d6c458bSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 44d6c458bSopenharmony_ci * you may not use this file except in compliance with the License. 54d6c458bSopenharmony_ci * You may obtain a copy of the License at 64d6c458bSopenharmony_ci * 74d6c458bSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 84d6c458bSopenharmony_ci * 94d6c458bSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 104d6c458bSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 114d6c458bSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 124d6c458bSopenharmony_ci * See the License for the specific language governing permissions and 134d6c458bSopenharmony_ci * limitations under the License. 144d6c458bSopenharmony_ci */ 154d6c458bSopenharmony_ci 164d6c458bSopenharmony_ci#include "js_uri.h" 174d6c458bSopenharmony_ci#include "tools/log.h" 184d6c458bSopenharmony_cinamespace OHOS::Uri { 194d6c458bSopenharmony_ci std::bitset<MAX_BIT_SIZE> g_ruleAlpha; 204d6c458bSopenharmony_ci std::bitset<MAX_BIT_SIZE> g_ruleScheme; 214d6c458bSopenharmony_ci std::bitset<MAX_BIT_SIZE> g_ruleUrlc; 224d6c458bSopenharmony_ci std::bitset<MAX_BIT_SIZE> g_rulePath; 234d6c458bSopenharmony_ci std::bitset<MAX_BIT_SIZE> g_ruleUserInfo; 244d6c458bSopenharmony_ci std::bitset<MAX_BIT_SIZE> g_ruleDigit; 254d6c458bSopenharmony_ci std::bitset<MAX_BIT_SIZE> g_rulePort; 264d6c458bSopenharmony_ci void Uri::PreliminaryWork() const 274d6c458bSopenharmony_ci { 284d6c458bSopenharmony_ci std::string digitAggregate = "0123456789"; 294d6c458bSopenharmony_ci for (size_t i = 0; i < digitAggregate.size(); ++i) { 304d6c458bSopenharmony_ci g_ruleDigit.set(digitAggregate[i]); 314d6c458bSopenharmony_ci } 324d6c458bSopenharmony_ci 334d6c458bSopenharmony_ci std::string alphasAggregate = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ"; 344d6c458bSopenharmony_ci for (size_t i = 0; i < alphasAggregate.size(); ++i) { 354d6c458bSopenharmony_ci g_ruleAlpha.set(alphasAggregate[i]); 364d6c458bSopenharmony_ci } 374d6c458bSopenharmony_ci 384d6c458bSopenharmony_ci std::string schemeAggregate = digitAggregate + alphasAggregate + "+-.| _-~!$&=,;'(){}*"; 394d6c458bSopenharmony_ci for (size_t i = 0; i < schemeAggregate.size(); ++i) { 404d6c458bSopenharmony_ci g_ruleScheme.set(schemeAggregate[i]); 414d6c458bSopenharmony_ci } 424d6c458bSopenharmony_ci 434d6c458bSopenharmony_ci std::string uricAggregate = schemeAggregate + ";/?:@&=$,[]_!~*'()%\""; 444d6c458bSopenharmony_ci for (size_t i = 0; i < uricAggregate.size(); ++i) { 454d6c458bSopenharmony_ci g_ruleUrlc.set(uricAggregate[i]); 464d6c458bSopenharmony_ci } 474d6c458bSopenharmony_ci 484d6c458bSopenharmony_ci std::string pathAggregate = schemeAggregate + ";/:@&=$,_!~*'()%"; 494d6c458bSopenharmony_ci for (size_t i = 0; i < pathAggregate.size(); ++i) { 504d6c458bSopenharmony_ci g_rulePath.set(pathAggregate[i]); 514d6c458bSopenharmony_ci } 524d6c458bSopenharmony_ci 534d6c458bSopenharmony_ci std::string userInfoAggregate = schemeAggregate + ";:&=$,_!~*'()%"; 544d6c458bSopenharmony_ci for (size_t i = 0; i < userInfoAggregate.size(); ++i) { 554d6c458bSopenharmony_ci g_ruleUserInfo.set(userInfoAggregate[i]); 564d6c458bSopenharmony_ci } 574d6c458bSopenharmony_ci 584d6c458bSopenharmony_ci std::string portAggregate = digitAggregate + alphasAggregate + ".:@-;&=+$,-_!~*'()"; 594d6c458bSopenharmony_ci for (size_t i = 0; i < portAggregate.size(); ++i) { 604d6c458bSopenharmony_ci g_rulePort.set(portAggregate[i]); 614d6c458bSopenharmony_ci } 624d6c458bSopenharmony_ci } 634d6c458bSopenharmony_ci 644d6c458bSopenharmony_ci Uri::Uri(const std::string input) 654d6c458bSopenharmony_ci { 664d6c458bSopenharmony_ci PreliminaryWork(); 674d6c458bSopenharmony_ci errStr_ = ""; 684d6c458bSopenharmony_ci if (input.empty()) { 694d6c458bSopenharmony_ci errStr_ = "uri is empty"; 704d6c458bSopenharmony_ci return; 714d6c458bSopenharmony_ci } 724d6c458bSopenharmony_ci inputUri_ = input; 734d6c458bSopenharmony_ci AnalysisUri(); 744d6c458bSopenharmony_ci } 754d6c458bSopenharmony_ci 764d6c458bSopenharmony_ci void Uri::AssignSchemeSpecificPart() 774d6c458bSopenharmony_ci { 784d6c458bSopenharmony_ci uriData_.SchemeSpecificPart.reserve(data_.length() + uriData_.query.length() + 1); 794d6c458bSopenharmony_ci uriData_.SchemeSpecificPart.append(data_); 804d6c458bSopenharmony_ci if (!uriData_.query.empty()) { 814d6c458bSopenharmony_ci uriData_.SchemeSpecificPart.append("?"); 824d6c458bSopenharmony_ci uriData_.SchemeSpecificPart.append(uriData_.query); 834d6c458bSopenharmony_ci } 844d6c458bSopenharmony_ci } 854d6c458bSopenharmony_ci 864d6c458bSopenharmony_ci void Uri::AnalysisUri() 874d6c458bSopenharmony_ci { 884d6c458bSopenharmony_ci data_ = inputUri_; 894d6c458bSopenharmony_ci size_t pos = data_.find('#'); // Fragment 904d6c458bSopenharmony_ci if (pos != std::string::npos) { 914d6c458bSopenharmony_ci AnalysisFragment(pos); 924d6c458bSopenharmony_ci if (!errStr_.empty()) { 934d6c458bSopenharmony_ci return; 944d6c458bSopenharmony_ci } 954d6c458bSopenharmony_ci } 964d6c458bSopenharmony_ci pos = data_.find('?'); // Query 974d6c458bSopenharmony_ci if (pos != std::string::npos) { 984d6c458bSopenharmony_ci AnalysisQuery(pos); 994d6c458bSopenharmony_ci if (!errStr_.empty()) { 1004d6c458bSopenharmony_ci return; 1014d6c458bSopenharmony_ci } 1024d6c458bSopenharmony_ci } 1034d6c458bSopenharmony_ci pos = data_.find(':'); // Scheme 1044d6c458bSopenharmony_ci if (pos != std::string::npos) { 1054d6c458bSopenharmony_ci AnalysisScheme(pos); 1064d6c458bSopenharmony_ci if (!errStr_.empty()) { 1074d6c458bSopenharmony_ci return; 1084d6c458bSopenharmony_ci } 1094d6c458bSopenharmony_ci } else { 1104d6c458bSopenharmony_ci SpecialPath(); 1114d6c458bSopenharmony_ci if (!errStr_.empty()) { 1124d6c458bSopenharmony_ci return; 1134d6c458bSopenharmony_ci } 1144d6c458bSopenharmony_ci AssignSchemeSpecificPart(); 1154d6c458bSopenharmony_ci return; 1164d6c458bSopenharmony_ci } 1174d6c458bSopenharmony_ci pos = data_.find("//"); // userInfo path host port ipv4 or ipv6 1184d6c458bSopenharmony_ci if (pos != std::string::npos && pos == 0) { 1194d6c458bSopenharmony_ci AssignSchemeSpecificPart(); 1204d6c458bSopenharmony_ci data_ = data_.substr(2); // 2:Intercept the string from the second subscript 1214d6c458bSopenharmony_ci AnalysisHostAndPath(); 1224d6c458bSopenharmony_ci if (!errStr_.empty()) { 1234d6c458bSopenharmony_ci return; 1244d6c458bSopenharmony_ci } 1254d6c458bSopenharmony_ci } else if (data_[0] == '/') { 1264d6c458bSopenharmony_ci uriData_.path = data_; 1274d6c458bSopenharmony_ci AssignSchemeSpecificPart(); 1284d6c458bSopenharmony_ci data_ = ""; 1294d6c458bSopenharmony_ci } else { 1304d6c458bSopenharmony_ci AssignSchemeSpecificPart(); 1314d6c458bSopenharmony_ci uriData_.query = ""; 1324d6c458bSopenharmony_ci data_ = ""; 1334d6c458bSopenharmony_ci } 1344d6c458bSopenharmony_ci } 1354d6c458bSopenharmony_ci 1364d6c458bSopenharmony_ci bool Uri::CheckCharacter(std::string data, std::bitset<MAX_BIT_SIZE> rule, bool flag) const 1374d6c458bSopenharmony_ci { 1384d6c458bSopenharmony_ci size_t dataLen = data.size(); 1394d6c458bSopenharmony_ci for (size_t i = 0; i < dataLen; ++i) { 1404d6c458bSopenharmony_ci if (static_cast<int>(data[i]) >= 0 && static_cast<int>(data[i]) < 128) { // 128:ASCII Max Number 1414d6c458bSopenharmony_ci bool isLegal = rule.test(data[i]); 1424d6c458bSopenharmony_ci if (!isLegal) { 1434d6c458bSopenharmony_ci return false; 1444d6c458bSopenharmony_ci } 1454d6c458bSopenharmony_ci } else if (!flag) { 1464d6c458bSopenharmony_ci return false; 1474d6c458bSopenharmony_ci } 1484d6c458bSopenharmony_ci } 1494d6c458bSopenharmony_ci return true; 1504d6c458bSopenharmony_ci } 1514d6c458bSopenharmony_ci 1524d6c458bSopenharmony_ci void Uri::SpecialPath() 1534d6c458bSopenharmony_ci { 1544d6c458bSopenharmony_ci if (!CheckCharacter(data_, g_rulePath, true)) { 1554d6c458bSopenharmony_ci errStr_ = "SpecialPath does not conform to the rule"; 1564d6c458bSopenharmony_ci return; 1574d6c458bSopenharmony_ci } 1584d6c458bSopenharmony_ci uriData_.path = data_; 1594d6c458bSopenharmony_ci data_ = ""; 1604d6c458bSopenharmony_ci } 1614d6c458bSopenharmony_ci 1624d6c458bSopenharmony_ci void Uri::AnalysisFragment(size_t pos) 1634d6c458bSopenharmony_ci { 1644d6c458bSopenharmony_ci if (pos == 0) { 1654d6c458bSopenharmony_ci errStr_ = "#It can't be the first"; 1664d6c458bSopenharmony_ci return; 1674d6c458bSopenharmony_ci } 1684d6c458bSopenharmony_ci std::string fragment = data_.substr(pos + 1); 1694d6c458bSopenharmony_ci if (!CheckCharacter(fragment, g_ruleUrlc, true)) { 1704d6c458bSopenharmony_ci errStr_ = "Fragment does not conform to the rule"; 1714d6c458bSopenharmony_ci return; 1724d6c458bSopenharmony_ci } 1734d6c458bSopenharmony_ci uriData_.fragment = fragment; 1744d6c458bSopenharmony_ci data_ = data_.substr(0, pos); 1754d6c458bSopenharmony_ci } 1764d6c458bSopenharmony_ci 1774d6c458bSopenharmony_ci void Uri::AnalysisQuery(size_t pos) 1784d6c458bSopenharmony_ci { 1794d6c458bSopenharmony_ci std::string query = data_.substr(pos + 1); 1804d6c458bSopenharmony_ci if (!CheckCharacter(query, g_ruleUrlc, true)) { 1814d6c458bSopenharmony_ci errStr_ = "Query does not conform to the rule"; 1824d6c458bSopenharmony_ci return; 1834d6c458bSopenharmony_ci } 1844d6c458bSopenharmony_ci uriData_.query = query; 1854d6c458bSopenharmony_ci data_ = data_.substr(0, pos); 1864d6c458bSopenharmony_ci } 1874d6c458bSopenharmony_ci 1884d6c458bSopenharmony_ci void Uri::AnalysisScheme(size_t pos) 1894d6c458bSopenharmony_ci { 1904d6c458bSopenharmony_ci size_t slashPos = data_.find('/'); 1914d6c458bSopenharmony_ci if (slashPos != std::string::npos && slashPos < pos) { 1924d6c458bSopenharmony_ci SpecialPath(); 1934d6c458bSopenharmony_ci uriData_.SchemeSpecificPart.reserve(uriData_.path.length() + uriData_.query.length() + 1); 1944d6c458bSopenharmony_ci uriData_.SchemeSpecificPart.append(uriData_.path); 1954d6c458bSopenharmony_ci uriData_.SchemeSpecificPart.append("?"); 1964d6c458bSopenharmony_ci uriData_.SchemeSpecificPart.append(uriData_.query); 1974d6c458bSopenharmony_ci data_ = ""; 1984d6c458bSopenharmony_ci } else { 1994d6c458bSopenharmony_ci if ((static_cast<int>(data_[0]) >= 0 && static_cast<int>(data_[0]) < MAX_BIT_SIZE) && 2004d6c458bSopenharmony_ci !g_ruleAlpha.test(data_[0])) { 2014d6c458bSopenharmony_ci errStr_ = "Scheme the first character must be a letter"; 2024d6c458bSopenharmony_ci return; 2034d6c458bSopenharmony_ci } 2044d6c458bSopenharmony_ci std::string scheme = data_.substr(0, pos); 2054d6c458bSopenharmony_ci if (!CheckCharacter(scheme, g_ruleScheme, false)) { 2064d6c458bSopenharmony_ci errStr_ = "scheme does not conform to the rule"; 2074d6c458bSopenharmony_ci return; 2084d6c458bSopenharmony_ci } 2094d6c458bSopenharmony_ci uriData_.scheme = scheme; 2104d6c458bSopenharmony_ci data_ = data_.substr(pos + 1); 2114d6c458bSopenharmony_ci } 2124d6c458bSopenharmony_ci } 2134d6c458bSopenharmony_ci 2144d6c458bSopenharmony_ci void Uri::AnalysisHost(bool isLawfulProt) 2154d6c458bSopenharmony_ci { 2164d6c458bSopenharmony_ci // find ipv4 or ipv6 or host 2174d6c458bSopenharmony_ci if (data_[0] == '[') { 2184d6c458bSopenharmony_ci if (data_[data_.size() - 1] == ']') { 2194d6c458bSopenharmony_ci // IPV6 2204d6c458bSopenharmony_ci if (!isLawfulProt) { 2214d6c458bSopenharmony_ci errStr_ = "Prot does not conform to the rule"; 2224d6c458bSopenharmony_ci return; 2234d6c458bSopenharmony_ci } 2244d6c458bSopenharmony_ci AnalysisIPV6(); 2254d6c458bSopenharmony_ci } else { 2264d6c458bSopenharmony_ci errStr_ = "IPv6 is missing a closing bracket"; 2274d6c458bSopenharmony_ci return; 2284d6c458bSopenharmony_ci } 2294d6c458bSopenharmony_ci } else { 2304d6c458bSopenharmony_ci if (data_.find('[') != std::string::npos || data_.find(']') != std::string::npos) { 2314d6c458bSopenharmony_ci errStr_ = "host does not conform to the rule"; 2324d6c458bSopenharmony_ci return; 2334d6c458bSopenharmony_ci } 2344d6c458bSopenharmony_ci // ipv4 2354d6c458bSopenharmony_ci if (!isLawfulProt || !AnalysisIPV4()) { 2364d6c458bSopenharmony_ci uriData_.port = -1; 2374d6c458bSopenharmony_ci uriData_.host = ""; 2384d6c458bSopenharmony_ci uriData_.userInfo = ""; 2394d6c458bSopenharmony_ci } 2404d6c458bSopenharmony_ci } 2414d6c458bSopenharmony_ci } 2424d6c458bSopenharmony_ci 2434d6c458bSopenharmony_ci void Uri::AnalysisHostAndPath() 2444d6c458bSopenharmony_ci { 2454d6c458bSopenharmony_ci if (data_.empty()) { 2464d6c458bSopenharmony_ci return; 2474d6c458bSopenharmony_ci } 2484d6c458bSopenharmony_ci // find path 2494d6c458bSopenharmony_ci size_t pos = data_.find('/'); 2504d6c458bSopenharmony_ci if (pos != std::string::npos) { 2514d6c458bSopenharmony_ci AnalysisPath(pos); 2524d6c458bSopenharmony_ci if (!errStr_.empty()) { 2534d6c458bSopenharmony_ci return; 2544d6c458bSopenharmony_ci } 2554d6c458bSopenharmony_ci } 2564d6c458bSopenharmony_ci uriData_.authority = data_; 2574d6c458bSopenharmony_ci // find UserInfo 2584d6c458bSopenharmony_ci pos = data_.find('@'); 2594d6c458bSopenharmony_ci if (pos != std::string::npos) { 2604d6c458bSopenharmony_ci AnalysisUserInfo(pos); 2614d6c458bSopenharmony_ci if (!errStr_.empty()) { 2624d6c458bSopenharmony_ci return; 2634d6c458bSopenharmony_ci } 2644d6c458bSopenharmony_ci } 2654d6c458bSopenharmony_ci bool isLawfulProt = true; 2664d6c458bSopenharmony_ci // find port 2674d6c458bSopenharmony_ci pos = data_.rfind(':'); 2684d6c458bSopenharmony_ci if (pos != std::string::npos) { 2694d6c458bSopenharmony_ci size_t pos1 = data_.rfind(']'); 2704d6c458bSopenharmony_ci if (pos1 == std::string::npos || pos > pos1) { 2714d6c458bSopenharmony_ci isLawfulProt = AnalysisPort(pos); 2724d6c458bSopenharmony_ci } 2734d6c458bSopenharmony_ci if (!errStr_.empty()) { 2744d6c458bSopenharmony_ci return; 2754d6c458bSopenharmony_ci } 2764d6c458bSopenharmony_ci } 2774d6c458bSopenharmony_ci AnalysisHost(isLawfulProt); 2784d6c458bSopenharmony_ci } 2794d6c458bSopenharmony_ci 2804d6c458bSopenharmony_ci void Uri::AnalysisPath(size_t pos) 2814d6c458bSopenharmony_ci { 2824d6c458bSopenharmony_ci std::string path = data_.substr(pos); 2834d6c458bSopenharmony_ci if (!CheckCharacter(path, g_rulePath, true)) { 2844d6c458bSopenharmony_ci errStr_ = "path does not conform to the rule"; 2854d6c458bSopenharmony_ci return; 2864d6c458bSopenharmony_ci } 2874d6c458bSopenharmony_ci uriData_.path = path; 2884d6c458bSopenharmony_ci data_ = data_.substr(0, pos); 2894d6c458bSopenharmony_ci } 2904d6c458bSopenharmony_ci 2914d6c458bSopenharmony_ci void Uri::AnalysisUserInfo(size_t pos) 2924d6c458bSopenharmony_ci { 2934d6c458bSopenharmony_ci std::string userInfo = data_.substr(0, pos); 2944d6c458bSopenharmony_ci if (!CheckCharacter(userInfo, g_ruleUserInfo, true)) { 2954d6c458bSopenharmony_ci errStr_ = "userInfo does not conform to the rule"; 2964d6c458bSopenharmony_ci return; 2974d6c458bSopenharmony_ci } 2984d6c458bSopenharmony_ci uriData_.userInfo = userInfo; 2994d6c458bSopenharmony_ci data_ = data_.substr(pos + 1); 3004d6c458bSopenharmony_ci } 3014d6c458bSopenharmony_ci 3024d6c458bSopenharmony_ci bool Uri::AnalysisPort(size_t pos) 3034d6c458bSopenharmony_ci { 3044d6c458bSopenharmony_ci std::string port = data_.substr(pos + 1); 3054d6c458bSopenharmony_ci if (!CheckCharacter(port, g_rulePort, true)) { 3064d6c458bSopenharmony_ci errStr_ = "port does not conform to the rule"; 3074d6c458bSopenharmony_ci return false; 3084d6c458bSopenharmony_ci } else if (CheckCharacter(port, g_ruleDigit, false)) { 3094d6c458bSopenharmony_ci if (port.size() == 0 || port.size() > 10) { // 10:The maximum number of bits for int value 3104d6c458bSopenharmony_ci return false; 3114d6c458bSopenharmony_ci } 3124d6c458bSopenharmony_ci double tempPort = std::strtod(port.c_str(), nullptr); 3134d6c458bSopenharmony_ci if (tempPort < 0 || tempPort > INT32_MAX) { 3144d6c458bSopenharmony_ci return false; 3154d6c458bSopenharmony_ci } 3164d6c458bSopenharmony_ci uriData_.port = static_cast<int>(tempPort); 3174d6c458bSopenharmony_ci data_ = data_.substr(0, pos); 3184d6c458bSopenharmony_ci return true; 3194d6c458bSopenharmony_ci } else { 3204d6c458bSopenharmony_ci data_ = data_.substr(0, pos); 3214d6c458bSopenharmony_ci return false; 3224d6c458bSopenharmony_ci } 3234d6c458bSopenharmony_ci return false; 3244d6c458bSopenharmony_ci } 3254d6c458bSopenharmony_ci 3264d6c458bSopenharmony_ci bool Uri::AnalysisIPV4() 3274d6c458bSopenharmony_ci { 3284d6c458bSopenharmony_ci std::regex ipv4("((25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]\\d|\\d)\\.){3}(25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]\\d|\\d)"); 3294d6c458bSopenharmony_ci std::regex hostname("(([a-zA-Z0-9]([a-zA-Z0-9\\-~_|\\+{}!$&=,;:'()\\*\\s]*[a-zA-Z0-9])?\\.)+" 3304d6c458bSopenharmony_ci "([a-zA-Z]([a-zA-Z0-9\\-~_|\\+{}!$&=,;:'()\\*\\s]*" 3314d6c458bSopenharmony_ci "[a-zA-Z0-9\\-~_|\\+{}!$&=,;:'()\\*\\s])?))|" 3324d6c458bSopenharmony_ci "([a-zA-Z0-9]([a-zA-Z0-9\\-~_|\\+{}!$&=,;:'()\\*\\s]*[a-zA-Z0-9])?)"); 3334d6c458bSopenharmony_ci bool isIpv4 = std::regex_match(data_, ipv4); 3344d6c458bSopenharmony_ci bool isHosName = std::regex_match(data_, hostname); 3354d6c458bSopenharmony_ci if (!isIpv4 && !isHosName) { 3364d6c458bSopenharmony_ci return false; 3374d6c458bSopenharmony_ci } else { 3384d6c458bSopenharmony_ci uriData_.host = data_; 3394d6c458bSopenharmony_ci data_ = ""; 3404d6c458bSopenharmony_ci return true; 3414d6c458bSopenharmony_ci } 3424d6c458bSopenharmony_ci } 3434d6c458bSopenharmony_ci 3444d6c458bSopenharmony_ci void Uri::AnalysisIPV6() 3454d6c458bSopenharmony_ci { 3464d6c458bSopenharmony_ci std::string str = data_.substr(1, data_.size() - 2); // 2:Intercept the string from the second subscript 3474d6c458bSopenharmony_ci std::regex ipv6("(::|(:((:[0-9A-Fa-f]{1,4}){1,7}))|(([0-9A-Fa-f]{1,4}:){7}([0-9A-Fa-f]{1,4}|:))|" 3484d6c458bSopenharmony_ci "(([0-9A-Fa-f]{1,4}:){1}(((:[0-9A-Fa-f]{1,4}){1,6})|:))|(([0-9A-Fa-f]{1,4}:){2}" 3494d6c458bSopenharmony_ci "(((:[0-9A-Fa-f]{1,4}){1,5})|:))|(([0-9A-Fa-f]{1,4}:){3}(((:[0-9A-Fa-f]{1,4}){1,4})" 3504d6c458bSopenharmony_ci "|:))|(([0-9A-Fa-f]{1,4}:){4}(((:[0-9A-Fa-f]{1,4}){1,3})|:))|(([0-9A-Fa-f]{1,4}:){5}" 3514d6c458bSopenharmony_ci "(((:[0-9A-Fa-f]{1,4}){1,2})|:))|(([0-9A-Fa-f]{1,4}:){6}(:[0-9A-Fa-f]{1,4}|:))|" 3524d6c458bSopenharmony_ci "(((:(:[0-9A-Fa-f]{1,4}){0,5}:)|(([0-9A-Fa-f]{1,4}:){1}(:[0-9A-Fa-f]{1,4}){0,4}:)" 3534d6c458bSopenharmony_ci "|(([0-9A-Fa-f]{1,4}:){2}(:[0-9A-Fa-f]{1,4}){0,3}:)|(([0-9A-Fa-f]{1,4}:){3}" 3544d6c458bSopenharmony_ci "(:[0-9A-Fa-f]{1,4}){0,2}:)|(([0-9A-Fa-f]{1,4}:){4}(:[0-9A-Fa-f]{1,4})?:)|" 3554d6c458bSopenharmony_ci "(([0-9A-Fa-f]{1,4}:){5}:)|(([0-9A-Fa-f]{1,4}:){6}))((25[0-5]|2[0-4]\\d|1\\d{2}|" 3564d6c458bSopenharmony_ci "[1-9]\\d|\\d)\\.){3}(25[0-5]|2[0-4]\\d|1\\d{2}|[1-9]\\d|\\d)))(%[a-zA-Z0-9._]+)?"); 3574d6c458bSopenharmony_ci if (!std::regex_match(str, ipv6)) { 3584d6c458bSopenharmony_ci errStr_ = "ipv6 does not conform to the rule"; 3594d6c458bSopenharmony_ci return; 3604d6c458bSopenharmony_ci } 3614d6c458bSopenharmony_ci uriData_.host = data_; 3624d6c458bSopenharmony_ci data_ = ""; 3634d6c458bSopenharmony_ci } 3644d6c458bSopenharmony_ci 3654d6c458bSopenharmony_ci bool Uri::Equals(const Uri other) const 3664d6c458bSopenharmony_ci { 3674d6c458bSopenharmony_ci if (uriData_.port != other.uriData_.port) { 3684d6c458bSopenharmony_ci return false; 3694d6c458bSopenharmony_ci } 3704d6c458bSopenharmony_ci if (uriData_.scheme != other.uriData_.scheme) { 3714d6c458bSopenharmony_ci return false; 3724d6c458bSopenharmony_ci } 3734d6c458bSopenharmony_ci if (uriData_.userInfo != other.uriData_.userInfo) { 3744d6c458bSopenharmony_ci return false; 3754d6c458bSopenharmony_ci } 3764d6c458bSopenharmony_ci if (uriData_.host != other.uriData_.host) { 3774d6c458bSopenharmony_ci return false; 3784d6c458bSopenharmony_ci } 3794d6c458bSopenharmony_ci if (uriData_.query != other.uriData_.query) { 3804d6c458bSopenharmony_ci return false; 3814d6c458bSopenharmony_ci } 3824d6c458bSopenharmony_ci if (uriData_.fragment != other.uriData_.fragment) { 3834d6c458bSopenharmony_ci return false; 3844d6c458bSopenharmony_ci } 3854d6c458bSopenharmony_ci if (uriData_.path != other.uriData_.path) { 3864d6c458bSopenharmony_ci return false; 3874d6c458bSopenharmony_ci } 3884d6c458bSopenharmony_ci if (uriData_.authority != other.uriData_.authority) { 3894d6c458bSopenharmony_ci return false; 3904d6c458bSopenharmony_ci } 3914d6c458bSopenharmony_ci if (uriData_.SchemeSpecificPart != other.uriData_.SchemeSpecificPart) { 3924d6c458bSopenharmony_ci return false; 3934d6c458bSopenharmony_ci } 3944d6c458bSopenharmony_ci return true; 3954d6c458bSopenharmony_ci } 3964d6c458bSopenharmony_ci 3974d6c458bSopenharmony_ci std::string Uri::ToString() const 3984d6c458bSopenharmony_ci { 3994d6c458bSopenharmony_ci return inputUri_; 4004d6c458bSopenharmony_ci } 4014d6c458bSopenharmony_ci 4024d6c458bSopenharmony_ci bool Uri::IsAbsolute() const 4034d6c458bSopenharmony_ci { 4044d6c458bSopenharmony_ci return !uriData_.scheme.empty(); 4054d6c458bSopenharmony_ci } 4064d6c458bSopenharmony_ci 4074d6c458bSopenharmony_ci bool Uri::IsRelative() const 4084d6c458bSopenharmony_ci { 4094d6c458bSopenharmony_ci return uriData_.scheme.empty(); 4104d6c458bSopenharmony_ci } 4114d6c458bSopenharmony_ci 4124d6c458bSopenharmony_ci bool Uri::IsOpaque() const 4134d6c458bSopenharmony_ci { 4144d6c458bSopenharmony_ci return !IsHierarchical(); 4154d6c458bSopenharmony_ci } 4164d6c458bSopenharmony_ci 4174d6c458bSopenharmony_ci bool Uri::IsHierarchical() const 4184d6c458bSopenharmony_ci { 4194d6c458bSopenharmony_ci size_t index = inputUri_.find(':'); 4204d6c458bSopenharmony_ci if (index == std::string::npos) { 4214d6c458bSopenharmony_ci return true; 4224d6c458bSopenharmony_ci } 4234d6c458bSopenharmony_ci if (inputUri_.length() == index + 1) { 4244d6c458bSopenharmony_ci return false; 4254d6c458bSopenharmony_ci } 4264d6c458bSopenharmony_ci return inputUri_[index + 1] == '/'; 4274d6c458bSopenharmony_ci } 4284d6c458bSopenharmony_ci 4294d6c458bSopenharmony_ci std::string Uri::AddQueryValue(const std::string key, const std::string value) const 4304d6c458bSopenharmony_ci { 4314d6c458bSopenharmony_ci return BuildUriString("query", key + "=" + value); 4324d6c458bSopenharmony_ci } 4334d6c458bSopenharmony_ci 4344d6c458bSopenharmony_ci std::string Uri::AddSegment(const std::string pathSegment) const 4354d6c458bSopenharmony_ci { 4364d6c458bSopenharmony_ci return BuildUriString("segment", pathSegment); 4374d6c458bSopenharmony_ci } 4384d6c458bSopenharmony_ci 4394d6c458bSopenharmony_ci std::string Uri::BuildUriString(const std::string str, const std::string param) const 4404d6c458bSopenharmony_ci { 4414d6c458bSopenharmony_ci std::string result = ""; 4424d6c458bSopenharmony_ci if (!uriData_.scheme.empty()) { 4434d6c458bSopenharmony_ci result += uriData_.scheme + ":"; 4444d6c458bSopenharmony_ci } 4454d6c458bSopenharmony_ci if (!uriData_.authority.empty()) { 4464d6c458bSopenharmony_ci result += "//" + uriData_.authority; 4474d6c458bSopenharmony_ci } 4484d6c458bSopenharmony_ci if (!uriData_.path.empty()) { 4494d6c458bSopenharmony_ci result += uriData_.path ; 4504d6c458bSopenharmony_ci } 4514d6c458bSopenharmony_ci if (str == "segment") { 4524d6c458bSopenharmony_ci if (result.back() == '/') { 4534d6c458bSopenharmony_ci result += param; 4544d6c458bSopenharmony_ci } else { 4554d6c458bSopenharmony_ci result += "/" + param; 4564d6c458bSopenharmony_ci } 4574d6c458bSopenharmony_ci } 4584d6c458bSopenharmony_ci if (str != "clearquery") { 4594d6c458bSopenharmony_ci if (uriData_.query.empty()) { 4604d6c458bSopenharmony_ci if (str == "query") { 4614d6c458bSopenharmony_ci result += "?" + param; 4624d6c458bSopenharmony_ci } 4634d6c458bSopenharmony_ci } else { 4644d6c458bSopenharmony_ci result += "?" + uriData_.query; 4654d6c458bSopenharmony_ci if (str == "query") { 4664d6c458bSopenharmony_ci result += "&" + param; 4674d6c458bSopenharmony_ci } 4684d6c458bSopenharmony_ci } 4694d6c458bSopenharmony_ci } 4704d6c458bSopenharmony_ci if (!uriData_.fragment.empty()) { 4714d6c458bSopenharmony_ci result += "#" + uriData_.fragment; 4724d6c458bSopenharmony_ci } 4734d6c458bSopenharmony_ci return result; 4744d6c458bSopenharmony_ci } 4754d6c458bSopenharmony_ci 4764d6c458bSopenharmony_ci std::vector<std::string> Uri::GetSegment() const 4774d6c458bSopenharmony_ci { 4784d6c458bSopenharmony_ci std::vector<std::string> segments; 4794d6c458bSopenharmony_ci if (uriData_.path.empty()) { 4804d6c458bSopenharmony_ci return segments; 4814d6c458bSopenharmony_ci } 4824d6c458bSopenharmony_ci size_t previous = 0; 4834d6c458bSopenharmony_ci size_t current = 0; 4844d6c458bSopenharmony_ci for (current = uriData_.path.find('/', previous); current != std::string::npos; 4854d6c458bSopenharmony_ci current = uriData_.path.find('/', previous)) { 4864d6c458bSopenharmony_ci if (previous < current) { 4874d6c458bSopenharmony_ci std::string segment = uriData_.path.substr(previous, current - previous); 4884d6c458bSopenharmony_ci segments.push_back(segment); 4894d6c458bSopenharmony_ci } 4904d6c458bSopenharmony_ci previous = current + 1; 4914d6c458bSopenharmony_ci } 4924d6c458bSopenharmony_ci if (previous < uriData_.path.length()) { 4934d6c458bSopenharmony_ci segments.push_back(uriData_.path.substr(previous)); 4944d6c458bSopenharmony_ci } 4954d6c458bSopenharmony_ci return segments; 4964d6c458bSopenharmony_ci } 4974d6c458bSopenharmony_ci 4984d6c458bSopenharmony_ci std::string Uri::IsFailed() const 4994d6c458bSopenharmony_ci { 5004d6c458bSopenharmony_ci return errStr_; 5014d6c458bSopenharmony_ci } 5024d6c458bSopenharmony_ci 5034d6c458bSopenharmony_ci std::string Uri::Normalize() const 5044d6c458bSopenharmony_ci { 5054d6c458bSopenharmony_ci std::vector<std::string> temp; 5064d6c458bSopenharmony_ci size_t pathLen = uriData_.path.size(); 5074d6c458bSopenharmony_ci if (pathLen == 0) { 5084d6c458bSopenharmony_ci return this->inputUri_; 5094d6c458bSopenharmony_ci } 5104d6c458bSopenharmony_ci size_t pos = 0; 5114d6c458bSopenharmony_ci size_t left = 0; 5124d6c458bSopenharmony_ci while ((pos = uriData_.path.find('/', left)) != std::string::npos) { 5134d6c458bSopenharmony_ci temp.push_back(uriData_.path.substr(left, pos - left)); 5144d6c458bSopenharmony_ci left = pos + 1; 5154d6c458bSopenharmony_ci } 5164d6c458bSopenharmony_ci if (left != pathLen) { 5174d6c458bSopenharmony_ci temp.push_back(uriData_.path.substr(left)); 5184d6c458bSopenharmony_ci } 5194d6c458bSopenharmony_ci size_t tempLen = temp.size(); 5204d6c458bSopenharmony_ci std::vector<std::string> normalizeTemp; 5214d6c458bSopenharmony_ci for (size_t i = 0; i < tempLen; ++i) { 5224d6c458bSopenharmony_ci if (!temp[i].empty() && !(temp[i] == ".") && !(temp[i] == "..")) { 5234d6c458bSopenharmony_ci normalizeTemp.push_back(temp[i]); 5244d6c458bSopenharmony_ci } 5254d6c458bSopenharmony_ci if (temp[i] == "..") { 5264d6c458bSopenharmony_ci if (!normalizeTemp.empty() && normalizeTemp.back() != "..") { 5274d6c458bSopenharmony_ci normalizeTemp.pop_back(); 5284d6c458bSopenharmony_ci } else { 5294d6c458bSopenharmony_ci normalizeTemp.push_back(temp[i]); 5304d6c458bSopenharmony_ci } 5314d6c458bSopenharmony_ci } 5324d6c458bSopenharmony_ci } 5334d6c458bSopenharmony_ci std::string normalizePath = ""; 5344d6c458bSopenharmony_ci tempLen = normalizeTemp.size(); 5354d6c458bSopenharmony_ci if (tempLen == 0) { 5364d6c458bSopenharmony_ci normalizePath = "/"; 5374d6c458bSopenharmony_ci } else { 5384d6c458bSopenharmony_ci for (size_t i = 0; i < tempLen; ++i) { 5394d6c458bSopenharmony_ci normalizePath += "/" + normalizeTemp[i]; 5404d6c458bSopenharmony_ci } 5414d6c458bSopenharmony_ci } 5424d6c458bSopenharmony_ci return Split(normalizePath); 5434d6c458bSopenharmony_ci } 5444d6c458bSopenharmony_ci 5454d6c458bSopenharmony_ci 5464d6c458bSopenharmony_ci std::string Uri::Split(const std::string &path) const 5474d6c458bSopenharmony_ci { 5484d6c458bSopenharmony_ci std::string normalizeUri = ""; 5494d6c458bSopenharmony_ci if (!uriData_.scheme.empty()) { 5504d6c458bSopenharmony_ci normalizeUri += uriData_.scheme + ":"; 5514d6c458bSopenharmony_ci } 5524d6c458bSopenharmony_ci if (uriData_.path.empty()) { 5534d6c458bSopenharmony_ci normalizeUri += uriData_.SchemeSpecificPart; 5544d6c458bSopenharmony_ci } else { 5554d6c458bSopenharmony_ci if (!uriData_.host.empty()) { 5564d6c458bSopenharmony_ci normalizeUri += "//"; 5574d6c458bSopenharmony_ci if (!uriData_.userInfo.empty()) { 5584d6c458bSopenharmony_ci normalizeUri += uriData_.userInfo + "@"; 5594d6c458bSopenharmony_ci } 5604d6c458bSopenharmony_ci normalizeUri += uriData_.host; 5614d6c458bSopenharmony_ci if (uriData_.port != -1) { 5624d6c458bSopenharmony_ci normalizeUri += ":" + std::to_string(uriData_.port); 5634d6c458bSopenharmony_ci } 5644d6c458bSopenharmony_ci } else if (!uriData_.authority.empty()) { 5654d6c458bSopenharmony_ci normalizeUri += "//" + uriData_.authority; 5664d6c458bSopenharmony_ci } 5674d6c458bSopenharmony_ci normalizeUri += path; 5684d6c458bSopenharmony_ci } 5694d6c458bSopenharmony_ci if (!uriData_.query.empty()) { 5704d6c458bSopenharmony_ci normalizeUri += "?" + uriData_.query; 5714d6c458bSopenharmony_ci } 5724d6c458bSopenharmony_ci if (!uriData_.fragment.empty()) { 5734d6c458bSopenharmony_ci normalizeUri += "#" + uriData_.fragment; 5744d6c458bSopenharmony_ci } 5754d6c458bSopenharmony_ci return normalizeUri; 5764d6c458bSopenharmony_ci } 5774d6c458bSopenharmony_ci 5784d6c458bSopenharmony_ci std::string Uri::GetScheme() const 5794d6c458bSopenharmony_ci { 5804d6c458bSopenharmony_ci return uriData_.scheme; 5814d6c458bSopenharmony_ci } 5824d6c458bSopenharmony_ci 5834d6c458bSopenharmony_ci std::string Uri::GetAuthority() const 5844d6c458bSopenharmony_ci { 5854d6c458bSopenharmony_ci return uriData_.authority; 5864d6c458bSopenharmony_ci } 5874d6c458bSopenharmony_ci 5884d6c458bSopenharmony_ci std::string Uri::GetSsp() const 5894d6c458bSopenharmony_ci { 5904d6c458bSopenharmony_ci return uriData_.SchemeSpecificPart; 5914d6c458bSopenharmony_ci } 5924d6c458bSopenharmony_ci 5934d6c458bSopenharmony_ci std::string Uri::GetUserinfo() const 5944d6c458bSopenharmony_ci { 5954d6c458bSopenharmony_ci return uriData_.userInfo; 5964d6c458bSopenharmony_ci } 5974d6c458bSopenharmony_ci 5984d6c458bSopenharmony_ci std::string Uri::GetHost() const 5994d6c458bSopenharmony_ci { 6004d6c458bSopenharmony_ci return uriData_.host; 6014d6c458bSopenharmony_ci } 6024d6c458bSopenharmony_ci 6034d6c458bSopenharmony_ci std::string Uri::GetPort() const 6044d6c458bSopenharmony_ci { 6054d6c458bSopenharmony_ci return std::to_string(uriData_.port); 6064d6c458bSopenharmony_ci } 6074d6c458bSopenharmony_ci 6084d6c458bSopenharmony_ci std::string Uri::GetPath() const 6094d6c458bSopenharmony_ci { 6104d6c458bSopenharmony_ci return uriData_.path; 6114d6c458bSopenharmony_ci } 6124d6c458bSopenharmony_ci 6134d6c458bSopenharmony_ci std::string Uri::GetQuery() const 6144d6c458bSopenharmony_ci { 6154d6c458bSopenharmony_ci return uriData_.query; 6164d6c458bSopenharmony_ci } 6174d6c458bSopenharmony_ci 6184d6c458bSopenharmony_ci std::string Uri::GetFragment() const 6194d6c458bSopenharmony_ci { 6204d6c458bSopenharmony_ci return uriData_.fragment; 6214d6c458bSopenharmony_ci } 6224d6c458bSopenharmony_ci 6234d6c458bSopenharmony_ci std::string Uri::ClearQuery() const 6244d6c458bSopenharmony_ci { 6254d6c458bSopenharmony_ci return BuildUriString("clearquery", ""); 6264d6c458bSopenharmony_ci } 6274d6c458bSopenharmony_ci} // namespace OHOS::Uri 628