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/message_loop/message_loop_proxy.h"
11 #include "base/profiler/scoped_tracker.h"
12 #include "chrome/browser/browser_process.h"
13 #include "chrome/browser/io_thread.h"
14 #include "chrome/browser/profiles/profile.h"
15 #include "chrome/browser/profiles/profile_io_data.h"
16 #include "chrome/browser/profiles/storage_partition_descriptor.h"
17 #include "content/public/browser/browser_thread.h"
18 #include "net/cookies/cookie_store.h"
20 using content::BrowserThread
;
22 class ChromeURLRequestContextFactory
{
24 ChromeURLRequestContextFactory() {}
25 virtual ~ChromeURLRequestContextFactory() {}
27 // Called to create a new instance (will only be called once).
28 virtual net::URLRequestContext
* Create() = 0;
31 DISALLOW_COPY_AND_ASSIGN(ChromeURLRequestContextFactory
);
36 // ----------------------------------------------------------------------------
38 // ----------------------------------------------------------------------------
40 // Factory that creates the main URLRequestContext.
41 class FactoryForMain
: public ChromeURLRequestContextFactory
{
44 const ProfileIOData
* profile_io_data
,
45 content::ProtocolHandlerMap
* protocol_handlers
,
46 content::URLRequestInterceptorScopedVector request_interceptors
)
47 : profile_io_data_(profile_io_data
),
48 request_interceptors_(request_interceptors
.Pass()) {
49 std::swap(protocol_handlers_
, *protocol_handlers
);
52 net::URLRequestContext
* Create() override
{
53 // TODO(vadimt): Remove ScopedTracker below once crbug.com/436671 is fixed.
54 tracked_objects::ScopedTracker
tracking_profile(
55 FROM_HERE_WITH_EXPLICIT_FUNCTION("436671 FactoryForMain::Create"));
57 profile_io_data_
->Init(&protocol_handlers_
, request_interceptors_
.Pass());
58 return profile_io_data_
->GetMainRequestContext();
62 const ProfileIOData
* const profile_io_data_
;
63 content::ProtocolHandlerMap protocol_handlers_
;
64 content::URLRequestInterceptorScopedVector request_interceptors_
;
67 // Factory that creates the URLRequestContext for extensions.
68 class FactoryForExtensions
: public ChromeURLRequestContextFactory
{
70 explicit FactoryForExtensions(const ProfileIOData
* profile_io_data
)
71 : profile_io_data_(profile_io_data
) {}
73 net::URLRequestContext
* Create() override
{
74 // TODO(vadimt): Remove ScopedTracker below once crbug.com/436671 is fixed.
75 tracked_objects::ScopedTracker
tracking_profile(
76 FROM_HERE_WITH_EXPLICIT_FUNCTION(
77 "436671 FactoryForExtensions::Create"));
79 return profile_io_data_
->GetExtensionsRequestContext();
83 const ProfileIOData
* const profile_io_data_
;
86 // Factory that creates the URLRequestContext for a given isolated app.
87 class FactoryForIsolatedApp
: public ChromeURLRequestContextFactory
{
89 FactoryForIsolatedApp(
90 const ProfileIOData
* profile_io_data
,
91 const StoragePartitionDescriptor
& partition_descriptor
,
92 ChromeURLRequestContextGetter
* main_context
,
93 scoped_ptr
<ProtocolHandlerRegistry::JobInterceptorFactory
>
94 protocol_handler_interceptor
,
95 content::ProtocolHandlerMap
* protocol_handlers
,
96 content::URLRequestInterceptorScopedVector request_interceptors
)
97 : profile_io_data_(profile_io_data
),
98 partition_descriptor_(partition_descriptor
),
99 main_request_context_getter_(main_context
),
100 protocol_handler_interceptor_(protocol_handler_interceptor
.Pass()),
101 request_interceptors_(request_interceptors
.Pass()) {
102 std::swap(protocol_handlers_
, *protocol_handlers
);
105 net::URLRequestContext
* Create() override
{
106 // TODO(vadimt): Remove ScopedTracker below once crbug.com/436671 is fixed.
107 tracked_objects::ScopedTracker
tracking_profile(
108 FROM_HERE_WITH_EXPLICIT_FUNCTION(
109 "436671 FactoryForIsolatedApp::Create"));
111 // We will copy most of the state from the main request context.
113 // Note that this factory is one-shot. After Create() is called once, the
114 // factory is actually destroyed. Thus it is safe to destructively pass
116 return profile_io_data_
->GetIsolatedAppRequestContext(
117 main_request_context_getter_
->GetURLRequestContext(),
118 partition_descriptor_
,
119 protocol_handler_interceptor_
.Pass(),
121 request_interceptors_
.Pass());
125 const ProfileIOData
* const profile_io_data_
;
126 const StoragePartitionDescriptor partition_descriptor_
;
127 scoped_refptr
<ChromeURLRequestContextGetter
>
128 main_request_context_getter_
;
129 scoped_ptr
<ProtocolHandlerRegistry::JobInterceptorFactory
>
130 protocol_handler_interceptor_
;
131 content::ProtocolHandlerMap protocol_handlers_
;
132 content::URLRequestInterceptorScopedVector request_interceptors_
;
135 // Factory that creates the media URLRequestContext for a given isolated
136 // app. The media context is based on the corresponding isolated app's context.
137 class FactoryForIsolatedMedia
: public ChromeURLRequestContextFactory
{
139 FactoryForIsolatedMedia(
140 const ProfileIOData
* profile_io_data
,
141 const StoragePartitionDescriptor
& partition_descriptor
,
142 ChromeURLRequestContextGetter
* app_context
)
143 : profile_io_data_(profile_io_data
),
144 partition_descriptor_(partition_descriptor
),
145 app_context_getter_(app_context
) {}
147 net::URLRequestContext
* Create() override
{
148 // TODO(vadimt): Remove ScopedTracker below once crbug.com/436671 is fixed.
149 tracked_objects::ScopedTracker
tracking_profile(
150 FROM_HERE_WITH_EXPLICIT_FUNCTION(
151 "436671 FactoryForIsolatedMedia::Create"));
153 // We will copy most of the state from the corresopnding app's
154 // request context. We expect to have the same lifetime as
155 // the associated |app_context_getter_| so we can just reuse
156 // all its backing objects, including the
157 // |protocol_handler_interceptor|. This is why the API
158 // looks different from FactoryForIsolatedApp's.
159 return profile_io_data_
->GetIsolatedMediaRequestContext(
160 app_context_getter_
->GetURLRequestContext(), partition_descriptor_
);
164 const ProfileIOData
* const profile_io_data_
;
165 const StoragePartitionDescriptor partition_descriptor_
;
166 scoped_refptr
<ChromeURLRequestContextGetter
> app_context_getter_
;
169 // Factory that creates the URLRequestContext for media.
170 class FactoryForMedia
: public ChromeURLRequestContextFactory
{
172 explicit FactoryForMedia(const ProfileIOData
* profile_io_data
)
173 : profile_io_data_(profile_io_data
) {
176 net::URLRequestContext
* Create() override
{
177 // TODO(vadimt): Remove ScopedTracker below once crbug.com/436671 is fixed.
178 tracked_objects::ScopedTracker
tracking_profile(
179 FROM_HERE_WITH_EXPLICIT_FUNCTION("436671 FactoryForMedia::Create"));
181 return profile_io_data_
->GetMediaRequestContext();
185 const ProfileIOData
* const profile_io_data_
;
190 // ----------------------------------------------------------------------------
191 // ChromeURLRequestContextGetter
192 // ----------------------------------------------------------------------------
194 ChromeURLRequestContextGetter::ChromeURLRequestContextGetter(
195 ChromeURLRequestContextFactory
* factory
)
197 url_request_context_(NULL
) {
201 ChromeURLRequestContextGetter::~ChromeURLRequestContextGetter() {}
203 // Lazily create a URLRequestContext using our factory.
204 net::URLRequestContext
*
205 ChromeURLRequestContextGetter::GetURLRequestContext() {
206 // TODO(vadimt): Remove ScopedTracker below once crbug.com/436671 is fixed.
207 tracked_objects::ScopedTracker
tracking_profile(
208 FROM_HERE_WITH_EXPLICIT_FUNCTION(
209 "436671 ChromeURLRequestContextGetter::GetURLRequestContext"));
211 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
213 if (factory_
.get()) {
214 DCHECK(!url_request_context_
);
215 url_request_context_
= factory_
->Create();
219 // Context reference is valid, unless we're trying to use the
220 // URLRequestContextGetter after the Profile has already been deleted.
221 CHECK(url_request_context_
);
223 return url_request_context_
;
226 void ChromeURLRequestContextGetter::Invalidate() {
227 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
229 url_request_context_
= NULL
;
232 scoped_refptr
<base::SingleThreadTaskRunner
>
233 ChromeURLRequestContextGetter::GetNetworkTaskRunner() const {
234 return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO
);
238 ChromeURLRequestContextGetter
* ChromeURLRequestContextGetter::Create(
240 const ProfileIOData
* profile_io_data
,
241 content::ProtocolHandlerMap
* protocol_handlers
,
242 content::URLRequestInterceptorScopedVector request_interceptors
) {
243 return new ChromeURLRequestContextGetter(new FactoryForMain(
244 profile_io_data
, protocol_handlers
, request_interceptors
.Pass()));
248 ChromeURLRequestContextGetter
*
249 ChromeURLRequestContextGetter::CreateForMedia(
250 Profile
* profile
, const ProfileIOData
* profile_io_data
) {
251 return new ChromeURLRequestContextGetter(
252 new FactoryForMedia(profile_io_data
));
256 ChromeURLRequestContextGetter
*
257 ChromeURLRequestContextGetter::CreateForExtensions(
258 Profile
* profile
, const ProfileIOData
* profile_io_data
) {
259 return new ChromeURLRequestContextGetter(
260 new FactoryForExtensions(profile_io_data
));
264 ChromeURLRequestContextGetter
*
265 ChromeURLRequestContextGetter::CreateForIsolatedApp(
267 const ProfileIOData
* profile_io_data
,
268 const StoragePartitionDescriptor
& partition_descriptor
,
269 scoped_ptr
<ProtocolHandlerRegistry::JobInterceptorFactory
>
270 protocol_handler_interceptor
,
271 content::ProtocolHandlerMap
* protocol_handlers
,
272 content::URLRequestInterceptorScopedVector request_interceptors
) {
273 ChromeURLRequestContextGetter
* main_context
=
274 static_cast<ChromeURLRequestContextGetter
*>(profile
->GetRequestContext());
275 return new ChromeURLRequestContextGetter(
276 new FactoryForIsolatedApp(profile_io_data
,
277 partition_descriptor
,
279 protocol_handler_interceptor
.Pass(),
281 request_interceptors
.Pass()));
285 ChromeURLRequestContextGetter
*
286 ChromeURLRequestContextGetter::CreateForIsolatedMedia(
288 ChromeURLRequestContextGetter
* app_context
,
289 const ProfileIOData
* profile_io_data
,
290 const StoragePartitionDescriptor
& partition_descriptor
) {
291 return new ChromeURLRequestContextGetter(
292 new FactoryForIsolatedMedia(
293 profile_io_data
, partition_descriptor
, app_context
));