1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134
  135
  136
  137
  138
  139
  140
  141
  142
  143
  144
  145
  146
  147
  148

content / browser / client_hints / client_hints.h [blame]

// 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/mojom/parsed_headers.mojom-forward.h"
#include "third_party/blink/public/common/permissions_policy/permissions_policy.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);

// 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 blink::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. |is_javascript_enabled| is
// whether JavaScript is enabled in blink or not.
CONTENT_EXPORT void AddPrefetchNavigationRequestClientHintsHeaders(
    const url::Origin& origin,
    net::HttpRequestHeaders* headers,
    BrowserContext* context,
    ClientHintsControllerDelegate* delegate,
    bool is_ua_override_on,
    bool is_javascript_enabled);

// 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_