blob: dc3e4c83f74c33fcbc5f861f08c1e9067de63ef0 [file] [log] [blame]
Alex Yangf8e2319032025-01-14 00:28:511// Copyright 2025 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 CONTENT_RENDERER_LOCAL_RESOURCE_URL_LOADER_FACTORY_H_
6#define CONTENT_RENDERER_LOCAL_RESOURCE_URL_LOADER_FACTORY_H_
7
8#include <cstdint>
9#include <memory>
10
11#include "base/memory/ref_counted.h"
12#include "base/memory/scoped_refptr.h"
13#include "base/task/sequenced_task_runner.h"
14#include "base/threading/sequence_bound.h"
15#include "content/common/content_export.h"
16#include "mojo/public/cpp/bindings/pending_receiver.h"
17#include "mojo/public/cpp/bindings/pending_remote.h"
18#include "mojo/public/cpp/bindings/receiver_set.h"
19#include "mojo/public/cpp/bindings/remote.h"
20#include "net/socket/socket.h"
21#include "services/network/public/cpp/resource_request.h"
22#include "services/network/public/mojom/url_loader.mojom.h"
23#include "services/network/public/mojom/url_loader_factory.mojom.h"
24#include "third_party/blink/public/mojom/loader/local_resource_loader_config.mojom.h"
25#include "url/origin.h"
26
27namespace content {
28
29// LocalResourceURLLoaderFactory is a URLLoaderFactory that lives in the
30// renderer process and fetches resources directly from the ResourceBundle,
31// enabling renderers to load bundled resources entirely in-process. This can
32// significantly reduce IPC overhead for WebUIs, whose resources come almost
33// exclusively from the ResourceBundle.
34class CONTENT_EXPORT LocalResourceURLLoaderFactory
35 : public network::mojom::URLLoaderFactory {
36 public:
37 struct Source {
38 Source(blink::mojom::LocalResourceSourcePtr source,
Alex Yang690544aa32025-02-03 22:30:2339 std::map<std::string, std::string> replacement_strings);
Alex Yangf8e2319032025-01-14 00:28:5140 Source(Source&& other);
41 Source& operator=(Source&& other);
42 ~Source();
43 blink::mojom::LocalResourceSourcePtr source;
Alex Yang690544aa32025-02-03 22:30:2344 std::map<std::string, std::string> replacement_strings;
Alex Yangf8e2319032025-01-14 00:28:5145 };
46
47 LocalResourceURLLoaderFactory(
Alex Yanga6e68122025-01-23 21:14:5048 blink::mojom::LocalResourceLoaderConfigPtr config,
Alex Yangf8e2319032025-01-14 00:28:5149 mojo::PendingRemote<network::mojom::URLLoaderFactory> fallback);
50 ~LocalResourceURLLoaderFactory() override;
51
52 // network::mojom::URLLoaderFactory implementation.
53 void CreateLoaderAndStart(
54 mojo::PendingReceiver<network::mojom::URLLoader> loader,
55 int32_t request_id,
56 uint32_t options,
57 const network::ResourceRequest& request,
58 mojo::PendingRemote<network::mojom::URLLoaderClient> client,
59 const net::MutableNetworkTrafficAnnotationTag& traffic_annotation)
60 override;
61 void Clone(mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver)
62 override;
63
64 private:
65 // CanServe returns true if and only if all of the following are true:
66 //
67 // 1. The LocalResourceURLLoaderFactory has a resource ID for the given URL
68 // (which depends on the resource metadata received from the browser
69 // process), and
70 // 2. The resource ID corresponds to a resource that exists in
71 // 'resources.pak'.
72 //
73 // It should return false in the following cases:
74 //
75 // 1. For dynamic resources that are generated on-the-fly in the browser
76 // process (e.g. strings.m.js, chrome://theme/colors.css).
77 // 2. For static resources that reside in a pak file that is not
78 // memory-mapped in the renderer process (e.g. browser_tests.pak).
79 //
80 // CanServe is called internally for every resource request to decide whether
81 // the request can be serviced in-process or if it has to be serviced
82 // out-of-process.
83 bool CanServe(const network::ResourceRequest& request) const;
84
Alex Yang34f57092025-01-14 00:29:0385 // Fetches the resource from the ResourceBundle and sends it to the
86 // URLLoaderClient. This is static because it is posted as a task which may
87 // outlive |this|.
88 static void GetResourceAndRespond(
89 const scoped_refptr<base::RefCountedData<std::map<url::Origin, Source>>>
90 sources,
Alex Yangf8e2319032025-01-14 00:28:5191 const network::ResourceRequest& request,
Alex Yang34f57092025-01-14 00:29:0392 mojo::PendingRemote<network::mojom::URLLoaderClient> client);
Alex Yangf8e2319032025-01-14 00:28:5193
Alex Yang34f57092025-01-14 00:29:0394 // Map for resolving origins to their respective source metadata
95 // (path-to-resource-ID mappings and string replacement maps).
96 // It is ref-counted because it needs to be accessed in an async call to
97 // GetResourceAndRespond, which may outlive |this|.
98 const scoped_refptr<base::RefCountedData<std::map<url::Origin, Source>>>
99 sources_;
Alex Yangf8e2319032025-01-14 00:28:51100
101 // Pipe to fallback factory, which should be the WebUIURLLoaderFactory in the
102 // browser process. This is required because there are certain resources that
103 // cannot be serviced in-process and must be serviced by the browser process.
104 // See the CanServe method for more details.
105 const mojo::Remote<network::mojom::URLLoaderFactory> fallback_;
106
107 // Pipes to callers of the Clone method.
108 mojo::ReceiverSet<network::mojom::URLLoaderFactory> receivers_;
109};
110
111} // namespace content
112
113#endif // CONTENT_RENDERER_LOCAL_RESOURCE_URL_LOADER_FACTORY_H_