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;
}