123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177 |
- // Copyright 2020 The Chromium Authors. All rights reserved.
- // Use of this source code is governed by a BSD-style license that can be
- // found in the LICENSE file.
- #include "net/base/schemeful_site.h"
- #include "base/check.h"
- #include "base/metrics/histogram_macros.h"
- #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
- #include "net/base/url_util.h"
- #include "url/gurl.h"
- #include "url/url_canon.h"
- #include "url/url_constants.h"
- namespace net {
- // Return a tuple containing:
- // * a new origin using the registerable domain of `origin` if possible and
- // a port of 0; otherwise, the passed-in origin.
- // * a bool indicating whether `origin` had a non-null registerable domain.
- // (False if `origin` was opaque.)
- //
- // Follows steps specified in
- // https://html.spec.whatwg.org/multipage/origin.html#obtain-a-site
- SchemefulSite::ObtainASiteResult SchemefulSite::ObtainASite(
- const url::Origin& origin) {
- // 1. If origin is an opaque origin, then return origin.
- if (origin.opaque())
- return {origin, false /* used_registerable_domain */};
- std::string registerable_domain;
- // Non-normative step.
- // We only lookup the registerable domain for schemes with network hosts, this
- // is non-normative. Other schemes for non-opaque origins do not
- // meaningfully have a registerable domain for their host, so they are
- // skipped.
- if (IsStandardSchemeWithNetworkHost(origin.scheme())) {
- registerable_domain = GetDomainAndRegistry(
- origin, net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES);
- }
- // If origin's host's registrable domain is null, then return (origin's
- // scheme, origin's host).
- //
- // `GetDomainAndRegistry()` returns an empty string for IP literals and
- // effective TLDs.
- //
- // Note that `registerable_domain` could still end up empty, since the
- // `origin` might have a scheme that permits empty hostnames, such as "file".
- bool used_registerable_domain = !registerable_domain.empty();
- if (!used_registerable_domain)
- registerable_domain = origin.host();
- int port = url::DefaultPortForScheme(origin.scheme().c_str(),
- origin.scheme().length());
- // Provide a default port of 0 for non-standard schemes.
- if (port == url::PORT_UNSPECIFIED)
- port = 0;
- return {url::Origin::CreateFromNormalizedTuple(origin.scheme(),
- registerable_domain, port),
- used_registerable_domain};
- }
- SchemefulSite::SchemefulSite(ObtainASiteResult result)
- : site_as_origin_(std::move(result.origin)) {}
- SchemefulSite::SchemefulSite(const url::Origin& origin)
- : SchemefulSite(ObtainASite(origin)) {}
- SchemefulSite::SchemefulSite(const GURL& url)
- : SchemefulSite(url::Origin::Create(url)) {}
- SchemefulSite::SchemefulSite(const SchemefulSite& other) = default;
- SchemefulSite::SchemefulSite(SchemefulSite&& other) noexcept = default;
- SchemefulSite& SchemefulSite::operator=(const SchemefulSite& other) = default;
- SchemefulSite& SchemefulSite::operator=(SchemefulSite&& other) noexcept =
- default;
- // static
- bool SchemefulSite::FromWire(const url::Origin& site_as_origin,
- SchemefulSite* out) {
- // The origin passed into this constructor may not match the
- // `site_as_origin_` used as the internal representation of the schemeful
- // site. However, a valid SchemefulSite's internal origin should result in a
- // match if used to construct another SchemefulSite. Thus, if there is a
- // mismatch here, we must indicate a failure.
- SchemefulSite candidate(site_as_origin);
- if (candidate.site_as_origin_ != site_as_origin)
- return false;
- *out = std::move(candidate);
- return true;
- }
- absl::optional<SchemefulSite> SchemefulSite::CreateIfHasRegisterableDomain(
- const url::Origin& origin) {
- ObtainASiteResult result = ObtainASite(origin);
- if (!result.used_registerable_domain)
- return absl::nullopt;
- return SchemefulSite(std::move(result));
- }
- void SchemefulSite::ConvertWebSocketToHttp() {
- if (site_as_origin_.scheme() == url::kWsScheme ||
- site_as_origin_.scheme() == url::kWssScheme) {
- site_as_origin_ = url::Origin::Create(
- ChangeWebSocketSchemeToHttpScheme(site_as_origin_.GetURL()));
- }
- }
- // static
- SchemefulSite SchemefulSite::Deserialize(const std::string& value) {
- return SchemefulSite(GURL(value));
- }
- std::string SchemefulSite::Serialize() const {
- return site_as_origin_.Serialize();
- }
- std::string SchemefulSite::SerializeFileSiteWithHost() const {
- DCHECK_EQ(url::kFileScheme, site_as_origin_.scheme());
- return site_as_origin_.GetTupleOrPrecursorTupleIfOpaque().Serialize();
- }
- std::string SchemefulSite::GetDebugString() const {
- return site_as_origin_.GetDebugString();
- }
- GURL SchemefulSite::GetURL() const {
- return site_as_origin_.GetURL();
- }
- const url::Origin& SchemefulSite::GetInternalOriginForTesting() const {
- return site_as_origin_;
- }
- bool SchemefulSite::operator==(const SchemefulSite& other) const {
- return site_as_origin_ == other.site_as_origin_;
- }
- bool SchemefulSite::operator!=(const SchemefulSite& other) const {
- return !(*this == other);
- }
- // Allows SchemefulSite to be used as a key in STL containers (for example, a
- // std::set or std::map).
- bool SchemefulSite::operator<(const SchemefulSite& other) const {
- return site_as_origin_ < other.site_as_origin_;
- }
- // static
- absl::optional<SchemefulSite> SchemefulSite::DeserializeWithNonce(
- const std::string& value) {
- absl::optional<url::Origin> result = url::Origin::Deserialize(value);
- if (!result)
- return absl::nullopt;
- return SchemefulSite(result.value());
- }
- absl::optional<std::string> SchemefulSite::SerializeWithNonce() {
- return site_as_origin_.SerializeWithNonceAndInitIfNeeded();
- }
- bool SchemefulSite::SchemelesslyEqual(const SchemefulSite& other) const {
- return site_as_origin_.host() == other.site_as_origin_.host();
- }
- std::ostream& operator<<(std::ostream& os, const SchemefulSite& ss) {
- os << ss.Serialize();
- return os;
- }
- } // namespace net
|