Move QuicheHostnameUtils implementation out of the platform.
Those are part of the platform API because they depend on net/base/url_util.h. We already have half of that code copied into impl.cc file; copy the rest and move it out of platform impl directory.
(this does not actually move the file out of platform, that will be done in a follow-up CL)
PiperOrigin-RevId: 438377608
diff --git a/common/platform/api/quiche_hostname_utils.cc b/common/platform/api/quiche_hostname_utils.cc
index 57fa53c..0513cb9 100644
--- a/common/platform/api/quiche_hostname_utils.cc
+++ b/common/platform/api/quiche_hostname_utils.cc
@@ -4,18 +4,106 @@
#include "common/platform/api/quiche_hostname_utils.h"
+#include <string>
+
#include "absl/strings/string_view.h"
+#include "url/url_canon.h"
+#include "url/url_canon_stdstring.h"
+#include "common/platform/api/quiche_logging.h"
namespace quiche {
+// TODO(vasilvv): the functions below are forked from Chromium's
+// net/base/url_util.h; those should be moved to googleurl.
+namespace {
+
+std::string CanonicalizeHost(absl::string_view host,
+ url::CanonHostInfo* host_info) {
+ // Try to canonicalize the host.
+ const url::Component raw_host_component(0, static_cast<int>(host.length()));
+ std::string canon_host;
+ url::StdStringCanonOutput canon_host_output(&canon_host);
+ url::CanonicalizeHostVerbose(host.data(), raw_host_component,
+ &canon_host_output, host_info);
+
+ if (host_info->out_host.is_nonempty() &&
+ host_info->family != url::CanonHostInfo::BROKEN) {
+ // Success! Assert that there's no extra garbage.
+ canon_host_output.Complete();
+ QUICHE_DCHECK_EQ(host_info->out_host.len,
+ static_cast<int>(canon_host.length()));
+ } else {
+ // Empty host, or canonicalization failed. We'll return empty.
+ canon_host.clear();
+ }
+
+ return canon_host;
+}
+
+bool IsHostCharAlphanumeric(char c) {
+ // We can just check lowercase because uppercase characters have already been
+ // normalized.
+ return ((c >= 'a') && (c <= 'z')) || ((c >= '0') && (c <= '9'));
+}
+
+bool IsCanonicalizedHostCompliant(const std::string& host) {
+ if (host.empty()) {
+ return false;
+ }
+
+ bool in_component = false;
+ bool most_recent_component_started_alphanumeric = false;
+
+ for (char c : host) {
+ if (!in_component) {
+ most_recent_component_started_alphanumeric = IsHostCharAlphanumeric(c);
+ if (!most_recent_component_started_alphanumeric && (c != '-') &&
+ (c != '_')) {
+ return false;
+ }
+ in_component = true;
+ } else if (c == '.') {
+ in_component = false;
+ } else if (!IsHostCharAlphanumeric(c) && (c != '-') && (c != '_')) {
+ return false;
+ }
+ }
+
+ return most_recent_component_started_alphanumeric;
+}
+
+} // namespace
+
// static
bool QuicheHostnameUtils::IsValidSNI(absl::string_view sni) {
- return QuicheHostnameUtilsImpl::IsValidSNI(sni);
+ // TODO(rtenneti): Support RFC2396 hostname.
+ // NOTE: Microsoft does NOT enforce this spec, so if we throw away hostnames
+ // based on the above spec, we may be losing some hostnames that windows
+ // would consider valid. By far the most common hostname character NOT
+ // accepted by the above spec is '_'.
+ url::CanonHostInfo host_info;
+ std::string canonicalized_host = CanonicalizeHost(sni, &host_info);
+ return !host_info.IsIPAddress() &&
+ IsCanonicalizedHostCompliant(canonicalized_host);
}
// static
std::string QuicheHostnameUtils::NormalizeHostname(absl::string_view hostname) {
- return QuicheHostnameUtilsImpl::NormalizeHostname(hostname);
+ url::CanonHostInfo host_info;
+ std::string host = CanonicalizeHost(hostname, &host_info);
+
+ // Walk backwards over the string, stopping at the first trailing dot.
+ size_t host_end = host.length();
+ while (host_end != 0 && host[host_end - 1] == '.') {
+ host_end--;
+ }
+
+ // Erase the trailing dots.
+ if (host_end != host.length()) {
+ host.erase(host_end, host.length() - host_end);
+ }
+
+ return host;
}
} // namespace quiche
diff --git a/common/platform/api/quiche_hostname_utils.h b/common/platform/api/quiche_hostname_utils.h
index a8a4acf..b9e0fb9 100644
--- a/common/platform/api/quiche_hostname_utils.h
+++ b/common/platform/api/quiche_hostname_utils.h
@@ -7,7 +7,6 @@
#include <string>
-#include "quiche_platform_impl/quiche_hostname_utils_impl.h"
#include "absl/strings/string_view.h"
#include "common/platform/api/quiche_export.h"