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
{
43 const ProfileIOData
* profile_io_data
,
44 content::ProtocolHandlerMap
* protocol_handlers
)
45 : profile_io_data_(profile_io_data
) {
46 std::swap(protocol_handlers_
, *protocol_handlers
);
49 virtual ChromeURLRequestContext
* Create() OVERRIDE
{
50 profile_io_data_
->Init(&protocol_handlers_
);
51 return profile_io_data_
->GetMainRequestContext();
55 const ProfileIOData
* const profile_io_data_
;
56 content::ProtocolHandlerMap protocol_handlers_
;
59 // Factory that creates the ChromeURLRequestContext for extensions.
60 class FactoryForExtensions
: public ChromeURLRequestContextFactory
{
62 explicit FactoryForExtensions(const ProfileIOData
* profile_io_data
)
63 : profile_io_data_(profile_io_data
) {}
65 virtual ChromeURLRequestContext
* Create() OVERRIDE
{
66 return profile_io_data_
->GetExtensionsRequestContext();
70 const ProfileIOData
* const profile_io_data_
;
73 // Factory that creates the ChromeURLRequestContext for a given isolated app.
74 class FactoryForIsolatedApp
: public ChromeURLRequestContextFactory
{
76 FactoryForIsolatedApp(
77 const ProfileIOData
* profile_io_data
,
78 const StoragePartitionDescriptor
& partition_descriptor
,
79 ChromeURLRequestContextGetter
* main_context
,
80 scoped_ptr
<ProtocolHandlerRegistry::JobInterceptorFactory
>
81 protocol_handler_interceptor
,
82 content::ProtocolHandlerMap
* protocol_handlers
)
83 : profile_io_data_(profile_io_data
),
84 partition_descriptor_(partition_descriptor
),
85 main_request_context_getter_(main_context
),
86 protocol_handler_interceptor_(protocol_handler_interceptor
.Pass()) {
87 std::swap(protocol_handlers_
, *protocol_handlers
);
90 virtual ChromeURLRequestContext
* Create() OVERRIDE
{
91 // We will copy most of the state from the main request context.
93 // Note that this factory is one-shot. After Create() is called once, the
94 // factory is actually destroyed. Thus it is safe to destructively pass
96 return profile_io_data_
->GetIsolatedAppRequestContext(
97 main_request_context_getter_
->GetURLRequestContext(),
98 partition_descriptor_
,
99 protocol_handler_interceptor_
.Pass(),
100 &protocol_handlers_
);
104 const ProfileIOData
* const profile_io_data_
;
105 const StoragePartitionDescriptor partition_descriptor_
;
106 scoped_refptr
<ChromeURLRequestContextGetter
>
107 main_request_context_getter_
;
108 scoped_ptr
<ProtocolHandlerRegistry::JobInterceptorFactory
>
109 protocol_handler_interceptor_
;
110 content::ProtocolHandlerMap protocol_handlers_
;
113 // Factory that creates the media ChromeURLRequestContext for a given isolated
114 // app. The media context is based on the corresponding isolated app's context.
115 class FactoryForIsolatedMedia
: public ChromeURLRequestContextFactory
{
117 FactoryForIsolatedMedia(
118 const ProfileIOData
* profile_io_data
,
119 const StoragePartitionDescriptor
& partition_descriptor
,
120 ChromeURLRequestContextGetter
* app_context
)
121 : profile_io_data_(profile_io_data
),
122 partition_descriptor_(partition_descriptor
),
123 app_context_getter_(app_context
) {}
125 virtual ChromeURLRequestContext
* Create() OVERRIDE
{
126 // We will copy most of the state from the corresopnding app's
127 // request context. We expect to have the same lifetime as
128 // the associated |app_context_getter_| so we can just reuse
129 // all its backing objects, including the
130 // |protocol_handler_interceptor|. This is why the API
131 // looks different from FactoryForIsolatedApp's.
132 return profile_io_data_
->GetIsolatedMediaRequestContext(
133 app_context_getter_
->GetURLRequestContext(), partition_descriptor_
);
137 const ProfileIOData
* const profile_io_data_
;
138 const StoragePartitionDescriptor partition_descriptor_
;
139 scoped_refptr
<ChromeURLRequestContextGetter
> app_context_getter_
;
142 // Factory that creates the ChromeURLRequestContext for media.
143 class FactoryForMedia
: public ChromeURLRequestContextFactory
{
145 explicit FactoryForMedia(const ProfileIOData
* profile_io_data
)
146 : profile_io_data_(profile_io_data
) {
149 virtual ChromeURLRequestContext
* Create() OVERRIDE
{
150 return profile_io_data_
->GetMediaRequestContext();
154 const ProfileIOData
* const profile_io_data_
;
159 // ----------------------------------------------------------------------------
160 // ChromeURLRequestContextGetter
161 // ----------------------------------------------------------------------------
163 ChromeURLRequestContextGetter::ChromeURLRequestContextGetter(
164 ChromeURLRequestContextFactory
* factory
)
165 : factory_(factory
) {
169 ChromeURLRequestContextGetter::~ChromeURLRequestContextGetter() {}
171 // Lazily create a ChromeURLRequestContext using our factory.
172 ChromeURLRequestContext
*
173 ChromeURLRequestContextGetter::GetURLRequestContext() {
174 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
176 if (!url_request_context_
.get()) {
177 DCHECK(factory_
.get());
178 url_request_context_
= factory_
->Create()->GetWeakPtr();
182 // Should not be NULL, unless we're trying to use the URLRequestContextGetter
183 // after the Profile has already been deleted.
184 CHECK(url_request_context_
.get());
186 return url_request_context_
.get();
189 scoped_refptr
<base::SingleThreadTaskRunner
>
190 ChromeURLRequestContextGetter::GetNetworkTaskRunner() const {
191 return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO
);
195 ChromeURLRequestContextGetter
* ChromeURLRequestContextGetter::Create(
197 const ProfileIOData
* profile_io_data
,
198 content::ProtocolHandlerMap
* protocol_handlers
) {
199 return new ChromeURLRequestContextGetter(
200 new FactoryForMain(profile_io_data
, protocol_handlers
));
204 ChromeURLRequestContextGetter
*
205 ChromeURLRequestContextGetter::CreateForMedia(
206 Profile
* profile
, const ProfileIOData
* profile_io_data
) {
207 return new ChromeURLRequestContextGetter(
208 new FactoryForMedia(profile_io_data
));
212 ChromeURLRequestContextGetter
*
213 ChromeURLRequestContextGetter::CreateForExtensions(
214 Profile
* profile
, const ProfileIOData
* profile_io_data
) {
215 return new ChromeURLRequestContextGetter(
216 new FactoryForExtensions(profile_io_data
));
220 ChromeURLRequestContextGetter
*
221 ChromeURLRequestContextGetter::CreateForIsolatedApp(
223 const ProfileIOData
* profile_io_data
,
224 const StoragePartitionDescriptor
& partition_descriptor
,
225 scoped_ptr
<ProtocolHandlerRegistry::JobInterceptorFactory
>
226 protocol_handler_interceptor
,
227 content::ProtocolHandlerMap
* protocol_handlers
) {
228 ChromeURLRequestContextGetter
* main_context
=
229 static_cast<ChromeURLRequestContextGetter
*>(profile
->GetRequestContext());
230 return new ChromeURLRequestContextGetter(
231 new FactoryForIsolatedApp(profile_io_data
, partition_descriptor
,
233 protocol_handler_interceptor
.Pass(),
238 ChromeURLRequestContextGetter
*
239 ChromeURLRequestContextGetter::CreateForIsolatedMedia(
241 ChromeURLRequestContextGetter
* app_context
,
242 const ProfileIOData
* profile_io_data
,
243 const StoragePartitionDescriptor
& partition_descriptor
) {
244 return new ChromeURLRequestContextGetter(
245 new FactoryForIsolatedMedia(
246 profile_io_data
, partition_descriptor
, app_context
));
249 // ----------------------------------------------------------------------------
250 // ChromeURLRequestContext
251 // ----------------------------------------------------------------------------
253 ChromeURLRequestContext::ChromeURLRequestContext()
254 : weak_factory_(this) {
255 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
258 ChromeURLRequestContext::~ChromeURLRequestContext() {
259 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO
));
262 void ChromeURLRequestContext::CopyFrom(ChromeURLRequestContext
* other
) {
263 URLRequestContext::CopyFrom(other
);
265 // Copy ChromeURLRequestContext parameters.