1 // Copyright 2019 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #ifndef NET_BASE_NETWORK_ISOLATION_KEY_H_ 6 #define NET_BASE_NETWORK_ISOLATION_KEY_H_ 7 8 #include <string> 9 10 #include "base/gtest_prod_util.h" 11 #include "base/macros.h" 12 #include "base/optional.h" 13 #include "base/values.h" 14 #include "net/base/net_export.h" 15 #include "url/origin.h" 16 17 namespace network { 18 namespace mojom { 19 class NetworkIsolationKeyDataView; 20 } // namespace mojom 21 } // namespace network 22 23 namespace mojo { 24 template <typename DataViewType, typename T> 25 struct StructTraits; 26 } // namespace mojo 27 28 namespace net { 29 30 // Key used to isolate shared network stack resources used by requests based on 31 // the context on which they were made. 32 class NET_EXPORT NetworkIsolationKey { 33 public: 34 // Full constructor. When a request is initiated by the top frame, it must 35 // also populate the |frame_origin| parameter when calling this constructor. 36 // Arguments can be either origins or schemeful sites. 37 NetworkIsolationKey(const url::Origin& top_frame_origin, 38 const url::Origin& frame_origin); 39 40 // Construct an empty key. 41 NetworkIsolationKey(); 42 43 NetworkIsolationKey(const NetworkIsolationKey& network_isolation_key); 44 NetworkIsolationKey(NetworkIsolationKey&& network_isolation_key); 45 46 ~NetworkIsolationKey(); 47 48 NetworkIsolationKey& operator=( 49 const NetworkIsolationKey& network_isolation_key); 50 NetworkIsolationKey& operator=(NetworkIsolationKey&& network_isolation_key); 51 52 // Creates a transient non-empty NetworkIsolationKey by creating an opaque 53 // origin. This prevents the NetworkIsolationKey from sharing data with other 54 // NetworkIsolationKeys. Data for transient NetworkIsolationKeys is not 55 // persisted to disk. 56 static NetworkIsolationKey CreateTransient(); 57 58 // Creates a non-empty NetworkIsolationKey with an opaque origin that is not 59 // considered transient. The returned NetworkIsolationKey will be cross-origin 60 // with all other keys and associated data is able to be persisted to disk. 61 static NetworkIsolationKey CreateOpaqueAndNonTransient(); 62 63 // Creates a new key using |top_frame_origin_| and |new_frame_origin|. 64 NetworkIsolationKey CreateWithNewFrameOrigin( 65 const url::Origin& new_frame_origin) const; 66 67 // Intended for temporary use in locations that should be using a non-empty 68 // NetworkIsolationKey(), but are not yet. This both reduces the chance of 69 // accidentally copying the lack of a NIK where one should be used, and 70 // provides a reasonable way of locating callsites that need to have their 71 // NetworkIsolationKey filled in. Todo()72 static NetworkIsolationKey Todo() { return NetworkIsolationKey(); } 73 74 // Compare keys for equality, true if all enabled fields are equal. 75 bool operator==(const NetworkIsolationKey& other) const { 76 return std::tie(top_frame_site_, frame_site_, opaque_and_non_transient_) == 77 std::tie(other.top_frame_site_, other.frame_site_, 78 other.opaque_and_non_transient_); 79 } 80 81 // Compare keys for inequality, true if any enabled field varies. 82 bool operator!=(const NetworkIsolationKey& other) const { 83 return !(*this == other); 84 } 85 86 // Provide an ordering for keys based on all enabled fields. 87 bool operator<(const NetworkIsolationKey& other) const { 88 return std::tie(top_frame_site_, frame_site_, opaque_and_non_transient_) < 89 std::tie(other.top_frame_site_, other.frame_site_, 90 other.opaque_and_non_transient_); 91 } 92 93 // Returns the string representation of the key, which is the string 94 // representation of each piece of the key separated by spaces. 95 std::string ToString() const; 96 97 // Returns string for debugging. Difference from ToString() is that transient 98 // entries may be distinguishable from each other. 99 std::string ToDebugString() const; 100 101 // Returns true if all parts of the key are non-empty. 102 bool IsFullyPopulated() const; 103 104 // Returns true if this key's lifetime is short-lived, or if 105 // IsFullyPopulated() returns true. It may not make sense to persist state to 106 // disk related to it (e.g., disk cache). 107 bool IsTransient() const; 108 109 // Getters for the top frame and frame sites. These are actually scheme + site 110 // for HTTP/HTTPS origins, or original origins for other schemes and opaque 111 // origins. These accessors are primarily intended for IPC calls, and to be 112 // able to create an IsolationInfo from a NetworkIsolationKey. GetTopFrameSite()113 const base::Optional<url::Origin>& GetTopFrameSite() const { 114 return top_frame_site_; 115 } GetFrameSite()116 const base::Optional<url::Origin>& GetFrameSite() const { 117 return frame_site_; 118 } 119 120 // Returns true if all parts of the key are empty. 121 bool IsEmpty() const; 122 123 // Returns a representation of |this| as a base::Value. Returns false on 124 // failure. Succeeds if either IsEmpty() or !IsTransient(). 125 bool ToValue(base::Value* out_value) const WARN_UNUSED_RESULT; 126 127 // Inverse of ToValue(). Writes the result to |network_isolation_key|. Returns 128 // false on failure. Fails on values that could not have been produced by 129 // ToValue(), like transient origins. If the value of 130 // net::features::kAppendFrameOriginToNetworkIsolationKey has changed between 131 // saving and loading the data, fails. 132 static bool FromValue(const base::Value& value, 133 NetworkIsolationKey* out_network_isolation_key) 134 WARN_UNUSED_RESULT; 135 136 private: 137 // These classes need to be able to set |opaque_and_non_transient_| 138 friend class IsolationInfo; 139 friend struct mojo::StructTraits<network::mojom::NetworkIsolationKeyDataView, 140 net::NetworkIsolationKey>; 141 142 NetworkIsolationKey(const url::Origin& top_frame_site, 143 const url::Origin& frame_site, 144 bool opaque_and_non_transient); 145 146 bool IsOpaque() const; 147 148 // Whether opaque origins cause the key to be transient. Always false, unless 149 // created with |CreateOpaqueAndNonTransient|. 150 bool opaque_and_non_transient_ = false; 151 152 // Whether or not to use the |frame_site_| as part of the key. 153 bool use_frame_site_; 154 155 // The origin/etld+1 of the top frame of the page making the request. 156 base::Optional<url::Origin> top_frame_site_; 157 158 // The origin/etld+1 of the frame that initiates the request. 159 base::Optional<url::Origin> frame_site_; 160 }; 161 162 } // namespace net 163 164 #endif // NET_BASE_NETWORK_ISOLATION_KEY_H_ 165