blob: 3736f566ec2f934129e08762ebbb679edb66e162 [file] [log] [blame]
// Copyright 2019 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.
#ifndef NET_BASE_NETWORK_ISOLATION_KEY_H_
#define NET_BASE_NETWORK_ISOLATION_KEY_H_
#include <string>
#include "base/gtest_prod_util.h"
#include "base/macros.h"
#include "base/optional.h"
#include "base/values.h"
#include "net/base/net_export.h"
#include "net/base/schemeful_site.h"
namespace network {
namespace mojom {
class NetworkIsolationKeyDataView;
} // namespace mojom
} // namespace network
namespace mojo {
template <typename DataViewType, typename T>
struct StructTraits;
} // namespace mojo
namespace url {
class Origin;
}
namespace net {
// Key used to isolate shared network stack resources used by requests based on
// the context on which they were made.
class NET_EXPORT NetworkIsolationKey {
public:
// Full constructor. When a request is initiated by the top frame, it must
// also populate the |frame_site| parameter when calling this constructor.
NetworkIsolationKey(const SchemefulSite& top_frame_site,
const SchemefulSite& frame_site);
// Alternative constructor that takes ownership of arguments, to save copies.
NetworkIsolationKey(SchemefulSite&& top_frame_site,
SchemefulSite&& frame_site);
// Legacy constructor.
// TODO(https://crbug.com/1145294): Remove this in favor of above
// constructor.
NetworkIsolationKey(const url::Origin& top_frame_origin,
const url::Origin& frame_origin);
// Construct an empty key.
NetworkIsolationKey();
NetworkIsolationKey(const NetworkIsolationKey& network_isolation_key);
NetworkIsolationKey(NetworkIsolationKey&& network_isolation_key);
~NetworkIsolationKey();
NetworkIsolationKey& operator=(
const NetworkIsolationKey& network_isolation_key);
NetworkIsolationKey& operator=(NetworkIsolationKey&& network_isolation_key);
// Creates a transient non-empty NetworkIsolationKey by creating an opaque
// origin. This prevents the NetworkIsolationKey from sharing data with other
// NetworkIsolationKeys. Data for transient NetworkIsolationKeys is not
// persisted to disk.
static NetworkIsolationKey CreateTransient();
// Creates a non-empty NetworkIsolationKey with an opaque origin that is not
// considered transient. The returned NetworkIsolationKey will be cross-origin
// with all other keys and associated data is able to be persisted to disk.
static NetworkIsolationKey CreateOpaqueAndNonTransient();
// Creates a new key using |top_frame_site_| and |new_frame_site|.
NetworkIsolationKey CreateWithNewFrameSite(
const SchemefulSite& new_frame_site) const;
// Creates a new key using |top_frame_site_| and |new_frame_origin|.
// TODO(https://crbug.com/1145294): Remove this in favor of above method.
NetworkIsolationKey CreateWithNewFrameOrigin(
const url::Origin& new_frame_origin) const;
// Intended for temporary use in locations that should be using a non-empty
// NetworkIsolationKey(), but are not yet. This both reduces the chance of
// accidentally copying the lack of a NIK where one should be used, and
// provides a reasonable way of locating callsites that need to have their
// NetworkIsolationKey filled in.
static NetworkIsolationKey Todo() { return NetworkIsolationKey(); }
// Intended for temporary use in locations that should be using main frame and
// frame origin, but are currently only using frame origin, because the
// creating object may be shared across main frame objects. Having a special
// constructor for these methods makes it easier to keep track of locating
// callsites that need to have their NetworkIsolationKey filled in.
static NetworkIsolationKey ToDoUseTopFrameOriginAsWell(
const url::Origin& incorrectly_used_frame_origin) {
return NetworkIsolationKey(incorrectly_used_frame_origin,
incorrectly_used_frame_origin);
}
// Compare keys for equality, true if all enabled fields are equal.
bool operator==(const NetworkIsolationKey& other) const {
return std::tie(top_frame_site_, frame_site_, opaque_and_non_transient_) ==
std::tie(other.top_frame_site_, other.frame_site_,
other.opaque_and_non_transient_);
}
// Compare keys for inequality, true if any enabled field varies.
bool operator!=(const NetworkIsolationKey& other) const {
return !(*this == other);
}
// Provide an ordering for keys based on all enabled fields.
bool operator<(const NetworkIsolationKey& other) const {
return std::tie(top_frame_site_, frame_site_, opaque_and_non_transient_) <
std::tie(other.top_frame_site_, other.frame_site_,
other.opaque_and_non_transient_);
}
// Returns the string representation of the key, which is the string
// representation of each piece of the key separated by spaces.
std::string ToString() const;
// Returns string for debugging. Difference from ToString() is that transient
// entries may be distinguishable from each other.
std::string ToDebugString() const;
// Returns true if all parts of the key are non-empty.
bool IsFullyPopulated() const;
// Returns true if this key's lifetime is short-lived, or if
// IsFullyPopulated() returns true. It may not make sense to persist state to
// disk related to it (e.g., disk cache).
bool IsTransient() const;
// Getters for the top frame and frame sites. These accessors are primarily
// intended for IPC calls, and to be able to create an IsolationInfo from a
// NetworkIsolationKey.
const base::Optional<SchemefulSite>& GetTopFrameSite() const {
return top_frame_site_;
}
const base::Optional<SchemefulSite>& GetFrameSite() const {
return frame_site_;
}
// Returns true if all parts of the key are empty.
bool IsEmpty() const;
// Returns a representation of |this| as a base::Value. Returns false on
// failure. Succeeds if either IsEmpty() or !IsTransient().
bool ToValue(base::Value* out_value) const WARN_UNUSED_RESULT;
// Inverse of ToValue(). Writes the result to |network_isolation_key|. Returns
// false on failure. Fails on values that could not have been produced by
// ToValue(), like transient origins. If the value of
// net::features::kAppendFrameOriginToNetworkIsolationKey has changed between
// saving and loading the data, fails.
static bool FromValue(const base::Value& value,
NetworkIsolationKey* out_network_isolation_key)
WARN_UNUSED_RESULT;
private:
// These classes need to be able to set |opaque_and_non_transient_|
friend class IsolationInfo;
friend struct mojo::StructTraits<network::mojom::NetworkIsolationKeyDataView,
net::NetworkIsolationKey>;
NetworkIsolationKey(SchemefulSite&& top_frame_site,
SchemefulSite&& frame_site,
bool opaque_and_non_transient);
bool IsOpaque() const;
// SchemefulSite::Serialize() is not const, as it may initialize the nonce.
// Need this to call it on a const |site|.
static base::Optional<std::string> SerializeSiteWithNonce(
const SchemefulSite& site);
// Whether opaque origins cause the key to be transient. Always false, unless
// created with |CreateOpaqueAndNonTransient|.
bool opaque_and_non_transient_ = false;
// Whether or not to use the |frame_site_| as part of the key.
bool use_frame_site_;
// The origin/etld+1 of the top frame of the page making the request.
base::Optional<SchemefulSite> top_frame_site_;
// The origin/etld+1 of the frame that initiates the request.
base::Optional<SchemefulSite> frame_site_;
};
} // namespace net
#endif // NET_BASE_NETWORK_ISOLATION_KEY_H_