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