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/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 ChromeURLRequestContext
* Create() = 0;
30 DISALLOW_COPY_AND_ASSIGN(ChromeURLRequestContextFactory
);
35 // ----------------------------------------------------------------------------
37 // ----------------------------------------------------------------------------
39 // Factory that creates the main ChromeURLRequestContext.
40 class FactoryForMain
: public ChromeURLRequestContextFactory
{
42 FactoryForMain(const ProfileIOData
* profile_io_data
,
43 content::ProtocolHandlerMap
* protocol_handlers
,
44 content::ProtocolHandlerScopedVector protocol_interceptors
)
45 : profile_io_data_(profile_io_data
),
46 protocol_interceptors_(protocol_interceptors
.Pass()) {
47 std::swap(protocol_handlers_
, *protocol_handlers
);
50 virtual ChromeURLRequestContext
* Create() OVERRIDE
{
51 profile_io_data_
->Init(&protocol_handlers_
, protocol_interceptors_
.Pass());
52 return profile_io_data_
->GetMainRequestContext();
56 const ProfileIOData
* const profile_io_data_
;
57 content::ProtocolHandlerMap protocol_handlers_
;
58 content::ProtocolHandlerScopedVector protocol_interceptors_
;
61 // Factory that creates the ChromeURLRequestContext for extensions.
62 class FactoryForExtensions
: public ChromeURLRequestContextFactory
{
64 explicit FactoryForExtensions(const ProfileIOData
* profile_io_data
)
65 : profile_io_data_(profile_io_data
) {}
67 virtual ChromeURLRequestContext
* Create() OVERRIDE
{
68 return profile_io_data_
->GetExtensionsRequestContext();
72 const ProfileIOData
* const profile_io_data_
;
75 // Factory that creates the ChromeURLRequestContext for a given isolated app.
76 class FactoryForIsolatedApp
: public ChromeURLRequestContextFactory
{
78 FactoryForIsolatedApp(
79 const ProfileIOData
* profile_io_data
,
80 const StoragePartitionDescriptor
& partition_descriptor
,
81 ChromeURLRequestContextGetter
* main_context
,
82 scoped_ptr
<ProtocolHandlerRegistry::JobInterceptorFactory
>
83 protocol_handler_interceptor
,
84 content::ProtocolHandlerMap
* protocol_handlers
,
85 content::ProtocolHandlerScopedVector protocol_interceptors
)
86 : profile_io_data_(profile_io_data
),
87 partition_descriptor_(partition_descriptor
),
88 main_request_context_getter_(main_context
),
89 protocol_handler_interceptor_(protocol_handler_interceptor
.Pass()),
90 protocol_interceptors_(protocol_interceptors
.Pass()) {
91 std::swap(protocol_handlers_
, *protocol_handlers
);
94 virtual ChromeURLRequestContext
* Create() OVERRIDE
{
95 // We will copy most of the state from the main request context.
97 // Note that this factory is one-shot. After Create() is called once, the
98 // factory is actually destroyed. Thus it is safe to destructively pass
100 return profile_io_data_
->GetIsolatedAppRequestContext(
101 main_request_context_getter_
->GetURLRequestContext(),
102 partition_descriptor_
,
103 protocol_handler_interceptor_
.Pass(),
105 protocol_interceptors_
.Pass());
109 const ProfileIOData
* const profile_io_data_
;
110 const StoragePartitionDescriptor partition_descriptor_
;
111 scoped_refptr
<ChromeURLRequestContextGetter
>
112 main_request_context_getter_
;
113 scoped_ptr
<ProtocolHandlerRegistry::JobInterceptorFactory
>
114 protocol_handler_interceptor_
;
115 content::ProtocolHandlerMap protocol_handlers_
;
116 content::ProtocolHandlerScopedVector protocol_interceptors_
;
119 // Factory that creates the media ChromeURLRequestContext for a given isolated
120 // app. The media context is based on the corresponding isolated app's context.
121 class FactoryForIsolatedMedia
: public ChromeURLRequestContextFactory
{
123 FactoryForIsolatedMedia(
124 const ProfileIOData
* profile_io_data
,
125 const StoragePartitionDescriptor
& partition_descriptor
,
126 ChromeURLRequestContextGetter
* app_context
)
127 : profile_io_data_(profile_io_data
),
128 partition_descriptor_(partition_descriptor
),
129 app_context_getter_(app_context
) {}
131 virtual ChromeURLRequestContext
* Create() OVERRIDE
{
132 // We will copy most of the state from the corresopnding app's
133 // request context. We expect to have the same lifetime as
134 // the associated |app_context_getter_| so we can just reuse
135 // all its backing objects, including the
136 // |protocol_handler_interceptor|. This is why the API
137 // looks different from FactoryForIsolatedApp's.
138 return profile_io_data_
->GetIsolatedMediaRequestContext(
139 app_context_getter_
->GetURLRequestContext(), partition_descriptor_
);
143 const ProfileIOData
* const profile_io_data_
;
144 const StoragePartitionDescriptor partition_descriptor_
;
145 scoped_refptr
<ChromeURLRequestContextGetter
> app_context_getter_
;
148 // Factory that creates the ChromeURLRequestContext for media.
149 class FactoryForMedia
: public ChromeURLRequestContextFactory
{
151 explicit FactoryForMedia(const ProfileIOData
* profile_io_data
)
152 : profile_io_data_(profile_io_data
) {
155 virtual ChromeURLRequestContext
* Create() OVERRIDE
{
156 return profile_io_data_
->GetMediaRequestContext();
160 const ProfileIOData
* const profile_io_data_
;
165 // ----------------------------------------------------------------------------
166 // ChromeURLRequestContextGetter
167 // ----------------------------------------------------------------------------
169 ChromeURLRequestContextGetter::ChromeURLRequestContextGetter(
170 ChromeURLRequestContextFactory
* factory
)
171 : factory_(factory
) {
175 ChromeURLRequestContextGetter::~ChromeURLRequestContextGetter() {}
177 // Lazily create a ChromeURLRequestContext using our factory.
178 ChromeURLRequestContext
*
179 ChromeURLRequestContextGetter::GetURLRequestContext() {
180 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
182 if (!url_request_context_
.get()) {
183 DCHECK(factory_
.get());
184 url_request_context_
= factory_
->Create()->GetWeakPtr();
188 // Should not be NULL, unless we're trying to use the URLRequestContextGetter
189 // after the Profile has already been deleted.
190 CHECK(url_request_context_
.get());
192 return url_request_context_
.get();
195 scoped_refptr
<base::SingleThreadTaskRunner
>
196 ChromeURLRequestContextGetter::GetNetworkTaskRunner() const {
197 return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO
);
201 ChromeURLRequestContextGetter
* ChromeURLRequestContextGetter::Create(
203 const ProfileIOData
* profile_io_data
,
204 content::ProtocolHandlerMap
* protocol_handlers
,
205 content::ProtocolHandlerScopedVector protocol_interceptors
) {
206 return new ChromeURLRequestContextGetter(new FactoryForMain(
207 profile_io_data
, protocol_handlers
, protocol_interceptors
.Pass()));
211 ChromeURLRequestContextGetter
*
212 ChromeURLRequestContextGetter::CreateForMedia(
213 Profile
* profile
, const ProfileIOData
* profile_io_data
) {
214 return new ChromeURLRequestContextGetter(
215 new FactoryForMedia(profile_io_data
));
219 ChromeURLRequestContextGetter
*
220 ChromeURLRequestContextGetter::CreateForExtensions(
221 Profile
* profile
, const ProfileIOData
* profile_io_data
) {
222 return new ChromeURLRequestContextGetter(
223 new FactoryForExtensions(profile_io_data
));
227 ChromeURLRequestContextGetter
*
228 ChromeURLRequestContextGetter::CreateForIsolatedApp(
230 const ProfileIOData
* profile_io_data
,
231 const StoragePartitionDescriptor
& partition_descriptor
,
232 scoped_ptr
<ProtocolHandlerRegistry::JobInterceptorFactory
>
233 protocol_handler_interceptor
,
234 content::ProtocolHandlerMap
* protocol_handlers
,
235 content::ProtocolHandlerScopedVector protocol_interceptors
) {
236 ChromeURLRequestContextGetter
* main_context
=
237 static_cast<ChromeURLRequestContextGetter
*>(profile
->GetRequestContext());
238 return new ChromeURLRequestContextGetter(
239 new FactoryForIsolatedApp(profile_io_data
,
240 partition_descriptor
,
242 protocol_handler_interceptor
.Pass(),
244 protocol_interceptors
.Pass()));
248 ChromeURLRequestContextGetter
*
249 ChromeURLRequestContextGetter::CreateForIsolatedMedia(
251 ChromeURLRequestContextGetter
* app_context
,
252 const ProfileIOData
* profile_io_data
,
253 const StoragePartitionDescriptor
& partition_descriptor
) {
254 return new ChromeURLRequestContextGetter(
255 new FactoryForIsolatedMedia(
256 profile_io_data
, partition_descriptor
, app_context
));
259 // ----------------------------------------------------------------------------
260 // ChromeURLRequestContext
261 // ----------------------------------------------------------------------------
263 ChromeURLRequestContext::ChromeURLRequestContext()
264 : weak_factory_(this) {
265 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
268 ChromeURLRequestContext::~ChromeURLRequestContext() {
269 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
272 void ChromeURLRequestContext::CopyFrom(ChromeURLRequestContext
* other
) {
273 URLRequestContext::CopyFrom(other
);
275 // Copy ChromeURLRequestContext parameters.