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 "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 virtual 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 virtual 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 virtual 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 virtual 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 virtual 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_(NULL) {
177 ChromeURLRequestContextGetter::~ChromeURLRequestContextGetter() {}
179 // Lazily create a URLRequestContext using our factory.
180 net::URLRequestContext*
181 ChromeURLRequestContextGetter::GetURLRequestContext() {
182 DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
184 if (factory_.get()) {
185 DCHECK(!url_request_context_);
186 url_request_context_ = factory_->Create();
190 // Context reference is valid, unless we're trying to use the
191 // URLRequestContextGetter after the Profile has already been deleted.
192 CHECK(url_request_context_);
194 return url_request_context_;
197 scoped_refptr<base::SingleThreadTaskRunner>
198 ChromeURLRequestContextGetter::GetNetworkTaskRunner() const {
199 return BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO);
203 ChromeURLRequestContextGetter* ChromeURLRequestContextGetter::Create(
205 const ProfileIOData* profile_io_data,
206 content::ProtocolHandlerMap* protocol_handlers,
207 content::URLRequestInterceptorScopedVector request_interceptors) {
208 return new ChromeURLRequestContextGetter(new FactoryForMain(
209 profile_io_data, protocol_handlers, request_interceptors.Pass()));
213 ChromeURLRequestContextGetter*
214 ChromeURLRequestContextGetter::CreateForMedia(
215 Profile* profile, const ProfileIOData* profile_io_data) {
216 return new ChromeURLRequestContextGetter(
217 new FactoryForMedia(profile_io_data));
221 ChromeURLRequestContextGetter*
222 ChromeURLRequestContextGetter::CreateForExtensions(
223 Profile* profile, const ProfileIOData* profile_io_data) {
224 return new ChromeURLRequestContextGetter(
225 new FactoryForExtensions(profile_io_data));
229 ChromeURLRequestContextGetter*
230 ChromeURLRequestContextGetter::CreateForIsolatedApp(
232 const ProfileIOData* profile_io_data,
233 const StoragePartitionDescriptor& partition_descriptor,
234 scoped_ptr<ProtocolHandlerRegistry::JobInterceptorFactory>
235 protocol_handler_interceptor,
236 content::ProtocolHandlerMap* protocol_handlers,
237 content::URLRequestInterceptorScopedVector request_interceptors) {
238 ChromeURLRequestContextGetter* main_context =
239 static_cast<ChromeURLRequestContextGetter*>(profile->GetRequestContext());
240 return new ChromeURLRequestContextGetter(
241 new FactoryForIsolatedApp(profile_io_data,
242 partition_descriptor,
244 protocol_handler_interceptor.Pass(),
246 request_interceptors.Pass()));
250 ChromeURLRequestContextGetter*
251 ChromeURLRequestContextGetter::CreateForIsolatedMedia(
253 ChromeURLRequestContextGetter* app_context,
254 const ProfileIOData* profile_io_data,
255 const StoragePartitionDescriptor& partition_descriptor) {
256 return new ChromeURLRequestContextGetter(
257 new FactoryForIsolatedMedia(
258 profile_io_data, partition_descriptor, app_context));