File: shared_storage_header_observer.h

package info (click to toggle)
chromium 138.0.7204.183-1~deb12u1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm-proposed-updates
  • size: 6,080,960 kB
  • sloc: cpp: 34,937,079; ansic: 7,176,967; javascript: 4,110,704; python: 1,419,954; asm: 946,768; xml: 739,971; pascal: 187,324; sh: 89,623; perl: 88,663; objc: 79,944; sql: 50,304; cs: 41,786; fortran: 24,137; makefile: 21,811; php: 13,980; tcl: 13,166; yacc: 8,925; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (129 lines) | stat: -rw-r--r-- 5,945 bytes parent folder | download | duplicates (4)
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
// Copyright 2023 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_SHARED_STORAGE_SHARED_STORAGE_HEADER_OBSERVER_H_
#define CONTENT_BROWSER_SHARED_STORAGE_SHARED_STORAGE_HEADER_OBSERVER_H_

#include <map>
#include <memory>
#include <string>
#include <vector>

#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "components/services/storage/shared_storage/shared_storage_manager.h"
#include "content/browser/navigation_or_document_handle.h"
#include "content/browser/shared_storage/shared_storage_runtime_manager.h"
#include "content/browser/storage_partition_impl.h"
#include "content/common/content_export.h"
#include "mojo/public/cpp/bindings/message.h"
#include "services/network/public/mojom/url_loader_network_service_observer.mojom.h"
#include "url/origin.h"

namespace content {

// Receives notifications from `StoragePartitionImpl` when a parsed
// "Shared-Storage-Write" header is received from the network service. The
// parsed header takes the form of a vector of StructPtrs bundling operation
// types with any parameters. The corresponding shared storage operations are
// invoked in the same order, omitting any operations that are missing any
// necessary parameters or for which any necessary parameters are invalid.
class CONTENT_EXPORT SharedStorageHeaderObserver {
 public:
  using OperationResult = storage::SharedStorageManager::OperationResult;
  using MethodWithOptionsPtr =
      network::mojom::SharedStorageModifierMethodWithOptionsPtr;
  using ContextType = StoragePartitionImpl::ContextType;

  // Enum for tracking how often the `PermissionsPolicy` double check runs along
  // with its results. Recorded to UMA; always add new values to the end and do
  // not reorder or delete values from this list. If you add any entries to this
  // enum, you must also update the corresponding enum
  // `SharedStorageHeaderObserverPermissionsPolicyDoubleCheckStatus` at
  // tools/metrics/histograms/metadata/storage/enums.xml.
  enum class PermissionsPolicyDoubleCheckStatus {
    // RFH is null, so no double check is run. Any previous permissions
    // policy checks were only done in the renderer; hence operations
    // are dropped.
    kSubresourceSourceNoRFH = 0,
    // RFH has not yet committed. Defer the operations until a corresponding
    // commit notification is received. If none is received, they will be
    // dropped when RFH dies.
    kSubresourceSourceDefer = 1,
    // RFH's LifecycleState is neither kPendingCommit nor kActive. We do not
    // handle these cases as the PermissionsPolicy that we have access to may
    // not be correct. Any operations are dropped.
    kSubresourceSourceOtherLifecycleState = 2,
    // RFH is non-null but has no `PermissionsPolicy`, so no double
    // check is run. Any previous permissions policy checks were only
    // done in the renderer; hence operations are dropped.
    kSubresourceSourceNoPolicy = 3,
    // RFH is non-null but has no `PermissionsPolicy`, so no double
    // check is run, but the request source is an iframe navigation, so
    // a previous browser-side permissions policy check was run in
    // `NavigationRequest`. Hence it is ok to skip the double-check and
    // proceed with the operations.
    kNavigationSourceNoPolicy = 4,
    // The request source is a navigation request for a main frame,
    // which is not supported.
    kDisallowedMainFrameNavigation = 5,
    // A double check is run and the feature is disabled so
    // operations are dropped.
    kDisabled = 6,
    // A double check is run and the feature is enabled so
    // operations are processed.
    kEnabled = 7,

    // Keep this at the end and equal to the last entry.
    kMaxValue = kEnabled,
  };

  explicit SharedStorageHeaderObserver(StoragePartitionImpl* storage_partition);
  virtual ~SharedStorageHeaderObserver();

  // Called by `StoragePartitionImpl` to notify that a parsed
  // "Shared-Storage-Write" header `operations` for a request to
  // `request_origin` from `rfh` has been received. For each operation in
  // `operations`, validates each operation and then invokes each valid
  // operation in the order received, skipping any operations that are missing
  // any necessary parameters or for which any necessary parameters are
  // invalid..
  void HeaderReceived(const url::Origin& request_origin,
                      ContextType context_type,
                      NavigationOrDocumentHandle* navigation_or_document_handle,
                      std::vector<MethodWithOptionsPtr> methods_with_options,
                      const std::optional<std::string>& with_lock,
                      base::OnceClosure callback,
                      mojo::ReportBadMessageCallback bad_message_callback,
                      bool can_defer);

 protected:
  // virtual for testing.
  virtual void OnHeaderProcessed(const url::Origin& request_origin) {}
  virtual void OnBatchUpdateFinished(
      const url::Origin& request_origin,
      std::vector<MethodWithOptionsPtr> methods_with_options,
      const std::optional<std::string>& with_lock,
      const std::string& error_message) {}

 private:
  PermissionsPolicyDoubleCheckStatus DoPermissionsPolicyDoubleCheck(
      const url::Origin& request_origin,
      ContextType context_type,
      NavigationOrDocumentHandle* navigation_or_document_handle);

  bool IsSharedStorageAllowedBySiteSettings(
      NavigationOrDocumentHandle* navigation_or_document_handle,
      const url::Origin& request_origin,
      std::string* out_debug_message = nullptr);

  // `storage_partition_` owns `this`, so it will outlive `this`.
  raw_ptr<StoragePartitionImpl> storage_partition_;

  base::WeakPtrFactory<SharedStorageHeaderObserver> weak_ptr_factory_{this};
};

}  // namespace content

#endif  // CONTENT_BROWSER_SHARED_STORAGE_SHARED_STORAGE_HEADER_OBSERVER_H_