1 // Copyright 2014 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.
5 #include "chrome/browser/net/chrome_url_request_context_getter.h"
8 #include "base/compiler_specific.h"
9 #include "base/message_loop/message_loop.h"
10 #include "base/thread_task_runner_handle.h"
11 #include "chrome/browser/browser_process.h"
12 #include "chrome/browser/io_thread.h"
13 #include "chrome/browser/profiles/profile.h"
14 #include "chrome/browser/profiles/profile_io_data.h"
15 #include "chrome/browser/profiles/storage_partition_descriptor.h"
16 #include "content/public/browser/browser_thread.h"
17 #include "net/cookies/cookie_store.h"
19 using content::BrowserThread
;
21 class ChromeURLRequestContextFactory
{
23 ChromeURLRequestContextFactory() {}
24 virtual ~ChromeURLRequestContextFactory() {}
26 // Called to create a new instance (will only be called once).
27 virtual net::URLRequestContext
* Create() = 0;
30 DISALLOW_COPY_AND_ASSIGN(ChromeURLRequestContextFactory
);
35 // ----------------------------------------------------------------------------
37 // ----------------------------------------------------------------------------
39 // Factory that creates the main URLRequestContext.
40 class FactoryForMain
: public ChromeURLRequestContextFactory
{
43 const ProfileIOData
* profile_io_data
,
44 content::ProtocolHandlerMap
* protocol_handlers
,
45 content::URLRequestInterceptorScopedVector request_interceptors
)
46 : profile_io_data_(profile_io_data
),
47 request_interceptors_(request_interceptors
.Pass()) {
48 std::swap(protocol_handlers_
, *protocol_handlers
);
51 net::URLRequestContext
* Create() override
{
52 profile_io_data_
->Init(&protocol_handlers_
, request_interceptors_
.Pass());
53 return profile_io_data_
->GetMainRequestContext();
57 const ProfileIOData
* const profile_io_data_
;
58 content::ProtocolHandlerMap protocol_handlers_
;
59 content::URLRequestInterceptorScopedVector request_interceptors_
;
62 // Factory that creates the URLRequestContext for extensions.
63 class FactoryForExtensions
: public ChromeURLRequestContextFactory
{
65 explicit FactoryForExtensions(const ProfileIOData
* profile_io_data
)
66 : profile_io_data_(profile_io_data
) {}
68 net::URLRequestContext
* Create() override
{
69 return profile_io_data_
->GetExtensionsRequestContext();
73 const ProfileIOData
* const profile_io_data_
;
76 // Factory that creates the URLRequestContext for a given isolated app.
77 class FactoryForIsolatedApp
: public ChromeURLRequestContextFactory
{
79 FactoryForIsolatedApp(
80 const ProfileIOData
* profile_io_data
,
81 const StoragePartitionDescriptor
& partition_descriptor
,
82 ChromeURLRequestContextGetter
* main_context
,
83 scoped_ptr
<ProtocolHandlerRegistry::JobInterceptorFactory
>
84 protocol_handler_interceptor
,
85 content::ProtocolHandlerMap
* protocol_handlers
,
86 content::URLRequestInterceptorScopedVector request_interceptors
)
87 : profile_io_data_(profile_io_data
),
88 partition_descriptor_(partition_descriptor
),
89 main_request_context_getter_(main_context
),
90 protocol_handler_interceptor_(protocol_handler_interceptor
.Pass()),
91 request_interceptors_(request_interceptors
.Pass()) {
92 std::swap(protocol_handlers_
, *protocol_handlers
);
95 net::URLRequestContext
* Create() override
{
96 // We will copy most of the state from the main request context.
98 // Note that this factory is one-shot. After Create() is called once, the
99 // factory is actually destroyed. Thus it is safe to destructively pass
101 return profile_io_data_
->GetIsolatedAppRequestContext(
102 main_request_context_getter_
->GetURLRequestContext(),
103 partition_descriptor_
,
104 protocol_handler_interceptor_
.Pass(),
106 request_interceptors_
.Pass());
110 const ProfileIOData
* const profile_io_data_
;
111 const StoragePartitionDescriptor partition_descriptor_
;
112 scoped_refptr
<ChromeURLRequestContextGetter
>
113 main_request_context_getter_
;
114 scoped_ptr
<ProtocolHandlerRegistry::JobInterceptorFactory
>
115 protocol_handler_interceptor_
;
116 content::ProtocolHandlerMap protocol_handlers_
;
117 content::URLRequestInterceptorScopedVector request_interceptors_
;
120 // Factory that creates the media URLRequestContext for a given isolated
121 // app. The media context is based on the corresponding isolated app's context.
122 class FactoryForIsolatedMedia
: public ChromeURLRequestContextFactory
{
124 FactoryForIsolatedMedia(
125 const ProfileIOData
* profile_io_data
,
126 const StoragePartitionDescriptor
& partition_descriptor
,
127 ChromeURLRequestContextGetter
* app_context
)
128 : profile_io_data_(profile_io_data
),
129 partition_descriptor_(partition_descriptor
),
130 app_context_getter_(app_context
) {}
132 net::URLRequestContext
* Create() override
{
133 // We will copy most of the state from the corresopnding app's
134 // request context. We expect to have the same lifetime as
135 // the associated |app_context_getter_| so we can just reuse
136 // all its backing objects, including the
137 // |protocol_handler_interceptor|. This is why the API
138 // looks different from FactoryForIsolatedApp's.
139 return profile_io_data_
->GetIsolatedMediaRequestContext(
140 app_context_getter_
->GetURLRequestContext(), partition_descriptor_
);
144 const ProfileIOData
* const profile_io_data_
;
145 const StoragePartitionDescriptor partition_descriptor_
;
146 scoped_refptr
<ChromeURLRequestContextGetter
> app_context_getter_
;
149 // Factory that creates the URLRequestContext for media.
150 class FactoryForMedia
: public ChromeURLRequestContextFactory
{
152 explicit FactoryForMedia(const ProfileIOData
* profile_io_data
)
153 : profile_io_data_(profile_io_data
) {
156 net::URLRequestContext
* Create() override
{
157 return profile_io_data_
->GetMediaRequestContext();
161 const ProfileIOData
* const profile_io_data_
;
166 // ----------------------------------------------------------------------------
167 // ChromeURLRequestContextGetter
168 // ----------------------------------------------------------------------------
170 ChromeURLRequestContextGetter::ChromeURLRequestContextGetter(
171 ChromeURLRequestContextFactory
* factory
)
173 url_request_context_(nullptr) {
177 ChromeURLRequestContextGetter::~ChromeURLRequestContextGetter() {
178 // NotifyContextShuttingDown() must have been called.
179 DCHECK(!factory_
.get());
180 DCHECK(!url_request_context_
);
183 // Lazily create a URLRequestContext using our factory.
184 net::URLRequestContext
*
185 ChromeURLRequestContextGetter::GetURLRequestContext() {
186 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
188 if (factory_
.get()) {
189 DCHECK(!url_request_context_
);
190 url_request_context_
= factory_
->Create();
194 return url_request_context_
;
197 void ChromeURLRequestContextGetter::NotifyContextShuttingDown() {
198 DCHECK_CURRENTLY_ON(BrowserThread::IO
);
201 url_request_context_
= nullptr;
202 URLRequestContextGetter::NotifyContextShuttingDown();
205 scoped_refptr
<base::SingleThreadTaskRunner
>
206 ChromeURLRequestContextGetter::GetNetworkTaskRunner() const {
207 return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO
);
211 ChromeURLRequestContextGetter
* ChromeURLRequestContextGetter::Create(
213 const ProfileIOData
* profile_io_data
,
214 content::ProtocolHandlerMap
* protocol_handlers
,
215 content::URLRequestInterceptorScopedVector request_interceptors
) {
216 return new ChromeURLRequestContextGetter(new FactoryForMain(
217 profile_io_data
, protocol_handlers
, request_interceptors
.Pass()));
221 ChromeURLRequestContextGetter
*
222 ChromeURLRequestContextGetter::CreateForMedia(
223 Profile
* profile
, const ProfileIOData
* profile_io_data
) {
224 return new ChromeURLRequestContextGetter(
225 new FactoryForMedia(profile_io_data
));
229 ChromeURLRequestContextGetter
*
230 ChromeURLRequestContextGetter::CreateForExtensions(
231 Profile
* profile
, const ProfileIOData
* profile_io_data
) {
232 return new ChromeURLRequestContextGetter(
233 new FactoryForExtensions(profile_io_data
));
237 ChromeURLRequestContextGetter
*
238 ChromeURLRequestContextGetter::CreateForIsolatedApp(
240 const ProfileIOData
* profile_io_data
,
241 const StoragePartitionDescriptor
& partition_descriptor
,
242 scoped_ptr
<ProtocolHandlerRegistry::JobInterceptorFactory
>
243 protocol_handler_interceptor
,
244 content::ProtocolHandlerMap
* protocol_handlers
,
245 content::URLRequestInterceptorScopedVector request_interceptors
) {
246 ChromeURLRequestContextGetter
* main_context
=
247 static_cast<ChromeURLRequestContextGetter
*>(profile
->GetRequestContext());
248 return new ChromeURLRequestContextGetter(
249 new FactoryForIsolatedApp(profile_io_data
,
250 partition_descriptor
,
252 protocol_handler_interceptor
.Pass(),
254 request_interceptors
.Pass()));
258 ChromeURLRequestContextGetter
*
259 ChromeURLRequestContextGetter::CreateForIsolatedMedia(
261 ChromeURLRequestContextGetter
* app_context
,
262 const ProfileIOData
* profile_io_data
,
263 const StoragePartitionDescriptor
& partition_descriptor
) {
264 return new ChromeURLRequestContextGetter(
265 new FactoryForIsolatedMedia(
266 profile_io_data
, partition_descriptor
, app_context
));