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
content / browser / loader / subresource_proxying_url_loader_service.h [blame]
// 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_LOADER_SUBRESOURCE_PROXYING_URL_LOADER_SERVICE_H_
#define CONTENT_BROWSER_LOADER_SUBRESOURCE_PROXYING_URL_LOADER_SERVICE_H_
#include <string>
#include "base/functional/callback.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/ref_counted.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/frame_tree_node_id.h"
#include "content/public/browser/weak_document_ptr.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/bindings/receiver_set.h"
#include "net/base/isolation_info.h"
#include "services/network/public/mojom/url_loader_factory.mojom.h"
#include "third_party/blink/public/common/loader/url_loader_factory_bundle.h"
namespace content {
class BrowserContext;
class PrefetchedSignedExchangeCache;
class PrefetchURLLoaderServiceContext;
class RenderFrameHostImpl;
// A URLLoaderFactory that can be passed to a renderer to intercept subresource
// requests.
//
// The renderer uses it for:
// - Prefetch requests including <link rel="prefetch">
// - Topics requests including fetch(<url>, {browsingTopics: true})
class CONTENT_EXPORT SubresourceProxyingURLLoaderService final
: public network::mojom::URLLoaderFactory {
public:
struct CONTENT_EXPORT BindContext : public base::RefCounted<BindContext> {
// `factory` is a clone of the default factory bundle for document
// subresource requests.
BindContext(FrameTreeNodeId frame_tree_node_id,
scoped_refptr<network::SharedURLLoaderFactory> factory,
base::WeakPtr<RenderFrameHostImpl> render_frame_host,
scoped_refptr<PrefetchedSignedExchangeCache>
prefetched_signed_exchange_cache);
// Set `document` to `committed_document`.
void OnDidCommitNavigation(WeakDocumentPtr committed_document);
const FrameTreeNodeId frame_tree_node_id;
scoped_refptr<network::SharedURLLoaderFactory> factory;
base::WeakPtr<RenderFrameHostImpl> render_frame_host;
// This member is lazily initialized by EnsureCrossOriginFactory().
scoped_refptr<network::SharedURLLoaderFactory> cross_origin_factory;
scoped_refptr<PrefetchedSignedExchangeCache>
prefetched_signed_exchange_cache;
// This maps recursive prefetch tokens to IsolationInfos that they should be
// fetched with.
std::map<base::UnguessableToken, net::IsolationInfo>
prefetch_isolation_infos;
// Upon NavigationRequest::DidCommitNavigation(), `document` will be set to
// the document that this `BindContext` is associated with. It will become
// null whenever the document navigates away.
WeakDocumentPtr document;
// This must be the last member.
base::WeakPtrFactory<SubresourceProxyingURLLoaderService::BindContext>
weak_ptr_factory{this};
private:
~BindContext();
friend class base::RefCounted<BindContext>;
};
explicit SubresourceProxyingURLLoaderService(BrowserContext* browser_context);
~SubresourceProxyingURLLoaderService() override;
SubresourceProxyingURLLoaderService(
const SubresourceProxyingURLLoaderService&) = delete;
SubresourceProxyingURLLoaderService& operator=(
const SubresourceProxyingURLLoaderService&) = delete;
base::WeakPtr<BindContext> GetFactory(
mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver,
FrameTreeNodeId frame_tree_node_id,
scoped_refptr<network::SharedURLLoaderFactory>
subresource_proxying_factory_bundle,
base::WeakPtr<RenderFrameHostImpl> render_frame_host,
scoped_refptr<PrefetchedSignedExchangeCache>
prefetched_signed_exchange_cache);
PrefetchURLLoaderServiceContext&
prefetch_url_loader_service_context_for_testing() {
return *prefetch_url_loader_service_context_;
}
private:
// network::mojom::URLLoaderFactory:
void CreateLoaderAndStart(
mojo::PendingReceiver<network::mojom::URLLoader> receiver,
int32_t request_id,
uint32_t options,
const network::ResourceRequest& resource_request_in,
mojo::PendingRemote<network::mojom::URLLoaderClient> client,
const net::MutableNetworkTrafficAnnotationTag& traffic_annotation)
override;
void Clone(mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver)
override;
void CreateSubresourceProxyingLoaderAndStart(
mojo::PendingReceiver<network::mojom::URLLoader> receiver,
int32_t request_id,
uint32_t options,
const network::ResourceRequest& resource_request_in,
mojo::PendingRemote<network::mojom::URLLoaderClient> client,
const net::MutableNetworkTrafficAnnotationTag& traffic_annotation);
mojo::ReceiverSet<network::mojom::URLLoaderFactory,
scoped_refptr<BindContext>>
loader_factory_receivers_;
mojo::ReceiverSet<network::mojom::URLLoader,
std::unique_ptr<network::mojom::URLLoader>>
subresource_proxying_loader_receivers_;
std::unique_ptr<PrefetchURLLoaderServiceContext>
prefetch_url_loader_service_context_;
};
} // namespace content
#endif // CONTENT_BROWSER_LOADER_SUBRESOURCE_PROXYING_URL_LOADER_SERVICE_H_