• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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