1 // Copyright (c) 2012 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.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 "chrome/browser/browser_process.h"
12 #include "chrome/browser/io_thread.h"
13 #include "chrome/browser/net/load_time_stats.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 ChromeURLRequestContext
* Create() = 0;
31 DISALLOW_COPY_AND_ASSIGN(ChromeURLRequestContextFactory
);
36 // ----------------------------------------------------------------------------
38 // ----------------------------------------------------------------------------
40 // Factory that creates the main ChromeURLRequestContext.
41 class FactoryForMain
: public ChromeURLRequestContextFactory
{
44 const ProfileIOData
* profile_io_data
,
45 content::ProtocolHandlerMap
* protocol_handlers
)
46 : profile_io_data_(profile_io_data
) {
47 std::swap(protocol_handlers_
, *protocol_handlers
);
50 virtual ChromeURLRequestContext
* Create() OVERRIDE
{
51 profile_io_data_
->Init(&protocol_handlers_
);
52 return profile_io_data_
->GetMainRequestContext();
56 const ProfileIOData
* const profile_io_data_
;
57 content::ProtocolHandlerMap protocol_handlers_
;
60 // Factory that creates the ChromeURLRequestContext for extensions.
61 class FactoryForExtensions
: public ChromeURLRequestContextFactory
{
63 explicit FactoryForExtensions(const ProfileIOData
* profile_io_data
)
64 : profile_io_data_(profile_io_data
) {}
66 virtual ChromeURLRequestContext
* Create() OVERRIDE
{
67 return profile_io_data_
->GetExtensionsRequestContext();
71 const ProfileIOData
* const profile_io_data_
;
74 // Factory that creates the ChromeURLRequestContext for a given isolated app.
75 class FactoryForIsolatedApp
: public ChromeURLRequestContextFactory
{
77 FactoryForIsolatedApp(
78 const ProfileIOData
* profile_io_data
,
79 const StoragePartitionDescriptor
& partition_descriptor
,
80 ChromeURLRequestContextGetter
* main_context
,
81 scoped_ptr
<ProtocolHandlerRegistry::JobInterceptorFactory
>
82 protocol_handler_interceptor
,
83 content::ProtocolHandlerMap
* protocol_handlers
)
84 : profile_io_data_(profile_io_data
),
85 partition_descriptor_(partition_descriptor
),
86 main_request_context_getter_(main_context
),
87 protocol_handler_interceptor_(protocol_handler_interceptor
.Pass()) {
88 std::swap(protocol_handlers_
, *protocol_handlers
);
91 virtual ChromeURLRequestContext
* Create() OVERRIDE
{
92 // We will copy most of the state from the main request context.
94 // Note that this factory is one-shot. After Create() is called once, the
95 // factory is actually destroyed. Thus it is safe to destructively pass
97 return profile_io_data_
->GetIsolatedAppRequestContext(
98 main_request_context_getter_
->GetURLRequestContext(),
99 partition_descriptor_
,
100 protocol_handler_interceptor_
.Pass(),
101 &protocol_handlers_
);
105 const ProfileIOData
* const profile_io_data_
;
106 const StoragePartitionDescriptor partition_descriptor_
;
107 scoped_refptr
<ChromeURLRequestContextGetter
>
108 main_request_context_getter_
;
109 scoped_ptr
<ProtocolHandlerRegistry::JobInterceptorFactory
>
110 protocol_handler_interceptor_
;
111 content::ProtocolHandlerMap protocol_handlers_
;
114 // Factory that creates the media ChromeURLRequestContext for a given isolated
115 // app. The media context is based on the corresponding isolated app's context.
116 class FactoryForIsolatedMedia
: public ChromeURLRequestContextFactory
{
118 FactoryForIsolatedMedia(
119 const ProfileIOData
* profile_io_data
,
120 const StoragePartitionDescriptor
& partition_descriptor
,
121 ChromeURLRequestContextGetter
* app_context
)
122 : profile_io_data_(profile_io_data
),
123 partition_descriptor_(partition_descriptor
),
124 app_context_getter_(app_context
) {}
126 virtual ChromeURLRequestContext
* Create() OVERRIDE
{
127 // We will copy most of the state from the corresopnding app's
128 // request context. We expect to have the same lifetime as
129 // the associated |app_context_getter_| so we can just reuse
130 // all its backing objects, including the
131 // |protocol_handler_interceptor|. This is why the API
132 // looks different from FactoryForIsolatedApp's.
133 return profile_io_data_
->GetIsolatedMediaRequestContext(
134 app_context_getter_
->GetURLRequestContext(), partition_descriptor_
);
138 const ProfileIOData
* const profile_io_data_
;
139 const StoragePartitionDescriptor partition_descriptor_
;
140 scoped_refptr
<ChromeURLRequestContextGetter
> app_context_getter_
;
143 // Factory that creates the ChromeURLRequestContext for media.
144 class FactoryForMedia
: public ChromeURLRequestContextFactory
{
146 explicit FactoryForMedia(const ProfileIOData
* profile_io_data
)
147 : profile_io_data_(profile_io_data
) {
150 virtual ChromeURLRequestContext
* Create() OVERRIDE
{
151 return profile_io_data_
->GetMediaRequestContext();
155 const ProfileIOData
* const profile_io_data_
;
160 // ----------------------------------------------------------------------------
161 // ChromeURLRequestContextGetter
162 // ----------------------------------------------------------------------------
164 ChromeURLRequestContextGetter::ChromeURLRequestContextGetter(
165 ChromeURLRequestContextFactory
* factory
)
166 : factory_(factory
) {
170 ChromeURLRequestContextGetter::~ChromeURLRequestContextGetter() {}
172 // Lazily create a ChromeURLRequestContext using our factory.
173 ChromeURLRequestContext
*
174 ChromeURLRequestContextGetter::GetURLRequestContext() {
175 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
177 if (!url_request_context_
.get()) {
178 DCHECK(factory_
.get());
179 url_request_context_
= factory_
->Create()->GetWeakPtr();
183 // Should not be NULL, unless we're trying to use the URLRequestContextGetter
184 // after the Profile has already been deleted.
185 CHECK(url_request_context_
.get());
187 return url_request_context_
.get();
190 scoped_refptr
<base::SingleThreadTaskRunner
>
191 ChromeURLRequestContextGetter::GetNetworkTaskRunner() const {
192 return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO
);
196 ChromeURLRequestContextGetter
* ChromeURLRequestContextGetter::CreateOriginal(
198 const ProfileIOData
* profile_io_data
,
199 content::ProtocolHandlerMap
* protocol_handlers
) {
200 DCHECK(!profile
->IsOffTheRecord());
201 return new ChromeURLRequestContextGetter(
202 new FactoryForMain(profile_io_data
, protocol_handlers
));
206 ChromeURLRequestContextGetter
*
207 ChromeURLRequestContextGetter::CreateOriginalForMedia(
208 Profile
* profile
, const ProfileIOData
* profile_io_data
) {
209 DCHECK(!profile
->IsOffTheRecord());
210 return new ChromeURLRequestContextGetter(
211 new FactoryForMedia(profile_io_data
));
215 ChromeURLRequestContextGetter
*
216 ChromeURLRequestContextGetter::CreateOriginalForExtensions(
217 Profile
* profile
, const ProfileIOData
* profile_io_data
) {
218 DCHECK(!profile
->IsOffTheRecord());
219 return new ChromeURLRequestContextGetter(
220 new FactoryForExtensions(profile_io_data
));
224 ChromeURLRequestContextGetter
*
225 ChromeURLRequestContextGetter::CreateOriginalForIsolatedApp(
227 const ProfileIOData
* profile_io_data
,
228 const StoragePartitionDescriptor
& partition_descriptor
,
229 scoped_ptr
<ProtocolHandlerRegistry::JobInterceptorFactory
>
230 protocol_handler_interceptor
,
231 content::ProtocolHandlerMap
* protocol_handlers
) {
232 DCHECK(!profile
->IsOffTheRecord());
233 ChromeURLRequestContextGetter
* main_context
=
234 static_cast<ChromeURLRequestContextGetter
*>(profile
->GetRequestContext());
235 return new ChromeURLRequestContextGetter(
236 new FactoryForIsolatedApp(profile_io_data
, partition_descriptor
,
238 protocol_handler_interceptor
.Pass(),
243 ChromeURLRequestContextGetter
*
244 ChromeURLRequestContextGetter::CreateOriginalForIsolatedMedia(
246 ChromeURLRequestContextGetter
* app_context
,
247 const ProfileIOData
* profile_io_data
,
248 const StoragePartitionDescriptor
& partition_descriptor
) {
249 DCHECK(!profile
->IsOffTheRecord());
250 return new ChromeURLRequestContextGetter(
251 new FactoryForIsolatedMedia(
252 profile_io_data
, partition_descriptor
, app_context
));
256 ChromeURLRequestContextGetter
*
257 ChromeURLRequestContextGetter::CreateOffTheRecord(
259 const ProfileIOData
* profile_io_data
,
260 content::ProtocolHandlerMap
* protocol_handlers
) {
261 DCHECK(profile
->IsOffTheRecord());
262 return new ChromeURLRequestContextGetter(
263 new FactoryForMain(profile_io_data
, protocol_handlers
));
267 ChromeURLRequestContextGetter
*
268 ChromeURLRequestContextGetter::CreateOffTheRecordForExtensions(
269 Profile
* profile
, const ProfileIOData
* profile_io_data
) {
270 DCHECK(profile
->IsOffTheRecord());
271 return new ChromeURLRequestContextGetter(
272 new FactoryForExtensions(profile_io_data
));
276 ChromeURLRequestContextGetter
*
277 ChromeURLRequestContextGetter::CreateOffTheRecordForIsolatedApp(
279 const ProfileIOData
* profile_io_data
,
280 const StoragePartitionDescriptor
& partition_descriptor
,
281 scoped_ptr
<ProtocolHandlerRegistry::JobInterceptorFactory
>
282 protocol_handler_interceptor
,
283 content::ProtocolHandlerMap
* protocol_handlers
) {
284 DCHECK(profile
->IsOffTheRecord());
285 ChromeURLRequestContextGetter
* main_context
=
286 static_cast<ChromeURLRequestContextGetter
*>(profile
->GetRequestContext());
287 return new ChromeURLRequestContextGetter(
288 new FactoryForIsolatedApp(profile_io_data
, partition_descriptor
,
290 protocol_handler_interceptor
.Pass(),
294 // ----------------------------------------------------------------------------
295 // ChromeURLRequestContext
296 // ----------------------------------------------------------------------------
298 ChromeURLRequestContext::ChromeURLRequestContext(
300 chrome_browser_net::LoadTimeStats
* load_time_stats
)
301 : weak_factory_(this),
302 load_time_stats_(load_time_stats
) {
303 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
304 if (load_time_stats_
)
305 load_time_stats_
->RegisterURLRequestContext(this, type
);
308 ChromeURLRequestContext::~ChromeURLRequestContext() {
309 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
310 if (load_time_stats_
)
311 load_time_stats_
->UnregisterURLRequestContext(this);
314 void ChromeURLRequestContext::CopyFrom(ChromeURLRequestContext
* other
) {
315 URLRequestContext::CopyFrom(other
);
317 // Copy ChromeURLRequestContext parameters.