void aws::iot::securedtunneling::url::parse()

in src/Url.cpp [19:79]


void aws::iot::securedtunneling::url::parse(const string& url_s)
{
    auto get_substring = [](const string& s, const size_t& start, const size_t& end) {
        return s.substr(start, end - start );
    };

    // parse protocol
    const string protocol_end("://");
    const size_t protocol_end_i = url_s.find(protocol_end);
    if (protocol_end_i == string::npos) {
        BOOST_LOG_TRIVIAL(debug) << "No protocol is provided in the URL, assuming the default protocol: http.";
        protocol = "http";
    } else {
        BOOST_LOG_TRIVIAL(trace) << "Extracting protocol";
        protocol = get_substring(url_s, 0, protocol_end_i);
        if (protocol.empty()) {
            throw invalid_argument("Invalid URL, missing protocol");
        }
        transform(protocol.begin(), protocol.end(), protocol.begin(), ::tolower);
        BOOST_LOG_TRIVIAL(info) << "Parsed URL protocol";
    }

    // parse authentication
    const size_t authentication_end_i = url_s.find_last_of('@');
    const bool is_authN_included = authentication_end_i != string::npos;
    if (is_authN_included) {
        authentication = aws::iot::securedtunneling::url::url_decode(
                get_substring(url_s, protocol_end_i + protocol_end.size(), authentication_end_i)
        );
        if (authentication.empty())
            throw invalid_argument("Empty authentication, if you don't need to authentication information, remove `@`");
        if (authentication.find(':') == string::npos)
            throw invalid_argument("Missing the colon between the username and password in URL.");
        if (authentication.length() < 3)
            throw invalid_argument("Invalid authentication format, missing either username or password.");
        BOOST_LOG_TRIVIAL(debug) << "Parsed basic auth credentials for the URL";
    } else {
        BOOST_LOG_TRIVIAL(debug) << "No authentication is found in the URL, assuming no authentication is required.";
    }

    // parse the host and port
    const size_t host_i = is_authN_included ? authentication_end_i + 1 : protocol_end_i + protocol_end.size();
    const size_t port_i = url_s.find(':', host_i);

    host = get_substring(url_s, host_i, port_i);

    if (host.empty()) {
        throw invalid_argument("Missing HTTP host address");
    }
    transform(host.begin(), host.end(), host.begin(), ::tolower);
    if (port_i != string::npos) {
        const string port_s = get_substring(url_s, port_i + 1, url_s.length());
        try {
            port = static_cast<uint16_t>(stoi(port_s));
        } catch (exception &e) {
            BOOST_LOG_TRIVIAL(fatal) << "Failed to parse the port";
            BOOST_LOG_TRIVIAL(fatal) << e.what();
            throw invalid_argument(e.what());
        }
    }
}