bool Uri::ParseHost()

in Source/Common/uri.cpp [521:595]


bool Uri::ParseHost(String const& uri, String::const_iterator& it)
{
    if (it == uri.end())
    {
        HC_TRACE_WARNING(HTTPCLIENT, "Missing host in URI."); // no tracing uris they could contain PII
        return false;
    }

    // extract host.
    // either a host string
    // an IPv4 address
    // or an IPv6 address
    // or IPvFuture address (not supported)
    if (*it == '[')
    {
        ++it; // consume the '['
              // IPv6 literal
              // extract IPv6 digits until ']'
        auto hostEnd = std::find(it, uri.end(), ']');

        if (hostEnd == uri.end())
        {
            HC_TRACE_WARNING(HTTPCLIENT, "Cannot parse IPv6 literal."); // no tracing uris they could contain PII
            return false;
        }
        else if (*it == 'v' || *it == 'V')
        {
            HC_TRACE_WARNING(HTTPCLIENT, "IPvFuture literal not supported."); // no tracing uris they could contain PII
            return false;
        }
        else
        {
            // Validate the IPv6 address
            for (auto tempIt = it; tempIt != hostEnd; ++tempIt)
            {
                if (*tempIt != ':' && !IsHexChar(*tempIt))
                {
                    HC_TRACE_WARNING(HTTPCLIENT, "Invalid character found in IPv6 literal."); // no tracing uris they could contain PII
                    return false;
                }
            }

            m_host.assign(it, hostEnd);
        }

        it = hostEnd + 1; // consume the ']'
    }
    else
    {
        // IPv4 or registered name
        // extract until : or / or ? or #
        String::const_iterator hostEnd = it;
        for (; hostEnd != uri.end() && *hostEnd != ':' && *hostEnd != '/' && *hostEnd != '?' && *hostEnd != '#'; ++hostEnd)
        {
            if (!IsRegNameCharacter(*hostEnd))
            {
                HC_TRACE_WARNING(HTTPCLIENT, "Invalid character found in host."); // no tracing uris they could contain PII
                return false;
            }
        }

        m_host.assign(it, hostEnd);
        it = hostEnd;
        if (m_host.empty())
        {
            HC_TRACE_WARNING(HTTPCLIENT, "Empty host name in URI."); // no tracing uris they could contain PII
            return false;
        }
    }

    // Canonicalize the host by lowercasing it
    BasicAsciiLowercase(m_host);

    return true;
}