1 // Copyright 2017 The Chromium Authors. All rights reserved.
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_BROWSER_URL_LOADER_FACTORY_GETTER_H_
6 #define CONTENT_BROWSER_URL_LOADER_FACTORY_GETTER_H_
7 
8 #include <memory>
9 
10 #include "base/callback_forward.h"
11 #include "base/macros.h"
12 #include "base/memory/ref_counted.h"
13 #include "content/common/content_export.h"
14 #include "content/public/browser/browser_thread.h"
15 #include "mojo/public/cpp/bindings/pending_receiver.h"
16 #include "mojo/public/cpp/bindings/pending_remote.h"
17 #include "mojo/public/cpp/bindings/remote.h"
18 #include "services/network/public/mojom/url_loader_factory.mojom.h"
19 
20 namespace network {
21 class PendingSharedURLLoaderFactory;
22 class SharedURLLoaderFactory;
23 }  // namespace network
24 
25 namespace content {
26 
27 class StoragePartitionImpl;
28 
29 // Holds on to URLLoaderFactory for a given StoragePartition and allows code
30 // running on the IO thread to access them. Note these are the factories used by
31 // the browser process for frame requests.
32 class URLLoaderFactoryGetter
33     : public base::RefCountedThreadSafe<URLLoaderFactoryGetter,
34                                         BrowserThread::DeleteOnIOThread> {
35  public:
36   CONTENT_EXPORT URLLoaderFactoryGetter();
37 
38   // Initializes this object on the UI thread. The |partition| is used to
39   // initialize the URLLoaderFactories for the network service, AppCache, and
40   // ServiceWorkers, and will be cached to recover from connection error.
41   // After Initialize(), you can get URLLoaderFactories from this
42   // getter.
43   void Initialize(StoragePartitionImpl* partition);
44 
45   // Clear the cached pointer to |StoragePartitionImpl| on the UI thread. Should
46   // be called when the partition is going away.
47   void OnStoragePartitionDestroyed();
48 
49   // Called on the IO thread to get a shared wrapper to this
50   // URLLoaderFactoryGetter, which can be used to access the URLLoaderFactory
51   // to the network service and supports auto-reconnect after crash.
52   CONTENT_EXPORT scoped_refptr<network::SharedURLLoaderFactory>
53   GetNetworkFactory();
54 
55   // Like above, except it returns a URLLoaderFactory that has CORB enabled. Use
56   // this when using the factory for requests on behalf of a renderer.
57   // TODO(lukasza): https://crbug.com/871827: Ensure that |request_initiator| is
58   // trustworthy, even when starting requests on behalf of a renderer.
59   CONTENT_EXPORT scoped_refptr<network::SharedURLLoaderFactory>
60   GetNetworkFactoryWithCORBEnabled();
61 
62   // Called on the UI thread to get an info that holds a reference to this
63   // URLLoaderFactoryGetter, which can be used to construct a similar
64   // SharedURLLoaderFactory as returned from |GetNetworkFactory()| on IO thread.
65   CONTENT_EXPORT std::unique_ptr<network::PendingSharedURLLoaderFactory>
66   GetPendingNetworkFactory();
67 
68   // Called on the IO thread. The factory obtained from here can only be used
69   // from the browser process. It must NOT be sent to a renderer process. It has
70   // CORB disabled, so it must NOT be used to make requests on behalf of a
71   // renderer.
72   //
73   // When NetworkService is enabled, this clones the internal factory to the
74   // network service, which doesn't support auto-reconnect after crash. Useful
75   // for one-off requests (e.g. a single navigation) to avoid an additional Mojo
76   // hop.
77   //
78   // When NetworkService is disabled, this clones the non-NetworkService direct
79   // network factory.
80   CONTENT_EXPORT void CloneNetworkFactory(
81       mojo::PendingReceiver<network::mojom::URLLoaderFactory>
82           network_factory_receiver);
83 
84   // Overrides the network URLLoaderFactory for subsequent requests. Passing a
85   // null pointer will restore the default behavior.
86   CONTENT_EXPORT void SetNetworkFactoryForTesting(
87       network::mojom::URLLoaderFactory* test_factory,
88       bool is_corb_enabled = false);
89 
90   CONTENT_EXPORT mojo::Remote<network::mojom::URLLoaderFactory>*
original_network_factory_for_testing()91   original_network_factory_for_testing() {
92     return &network_factory_;
93   }
94 
95   CONTENT_EXPORT mojo::Remote<network::mojom::URLLoaderFactory>*
original_network_factory__corb_enabled_for_testing()96   original_network_factory__corb_enabled_for_testing() {
97     return &network_factory_corb_enabled_;
98   }
99 
100   // When this global function is set, if GetURLLoaderFactory is called and
101   // |test_factory_| is null, then the callback will be run. This method must be
102   // called either on the IO thread or before threads start. This callback is
103   // run on the IO thread.
104   using GetNetworkFactoryCallback = base::RepeatingCallback<void(
105       scoped_refptr<URLLoaderFactoryGetter> url_loader_factory_getter)>;
106   CONTENT_EXPORT static void SetGetNetworkFactoryCallbackForTesting(
107       const GetNetworkFactoryCallback& get_network_factory_callback);
108 
109   // Call |network_factory_.FlushForTesting()| on IO thread. For test use only.
110   CONTENT_EXPORT void FlushNetworkInterfaceOnIOThreadForTesting();
111 
112  private:
113   class PendingURLLoaderFactoryForIOThread;
114   class URLLoaderFactoryForIOThread;
115 
116   friend class base::DeleteHelper<URLLoaderFactoryGetter>;
117   friend struct BrowserThread::DeleteOnThread<BrowserThread::IO>;
118 
119   CONTENT_EXPORT ~URLLoaderFactoryGetter();
120   void InitializeOnIOThread(
121       mojo::PendingRemote<network::mojom::URLLoaderFactory> network_factory);
122 
123   // Moves |network_factory| to |network_factory_| or
124   // |network_factory_corb_enabled_| depending on |is_corb_enabled| and sets up
125   // an error handler.
126   void ReinitializeOnIOThread(
127       mojo::Remote<network::mojom::URLLoaderFactory> network_factory,
128       bool is_corb_enabled);
129 
130   // Send |network_factory_request| to cached |StoragePartitionImpl|.
131   void HandleNetworkFactoryRequestOnUIThread(
132       mojo::PendingReceiver<network::mojom::URLLoaderFactory>
133           network_factory_receiver,
134       bool is_corb_enabled);
135 
136   // Called on the IO thread to get the URLLoaderFactory to the network service.
137   // The pointer shouldn't be cached.
138   network::mojom::URLLoaderFactory* GetURLLoaderFactory(bool is_corb_enabled);
139 
140   // Call |network_factory_.FlushForTesting()|. For test use only. When the
141   // flush is complete, |callback| will be called.
142   void FlushNetworkInterfaceForTesting(base::OnceClosure callback);
143 
144   // Only accessed on IO thread.
145   mojo::Remote<network::mojom::URLLoaderFactory> network_factory_;
146   mojo::Remote<network::mojom::URLLoaderFactory> network_factory_corb_enabled_;
147   network::mojom::URLLoaderFactory* test_factory_ = nullptr;
148   network::mojom::URLLoaderFactory* test_factory_corb_enabled_ = nullptr;
149 
150   // Used to re-create |network_factory_| when connection error happens. Can
151   // only be accessed on UI thread. Must be cleared by |StoragePartitionImpl|
152   // when it's going away.
153   StoragePartitionImpl* partition_ = nullptr;
154 
155   DISALLOW_COPY_AND_ASSIGN(URLLoaderFactoryGetter);
156 };
157 
158 }  // namespace content
159 
160 #endif  // CONTENT_BROWSER_URL_LOADER_FACTORY_GETTER_H_
161