1 // Copyright 2024 The Chromium Authors 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_DEVICE_BOUND_SESSIONS_SESSION_INCLUSION_RULES_H_ 6 #define NET_DEVICE_BOUND_SESSIONS_SESSION_INCLUSION_RULES_H_ 7 8 #include <memory> 9 #include <optional> 10 #include <vector> 11 12 #include "net/base/net_export.h" 13 #include "net/base/scheme_host_port_matcher_rule.h" 14 #include "net/base/schemeful_site.h" 15 #include "url/origin.h" 16 17 namespace net::device_bound_sessions { 18 19 namespace proto { 20 class SessionInclusionRules; 21 } 22 23 // This class represents a set of rules that define which network requests may 24 // potentially be deferred on account of an active DBSC session. It is derived 25 // from parameters specified in the session config. Note that this scope is a 26 // distinct concept from the "scope" of a cookie (or CookieCraving), which is 27 // the set of requests for which that cookie should be included. 28 // 29 // The SessionInclusionRules consists of a basic include rule and a number of 30 // specific include/exclude rules. 31 // 1. The basic include rule defaults to including the origin that created/set 32 // this session's config, but can be expanded to include the whole site 33 // (eTLD+1) if allowed. 34 // 2. A session is allowed to include requests beyond its setting origin if the 35 // setting origin's host is the root eTLD+1 (not a subdomain). 36 // 3. Specific include and exclude rules specify URL patterns that are included 37 // or excluded from deferral by the session. 38 // 39 // A request URL is evaluated for inclusion by matching with the specific rules 40 // in reverse order of addition, and then following the basic include rule if no 41 // specific rules match. Once established, a SessionInclusionRules only cares 42 // about the request URL, not any other properties of the request. 43 class NET_EXPORT SessionInclusionRules final { 44 public: 45 enum InclusionResult { 46 // Definitely do not defer a request on behalf of this DBSC session. 47 kExclude, 48 // Consider a request eligible for deferral on behalf of this session, if 49 // other conditions are met. 50 kInclude, 51 }; 52 53 // Initializes a default rule for the given origin. Does not do any checks 54 // on the origin; caller should enforce semantic checks on the origin such as 55 // desired schemes. 56 explicit SessionInclusionRules(const url::Origin& origin); 57 58 // Default, matches nothing. 59 SessionInclusionRules(); 60 61 SessionInclusionRules(const SessionInclusionRules& other) = delete; 62 SessionInclusionRules& operator=(const SessionInclusionRules& other) = delete; 63 64 SessionInclusionRules(SessionInclusionRules&& other); 65 SessionInclusionRules& operator=(SessionInclusionRules&& other); 66 67 ~SessionInclusionRules(); 68 69 bool operator==(const SessionInclusionRules& other) const; 70 71 // Sets the basic include rule underlying the more specific URL rules. This 72 // should be derived from the "include_site" param in the config. If not set 73 // explicitly, the default is false (meaning an origin-scoped session). If 74 // called with true: expands the basic include rule to include the whole site 75 // of the setting origin, if allowed. If called with false: restricts the 76 // basic rule to the setting origin only (any specific URL rules that are 77 // present will still apply). 78 void SetIncludeSite(bool include_site); 79 80 // Adds a specific URL rule that includes/excludes certain URLs based on their 81 // host part matching `host_pattern` and the path matching `path_prefix`. Any 82 // matching rule takes precedence over the basic scope. Does some validity 83 // checks on the inputs first. The `host_pattern` must either be a full domain 84 // (host piece) or a pattern containing a wildcard ('*' character) in the 85 // most-specific (leftmost) label position followed by a dot and a non-eTLD. 86 // The `path_prefix` must begin with '/' and cannot contain wildcards, and 87 // will match paths that start with the same path components. Returns whether 88 // the specified rule was added. 89 bool AddUrlRuleIfValid(InclusionResult rule_type, 90 const std::string& host_pattern, 91 const std::string& path_prefix); 92 93 // Evaluates `url` to determine whether a request to `url` may be included 94 // (i.e. potentially deferred on account of this DBSC session, if other 95 // conditions are met). 96 InclusionResult EvaluateRequestUrl(const GURL& url) const; 97 may_include_site_for_testing()98 bool may_include_site_for_testing() const { return may_include_site_; } origin()99 const url::Origin& origin() const { return origin_; } 100 101 size_t num_url_rules_for_testing() const; 102 103 proto::SessionInclusionRules ToProto() const; 104 static std::unique_ptr<SessionInclusionRules> CreateFromProto( 105 const proto::SessionInclusionRules& proto); 106 107 private: 108 struct UrlRule; 109 110 // The origin that created/set the session that this applies to. By default, 111 // sessions are origin-scoped unless specified otherwise. 112 url::Origin origin_; 113 114 // Whether the setting origin is allowed to include the whole site in its 115 // rules. This is equivalent to whether the origin's domain is the root eTLD+1 116 // (not a subdomain). It is cached here to avoid repeated eTLD lookups. 117 bool may_include_site_ = false; 118 119 // If non-nullopt: The site of `origin_`, when the config has specified 120 // "include_site" to make the session include any request URL on the setting 121 // origin's whole eTLD+1. This is only allowed if the origin's host is the 122 // root eTLD+1 (not a subdomain). We cache it here for efficiency rather than 123 // repeatedly constructing it from the `origin_` from which it's derived. 124 // If nullopt: Either the config has not specified "include_site", or the 125 // `origin_` is not allowed to include anything outside its origin. 126 // Invariant: If `may_include_site_` is false, then this must also be nullopt. 127 // This shouldn't ever be an opaque site. 128 std::optional<SchemefulSite> include_site_; 129 130 // A list of rules that modify the basic include rule (specified by `origin_` 131 // or `include_site_`), which may specify inclusion or exclusion for URLs that 132 // match. If any rules overlap, the latest rule takes precedence over earlier 133 // rules. 134 std::vector<UrlRule> url_rules_; 135 }; 136 137 } // namespace net::device_bound_sessions 138 139 #endif // NET_DEVICE_BOUND_SESSIONS_SESSION_INCLUSION_RULES_H_ 140