OLD | NEW |
| (Empty) |
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. | |
4 | |
5 #include "extensions/browser/extension_url_request_context_getter.h" | |
6 | |
7 #include "base/command_line.h" | |
8 #include "base/logging.h" | |
9 #include "base/strings/string_number_conversions.h" | |
10 #include "base/strings/string_split.h" | |
11 #include "base/strings/string_util.h" | |
12 #include "base/threading/sequenced_worker_pool.h" | |
13 #include "base/threading/worker_pool.h" | |
14 #include "content/public/browser/browser_thread.h" | |
15 #include "content/public/browser/cookie_store_factory.h" | |
16 #include "content/public/browser/resource_request_info.h" | |
17 #include "content/public/common/content_switches.h" | |
18 #include "extensions/browser/extension_network_delegate.h" | |
19 #include "extensions/browser/info_map.h" | |
20 #include "extensions/common/constants.h" | |
21 #include "extensions/common/switches.h" | |
22 #include "net/base/cache_type.h" | |
23 #include "net/cert/cert_verifier.h" | |
24 #include "net/cookies/cookie_monster.h" | |
25 #include "net/dns/host_resolver.h" | |
26 #include "net/dns/mapped_host_resolver.h" | |
27 #include "net/http/http_auth_handler_factory.h" | |
28 #include "net/http/http_cache.h" | |
29 #include "net/http/http_network_session.h" | |
30 #include "net/http/http_server_properties_impl.h" | |
31 #include "net/http/transport_security_state.h" | |
32 #include "net/proxy/proxy_service.h" | |
33 #include "net/ssl/channel_id_service.h" | |
34 #include "net/ssl/default_channel_id_store.h" | |
35 #include "net/ssl/ssl_config_service_defaults.h" | |
36 #include "net/url_request/data_protocol_handler.h" | |
37 #include "net/url_request/file_protocol_handler.h" | |
38 #include "net/url_request/static_http_user_agent_settings.h" | |
39 #include "net/url_request/url_request_context.h" | |
40 #include "net/url_request/url_request_context_storage.h" | |
41 #include "net/url_request/url_request_intercepting_job_factory.h" | |
42 #include "net/url_request/url_request_job_factory_impl.h" | |
43 #include "url/url_constants.h" | |
44 | |
45 namespace extensions { | |
46 | |
47 namespace { | |
48 void InstallProtocolHandlers(net::URLRequestJobFactoryImpl* job_factory, | |
49 content::ProtocolHandlerMap* protocol_handlers) { | |
50 for (content::ProtocolHandlerMap::iterator it = | |
51 protocol_handlers->begin(); | |
52 it != protocol_handlers->end(); | |
53 ++it) { | |
54 bool set_protocol = job_factory->SetProtocolHandler( | |
55 it->first, it->second.release()); | |
56 DCHECK(set_protocol); | |
57 } | |
58 protocol_handlers->clear(); | |
59 } | |
60 | |
61 } // namespace | |
62 | |
63 ExtensionURLRequestContextGetter::ExtensionURLRequestContextGetter( | |
64 void* browser_context, | |
65 bool ignore_certificate_errors, | |
66 const base::FilePath& base_path, | |
67 base::MessageLoop* io_loop, | |
68 base::MessageLoop* file_loop, | |
69 content::ProtocolHandlerMap* protocol_handlers, | |
70 content::URLRequestInterceptorScopedVector request_interceptors, | |
71 net::NetLog* net_log, | |
72 InfoMap* extension_info_map) | |
73 : browser_context_(browser_context), | |
74 ignore_certificate_errors_(ignore_certificate_errors), | |
75 base_path_(base_path), | |
76 io_loop_(io_loop), | |
77 file_loop_(file_loop), | |
78 net_log_(net_log), | |
79 extension_info_map_(extension_info_map), | |
80 request_interceptors_(request_interceptors.Pass()) { | |
81 // Must first be created on the UI thread. | |
82 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); | |
83 std::swap(protocol_handlers_, *protocol_handlers); | |
84 | |
85 // We must create the proxy config service on the UI loop on Linux because it | |
86 // must synchronously run on the glib message loop. This will be passed to | |
87 // the URLRequestContextStorage on the IO thread in GetURLRequestContext(). | |
88 if (!CommandLine::ForCurrentProcess()->HasSwitch(switches::kDumpRenderTree)) { | |
89 proxy_config_service_.reset( | |
90 net::ProxyService::CreateSystemProxyConfigService( | |
91 io_loop_->message_loop_proxy(), file_loop_->message_loop_proxy())); | |
92 } | |
93 } | |
94 | |
95 ExtensionURLRequestContextGetter::~ExtensionURLRequestContextGetter() { | |
96 } | |
97 | |
98 net::URLRequestContext* | |
99 ExtensionURLRequestContextGetter::GetURLRequestContext() { | |
100 DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::IO)); | |
101 | |
102 if (!url_request_context_) { | |
103 const CommandLine& command_line = *CommandLine::ForCurrentProcess(); | |
104 | |
105 url_request_context_.reset(new net::URLRequestContext()); | |
106 url_request_context_->set_net_log(net_log_); | |
107 network_delegate_.reset( | |
108 new ExtensionNetworkDelegate(browser_context_, extension_info_map_)); | |
109 if (command_line.HasSwitch(switches::kDumpRenderTree)) | |
110 ExtensionNetworkDelegate::SetAcceptAllCookies(false); | |
111 url_request_context_->set_network_delegate(network_delegate_.get()); | |
112 storage_.reset( | |
113 new net::URLRequestContextStorage(url_request_context_.get())); | |
114 storage_->set_cookie_store(CreateCookieStore(content::CookieStoreConfig())); | |
115 storage_->set_channel_id_service(new net::ChannelIDService( | |
116 new net::DefaultChannelIDStore(NULL), | |
117 base::WorkerPool::GetTaskRunner(true))); | |
118 | |
119 scoped_ptr<net::HostResolver> host_resolver( | |
120 net::HostResolver::CreateDefaultResolver( | |
121 url_request_context_->net_log())); | |
122 | |
123 storage_->set_cert_verifier(net::CertVerifier::CreateDefault()); | |
124 storage_->set_transport_security_state(new net::TransportSecurityState); | |
125 if (command_line.HasSwitch(switches::kDumpRenderTree)) { | |
126 storage_->set_proxy_service(net::ProxyService::CreateDirect()); | |
127 } else { | |
128 // TODO(jam): use v8 if possible, look at chrome code. | |
129 storage_->set_proxy_service( | |
130 net::ProxyService::CreateUsingSystemProxyResolver( | |
131 proxy_config_service_.release(), | |
132 0, | |
133 url_request_context_->net_log())); | |
134 } | |
135 storage_->set_ssl_config_service(new net::SSLConfigServiceDefaults); | |
136 storage_->set_http_auth_handler_factory( | |
137 net::HttpAuthHandlerFactory::CreateDefault(host_resolver.get())); | |
138 storage_->set_http_server_properties( | |
139 scoped_ptr<net::HttpServerProperties>( | |
140 new net::HttpServerPropertiesImpl())); | |
141 | |
142 base::FilePath cache_path = base_path_.Append(FILE_PATH_LITERAL("Cache")); | |
143 net::HttpCache::DefaultBackend* main_backend = | |
144 new net::HttpCache::DefaultBackend( | |
145 net::DISK_CACHE, | |
146 #if defined(OS_ANDROID) | |
147 // TODO(rdsmith): Remove when default backend for Android is | |
148 // changed to simple cache. | |
149 net::CACHE_BACKEND_SIMPLE, | |
150 #else | |
151 net::CACHE_BACKEND_DEFAULT, | |
152 #endif | |
153 cache_path, | |
154 0, | |
155 content::BrowserThread::GetMessageLoopProxyForThread( | |
156 content::BrowserThread::CACHE)); | |
157 | |
158 net::HttpNetworkSession::Params network_session_params; | |
159 network_session_params.cert_verifier = | |
160 url_request_context_->cert_verifier(); | |
161 network_session_params.transport_security_state = | |
162 url_request_context_->transport_security_state(); | |
163 network_session_params.channel_id_service = | |
164 url_request_context_->channel_id_service(); | |
165 network_session_params.proxy_service = | |
166 url_request_context_->proxy_service(); | |
167 network_session_params.ssl_config_service = | |
168 url_request_context_->ssl_config_service(); | |
169 network_session_params.http_auth_handler_factory = | |
170 url_request_context_->http_auth_handler_factory(); | |
171 network_session_params.network_delegate = | |
172 network_delegate_.get(); | |
173 network_session_params.http_server_properties = | |
174 url_request_context_->http_server_properties(); | |
175 network_session_params.net_log = | |
176 url_request_context_->net_log(); | |
177 network_session_params.ignore_certificate_errors = | |
178 ignore_certificate_errors_; | |
179 if (command_line.HasSwitch(::switches::kTestingFixedHttpPort)) { | |
180 int value; | |
181 base::StringToInt(command_line.GetSwitchValueASCII( | |
182 ::switches::kTestingFixedHttpPort), &value); | |
183 network_session_params.testing_fixed_http_port = value; | |
184 } | |
185 if (command_line.HasSwitch(::switches::kTestingFixedHttpsPort)) { | |
186 int value; | |
187 base::StringToInt(command_line.GetSwitchValueASCII( | |
188 ::switches::kTestingFixedHttpsPort), &value); | |
189 network_session_params.testing_fixed_https_port = value; | |
190 } | |
191 if (command_line.HasSwitch(::switches::kHostResolverRules)) { | |
192 scoped_ptr<net::MappedHostResolver> mapped_host_resolver( | |
193 new net::MappedHostResolver(host_resolver.Pass())); | |
194 mapped_host_resolver->SetRulesFromString( | |
195 command_line.GetSwitchValueASCII(::switches::kHostResolverRules)); | |
196 host_resolver = mapped_host_resolver.Pass(); | |
197 } | |
198 | |
199 // Give |storage_| ownership at the end in case it's |mapped_host_resolver|. | |
200 storage_->set_host_resolver(host_resolver.Pass()); | |
201 network_session_params.host_resolver = | |
202 url_request_context_->host_resolver(); | |
203 | |
204 net::HttpCache* main_cache = new net::HttpCache( | |
205 network_session_params, main_backend); | |
206 storage_->set_http_transaction_factory(main_cache); | |
207 | |
208 scoped_ptr<net::URLRequestJobFactoryImpl> job_factory( | |
209 new net::URLRequestJobFactoryImpl()); | |
210 // Keep ProtocolHandlers added in sync with | |
211 // ShellContentBrowserClient::IsHandledURL(). | |
212 InstallProtocolHandlers(job_factory.get(), &protocol_handlers_); | |
213 bool set_protocol = job_factory->SetProtocolHandler( | |
214 url::kDataScheme, new net::DataProtocolHandler); | |
215 DCHECK(set_protocol); | |
216 #if !defined(DISABLE_FILE_SUPPORT) | |
217 set_protocol = job_factory->SetProtocolHandler( | |
218 url::kFileScheme, | |
219 new net::FileProtocolHandler( | |
220 content::BrowserThread::GetBlockingPool()-> | |
221 GetTaskRunnerWithShutdownBehavior( | |
222 base::SequencedWorkerPool::SKIP_ON_SHUTDOWN))); | |
223 DCHECK(set_protocol); | |
224 #endif | |
225 | |
226 // Set up interceptors in the reverse order. | |
227 scoped_ptr<net::URLRequestJobFactory> top_job_factory = | |
228 job_factory.PassAs<net::URLRequestJobFactory>(); | |
229 for (content::URLRequestInterceptorScopedVector::reverse_iterator i = | |
230 request_interceptors_.rbegin(); | |
231 i != request_interceptors_.rend(); | |
232 ++i) { | |
233 top_job_factory.reset(new net::URLRequestInterceptingJobFactory( | |
234 top_job_factory.Pass(), make_scoped_ptr(*i))); | |
235 } | |
236 request_interceptors_.weak_clear(); | |
237 | |
238 storage_->set_job_factory(top_job_factory.release()); | |
239 } | |
240 | |
241 return url_request_context_.get(); | |
242 } | |
243 | |
244 scoped_refptr<base::SingleThreadTaskRunner> | |
245 ExtensionURLRequestContextGetter::GetNetworkTaskRunner() const { | |
246 return content::BrowserThread::GetMessageLoopProxyForThread( | |
247 content::BrowserThread::IO); | |
248 } | |
249 | |
250 } // namespace extensions | |
OLD | NEW |