void URL::from_string()

in net/http/url.cpp [36:96]


void URL::from_string(std::string_view url) {
    DEFER(fix_target(););
    if (m_tmp_target) {
        free((void*)m_tmp_target);
        m_tmp_target = nullptr;
    }
    m_url = url.begin();
    size_t pos = 0;
    LOG_DEBUG(VALUE(url));
    m_secure = ((estring_view&) (url)).starts_with(https_url_scheme);
    // hashtag should be dropped, since it is pure client-side mark
    url = url.substr(0, url.find_first_of('#'));
    auto p = url.find("://");
    if (p != url.npos) {
        pos += p + 3;
        url.remove_prefix(p + 3);
    }
    p = url.find_first_of(":/?");
    if (p == url.npos) p = url.size();
    m_host = rstring_view16(pos, p);
    m_host_port = m_host;
    pos += p;
    url.remove_prefix(p);
    if (url.empty()) {
        m_port = m_secure ? 443 : 80;
        m_path = rstring_view16(pos, 0);
        m_query = rstring_view16(0, 0);
        m_target = m_path;
        return;
    }
    if (url.front() == ':') {
        char* endp;
        auto port = strtol(url.begin() + 1, &endp, 10);
        auto port_len= endp - url.begin();
        if (endp != url.begin() + 1) {
            m_port = port;
            if (need_optional_port(*this)) m_host_port = rstring_view16(m_host.offset(), m_host.length() + port_len);
        }
        pos += port_len;
        url.remove_prefix(endp - url.begin());
    } else {
        m_port = m_secure ? 443 : 80;
    }
    if (url.empty()) {
        m_path = rstring_view16(pos, 0);
        m_query = rstring_view16(0, 0);
        m_target = m_path;
        return;
    }
    p = url.find_first_of("?");
    if (p == url.npos) {
        m_path = rstring_view16(pos, url.size());
        m_query = rstring_view16(0, 0);
        m_target = m_path;
        return;
    }
    m_path = rstring_view16(pos, p);
    m_target = rstring_view16(pos, url.size());
    pos += p+1;
    m_query = rstring_view16(pos, url.size() - (p + 1));
}