| // Copyright 2019 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef CONTENT_BROWSER_CLIENT_HINTS_CLIENT_HINTS_H_ |
| #define CONTENT_BROWSER_CLIENT_HINTS_CLIENT_HINTS_H_ |
| |
| #include <memory> |
| #include <string> |
| |
| #include "content/common/content_export.h" |
| #include "content/public/browser/client_hints_controller_delegate.h" |
| #include "net/http/http_request_headers.h" |
| #include "services/network/public/cpp/permissions_policy/permissions_policy_declaration.h" |
| #include "services/network/public/mojom/parsed_headers.mojom-forward.h" |
| #include "url/gurl.h" |
| |
| namespace net { |
| class HttpResponseHeaders; |
| } // namespace net |
| |
| namespace content { |
| |
| class BrowserContext; |
| class FrameTreeNode; |
| |
| // Returns whether client hints can be added for the given URL and frame. This |
| // is true only if the URL is eligible and JavaScript is enabled. |
| // |
| // |origin| is the origin to be used for client hints storage. |
| // |maybe_request_url| is the url of the request. It is used as an origin for |
| // the origin trial client hints. |
| // |
| // Where possible, |origin| should be the origin of the document the navigation |
| // is creating. NavigationRequest::GetOriginToCommit() is used, and takes |
| // sandbox into account, which means that |origin| can be opaque. When called at |
| // request time, NavigationRequest::GetTentativeOriginAtRequestTime() should be |
| // used, because it is not possible to determine the origin before receiving the |
| // final navigation response and the CSP:sandbox response header. It takes into |
| // account the sandbox flags set by the embedder only. |
| // |
| // If |request_url| is not provided, |origin| must not be opaque. This is the |
| // case for Critical-CH processing and ACCEPT_CH frame processing, where the |
| // document is not taken into account. |
| CONTENT_EXPORT bool ShouldAddClientHints( |
| const url::Origin& origin, |
| FrameTreeNode* frame_tree_node, |
| ClientHintsControllerDelegate* delegate, |
| const std::optional<GURL> maybe_request_url = std::nullopt); |
| |
| // Returns |rtt| after adding host-specific random noise, and rounding it as |
| // per the NetInfo spec to improve privacy. |
| CONTENT_EXPORT unsigned long RoundRttForTesting( |
| const std::string& host, |
| const std::optional<base::TimeDelta>& rtt); |
| |
| // Returns downlink (in Mbps) after adding host-specific random noise to |
| // |downlink_kbps| (which is in Kbps), and rounding it as per the NetInfo spec |
| // to improve privacy. |
| CONTENT_EXPORT double RoundKbpsToMbpsForTesting( |
| const std::string& host, |
| const std::optional<int32_t>& downlink_kbps); |
| |
| // Returns true if there is a hint in |critical_hints| that would be sent (i.e. |
| // not blocked by browser or origin level preferences like disabled JavaScript |
| // or Feature/Permission Policy) but is not currently in the client hint |
| // storage. |
| CONTENT_EXPORT bool AreCriticalHintsMissing( |
| const url::Origin& origin, |
| FrameTreeNode* frame_tree_node, |
| ClientHintsControllerDelegate* delegate, |
| const std::vector<network::mojom::WebClientHintsType>& critical_hints); |
| |
| // Return a list of client hints that are both allowed and cached based on |
| // the Accept-CH response header |
| // The algorithm follows the `AreCriticalHintsMissing` function. |
| CONTENT_EXPORT std::vector<network::mojom::WebClientHintsType> |
| GetEnabledClientHints(const url::Origin& origin, |
| FrameTreeNode* frame_tree_node, |
| ClientHintsControllerDelegate* delegate); |
| |
| // Updates the user agent client hint headers. This is called if the value of |
| // |override_ua| changes after the NavigationRequest was created. |
| // |
| // See |ShouldAddClientHints| for |origin| vs |request_url| |
| CONTENT_EXPORT void UpdateNavigationRequestClientUaHeaders( |
| const url::Origin& origin, |
| ClientHintsControllerDelegate* delegate, |
| bool override_ua, |
| FrameTreeNode* frame_tree_node, |
| net::HttpRequestHeaders* headers, |
| const std::optional<GURL>& request_url = std::nullopt); |
| |
| CONTENT_EXPORT void AddNavigationRequestClientHintsHeaders( |
| const url::Origin& origin, |
| net::HttpRequestHeaders* headers, |
| BrowserContext* context, |
| ClientHintsControllerDelegate* delegate, |
| bool is_ua_override_on, |
| FrameTreeNode*, |
| const network::ParsedPermissionsPolicy&, |
| const std::optional<GURL>& request_url = std::nullopt); |
| |
| // Adds client hints headers for a prefetch navigation that is not associated |
| // with a frame. It must be a main frame navigation. |
| CONTENT_EXPORT void AddPrefetchNavigationRequestClientHintsHeaders( |
| const url::Origin& origin, |
| net::HttpRequestHeaders* headers, |
| BrowserContext* context, |
| ClientHintsControllerDelegate* delegate, |
| bool is_ua_override_on); |
| |
| // Parses incoming client hints and persists them as appropriate. Returns |
| // hints that were accepted as enabled even if they are not going to be |
| // persisted. |
| // |
| // The ParsedHeaders are used to retrieve the already parsed Accept-CH header |
| // values. The HttpResponseHeaders are not meant to be used by non-sandboxed |
| // processes, but here, we just pass the HttpRequestHeaders to the |
| // TrialTokenValidator library. There is precedent for calling the |
| // TrialTokenValidator from the browser process, see crrev.com/c/2142580. |
| CONTENT_EXPORT std::optional<std::vector<network::mojom::WebClientHintsType>> |
| ParseAndPersistAcceptCHForNavigation( |
| const url::Origin& origin, |
| const network::mojom::ParsedHeadersPtr& parsed_headers, |
| const net::HttpResponseHeaders* response_headers, |
| BrowserContext* context, |
| ClientHintsControllerDelegate* delegate, |
| FrameTreeNode*); |
| |
| // Persists the `hints` in the Accept-CH storage for the Origin of `url`. |
| // `delegate` cannot be nullptr. |
| CONTENT_EXPORT void PersistAcceptCH( |
| const url::Origin& origin, |
| FrameTreeNode& frame_tree_node, |
| ClientHintsControllerDelegate* delegate, |
| const std::vector<network::mojom::WebClientHintsType>& hints); |
| |
| // Looks up which client hints the renderer should be told to enable |
| // (after subjecting them to permissions policy). |
| // |
| // Note that this is based on the top-level frame, and not necessarily the |
| // frame being committed. |
| // |
| // See |ShouldAddClientHints| for |origin| vs |request_url| |
| CONTENT_EXPORT std::vector<::network::mojom::WebClientHintsType> |
| LookupAcceptCHForCommit(const url::Origin& origin, |
| ClientHintsControllerDelegate* delegate, |
| FrameTreeNode* frame_tree_node, |
| const std::optional<GURL>& request_url = std::nullopt); |
| |
| } // namespace content |
| |
| #endif // CONTENT_BROWSER_CLIENT_HINTS_CLIENT_HINTS_H_ |