#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 {
SchemefulSite::ObtainASiteResult SchemefulSite::ObtainASite(
const url::Origin& origin) {
if (origin.opaque())
return {origin, false };
std::string registerable_domain;
if (IsStandardSchemeWithNetworkHost(origin.scheme())) {
registerable_domain = GetDomainAndRegistry(
origin, net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES);
}
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());
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;
bool SchemefulSite::FromWire(const url::Origin& site_as_origin,
SchemefulSite* out) {
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()));
}
}
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);
}
bool SchemefulSite::operator<(const SchemefulSite& other) const {
return site_as_origin_ < other.site_as_origin_;
}
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;
}
}