Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(119)

Side by Side Diff: components/cronet/ios/cronet_environment.cc

Issue 2513023002: [Cronet] Add CookieStoreIOS. (Closed)
Patch Set: . Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « components/cronet/ios/cronet_environment.h ('k') | components/cronet/ios/cronet_environment.mm » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2016 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 "components/cronet/ios/cronet_environment.h"
6
7 #include <utility>
8
9 #include "base/at_exit.h"
10 #include "base/atomicops.h"
11 #include "base/command_line.h"
12 #include "base/feature_list.h"
13 #include "base/files/file_path.h"
14 #include "base/files/file_util.h"
15 #include "base/files/scoped_file.h"
16 #include "base/json/json_writer.h"
17 #include "base/mac/bind_objc_block.h"
18 #include "base/mac/foundation_util.h"
19 #include "base/macros.h"
20 #include "base/memory/ptr_util.h"
21 #include "base/metrics/statistics_recorder.h"
22 #include "base/path_service.h"
23 #include "base/single_thread_task_runner.h"
24 #include "base/synchronization/waitable_event.h"
25 #include "base/threading/worker_pool.h"
26 #include "components/cronet/histogram_manager.h"
27 #include "components/cronet/ios/version.h"
28 #include "components/prefs/json_pref_store.h"
29 #include "components/prefs/pref_filter.h"
30 #include "ios/web/public/user_agent.h"
31 #include "net/base/net_errors.h"
32 #include "net/base/network_change_notifier.h"
33 #include "net/cert/cert_verifier.h"
34 #include "net/cert/ct_known_logs.h"
35 #include "net/cert/ct_log_verifier.h"
36 #include "net/cert/ct_policy_enforcer.h"
37 #include "net/cert/ct_verifier.h"
38 #include "net/cert/multi_log_ct_verifier.h"
39 #include "net/dns/host_resolver.h"
40 #include "net/dns/mapped_host_resolver.h"
41 #include "net/http/http_auth_handler_factory.h"
42 #include "net/http/http_cache.h"
43 #include "net/http/http_response_headers.h"
44 #include "net/http/http_server_properties_impl.h"
45 #include "net/http/http_stream_factory.h"
46 #include "net/http/http_util.h"
47 #include "net/log/net_log.h"
48 #include "net/log/net_log_capture_mode.h"
49 #include "net/log/write_to_file_net_log_observer.h"
50 #include "net/proxy/proxy_service.h"
51 #include "net/socket/ssl_client_socket.h"
52 #include "net/ssl/channel_id_service.h"
53 #include "net/ssl/default_channel_id_store.h"
54 #include "net/ssl/ssl_config_service_defaults.h"
55 #include "net/url_request/static_http_user_agent_settings.h"
56 #include "net/url_request/url_request_context_storage.h"
57 #include "net/url_request/url_request_job_factory_impl.h"
58 #include "url/scheme_host_port.h"
59 #include "url/url_util.h"
60
61 namespace {
62
63 base::AtExitManager* g_at_exit_ = nullptr;
64 net::NetworkChangeNotifier* g_network_change_notifier = nullptr;
65 // MessageLoop on the main thread.
66 base::MessageLoop* g_main_message_loop = nullptr;
67
68 // Request context getter for Cronet.
69 class CronetURLRequestContextGetter : public net::URLRequestContextGetter {
70 public:
71 CronetURLRequestContextGetter(
72 cronet::CronetEnvironment* environment,
73 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner)
74 : environment_(environment), task_runner_(task_runner) {}
75
76 net::URLRequestContext* GetURLRequestContext() override {
77 DCHECK(environment_);
78 return environment_->GetURLRequestContext();
79 }
80
81 scoped_refptr<base::SingleThreadTaskRunner> GetNetworkTaskRunner()
82 const override {
83 return task_runner_;
84 }
85
86 private:
87 // Must be called on the IO thread.
88 ~CronetURLRequestContextGetter() override {}
89
90 cronet::CronetEnvironment* environment_;
91 scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
92 DISALLOW_COPY_AND_ASSIGN(CronetURLRequestContextGetter);
93 };
94
95 } // namespace
96
97 namespace cronet {
98
99 void CronetEnvironment::PostToNetworkThread(
100 const tracked_objects::Location& from_here,
101 const base::Closure& task) {
102 network_io_thread_->task_runner()->PostTask(from_here, task);
103 }
104
105 void CronetEnvironment::PostToFileUserBlockingThread(
106 const tracked_objects::Location& from_here,
107 const base::Closure& task) {
108 file_user_blocking_thread_->task_runner()->PostTask(from_here, task);
109 }
110
111 net::URLRequestContext* CronetEnvironment::GetURLRequestContext() const {
112 return main_context_.get();
113 }
114
115 net::URLRequestContextGetter* CronetEnvironment::GetURLRequestContextGetter()
116 const {
117 return main_context_getter_.get();
118 }
119
120 // static
121 void CronetEnvironment::Initialize() {
122 // DCHECK_EQ([NSThread currentThread], [NSThread mainThread]);
123 // This method must be called once from the main thread.
124 if (!g_at_exit_)
125 g_at_exit_ = new base::AtExitManager;
126
127 url::Initialize();
128 base::CommandLine::Init(0, nullptr);
129
130 // Without doing this, StatisticsRecorder::FactoryGet() leaks one histogram
131 // per call after the first for a given name.
132 base::StatisticsRecorder::Initialize();
133
134 // Create a message loop on the UI thread.
135 DCHECK(!base::MessageLoop::current());
136 DCHECK(!g_main_message_loop);
137 g_main_message_loop = new base::MessageLoopForUI();
138 base::MessageLoopForUI::current()->Attach();
139 // The network change notifier must be initialized so that registered
140 // delegates will receive callbacks.
141 DCHECK(!g_network_change_notifier);
142 g_network_change_notifier = net::NetworkChangeNotifier::Create();
143 }
144
145 void CronetEnvironment::StartNetLog(base::FilePath::StringType file_name,
146 bool log_bytes) {
147 DCHECK(file_name.length());
148 PostToNetworkThread(FROM_HERE,
149 base::Bind(&CronetEnvironment::StartNetLogOnNetworkThread,
150 base::Unretained(this), file_name, log_bytes));
151 }
152
153 void CronetEnvironment::StartNetLogOnNetworkThread(
154 const base::FilePath::StringType& file_name,
155 bool log_bytes) {
156 DCHECK(file_name.length());
157 DCHECK(net_log_);
158
159 if (net_log_observer_)
160 return;
161
162 base::FilePath files_root;
163 if (!PathService::Get(base::DIR_HOME, &files_root))
164 return;
165
166 base::FilePath full_path = files_root.Append(file_name);
167 base::ScopedFILE file(base::OpenFile(full_path, "w"));
168 if (!file) {
169 LOG(ERROR) << "Can not start NetLog to " << full_path.value();
170 return;
171 }
172
173 net::NetLogCaptureMode capture_mode =
174 log_bytes ? net::NetLogCaptureMode::IncludeSocketBytes()
175 : net::NetLogCaptureMode::Default();
176
177 net_log_observer_.reset(new net::WriteToFileNetLogObserver());
178 net_log_observer_->set_capture_mode(capture_mode);
179 net_log_observer_->StartObserving(main_context_->net_log(), std::move(file),
180 nullptr, main_context_.get());
181 LOG(WARNING) << "Started NetLog to " << full_path.value();
182 }
183
184 void CronetEnvironment::StopNetLog() {
185 base::WaitableEvent log_stopped_event(
186 base::WaitableEvent::ResetPolicy::MANUAL,
187 base::WaitableEvent::InitialState::NOT_SIGNALED);
188 PostToNetworkThread(FROM_HERE,
189 base::Bind(&CronetEnvironment::StopNetLogOnNetworkThread,
190 base::Unretained(this), &log_stopped_event));
191 log_stopped_event.Wait();
192 }
193
194 void CronetEnvironment::StopNetLogOnNetworkThread(
195 base::WaitableEvent* log_stopped_event) {
196 if (net_log_observer_) {
197 DLOG(WARNING) << "Stopped NetLog.";
198 net_log_observer_->StopObserving(main_context_.get());
199 net_log_observer_.reset();
200 }
201 log_stopped_event->Signal();
202 }
203
204 net::HttpNetworkSession* CronetEnvironment::GetHttpNetworkSession(
205 net::URLRequestContext* context) {
206 DCHECK(context);
207 if (!context->http_transaction_factory())
208 return nullptr;
209
210 return context->http_transaction_factory()->GetSession();
211 }
212
213 void CronetEnvironment::AddQuicHint(const std::string& host,
214 int port,
215 int alternate_port) {
216 DCHECK(port == alternate_port);
217 quic_hints_.push_back(net::HostPortPair(host, port));
218 }
219
220 CronetEnvironment::CronetEnvironment(const std::string& user_agent,
221 bool user_agent_partial)
222 : http2_enabled_(false),
223 quic_enabled_(false),
224 user_agent_(user_agent),
225 user_agent_partial_(user_agent_partial),
226 net_log_(new net::NetLog) {}
227
228 void CronetEnvironment::Start() {
229 // Threads setup.
230 network_cache_thread_.reset(new base::Thread("Chrome Network Cache Thread"));
231 network_cache_thread_->StartWithOptions(
232 base::Thread::Options(base::MessageLoop::TYPE_IO, 0));
233 network_io_thread_.reset(new base::Thread("Chrome Network IO Thread"));
234 network_io_thread_->StartWithOptions(
235 base::Thread::Options(base::MessageLoop::TYPE_IO, 0));
236 file_thread_.reset(new base::Thread("Chrome File Thread"));
237 file_thread_->StartWithOptions(
238 base::Thread::Options(base::MessageLoop::TYPE_IO, 0));
239 file_user_blocking_thread_.reset(
240 new base::Thread("Chrome File User Blocking Thread"));
241 file_user_blocking_thread_->StartWithOptions(
242 base::Thread::Options(base::MessageLoop::TYPE_IO, 0));
243
244 static bool ssl_key_log_file_set = false;
245 if (!ssl_key_log_file_set && !ssl_key_log_file_name_.empty()) {
246 ssl_key_log_file_set = true;
247 base::FilePath ssl_key_log_file;
248 if (!PathService::Get(base::DIR_HOME, &ssl_key_log_file))
249 return;
250 net::SSLClientSocket::SetSSLKeyLogFile(
251 ssl_key_log_file.Append(ssl_key_log_file_name_),
252 file_thread_->task_runner());
253 }
254
255 proxy_config_service_ = net::ProxyService::CreateSystemProxyConfigService(
256 network_io_thread_->task_runner(), nullptr);
257 main_context_getter_ = new CronetURLRequestContextGetter(
258 this, network_io_thread_->task_runner());
259 base::subtle::MemoryBarrier();
260 PostToNetworkThread(FROM_HERE,
261 base::Bind(&CronetEnvironment::InitializeOnNetworkThread,
262 base::Unretained(this)));
263 }
264
265 CronetEnvironment::~CronetEnvironment() {
266 // net::HTTPProtocolHandlerDelegate::SetInstance(nullptr);
267 }
268
269 void CronetEnvironment::InitializeOnNetworkThread() {
270 DCHECK(network_io_thread_->task_runner()->BelongsToCurrentThread());
271 base::FeatureList::InitializeInstance(std::string(), std::string());
272 // TODO(mef): Use net:UrlRequestContextBuilder instead of manual build.
273 main_context_.reset(new net::URLRequestContext);
274 main_context_->set_net_log(net_log_.get());
275
276 if (user_agent_partial_)
277 user_agent_ = web::BuildUserAgentFromProduct(user_agent_);
278
279 main_context_->set_http_user_agent_settings(
280 new net::StaticHttpUserAgentSettings(accept_language_, user_agent_));
281
282 main_context_->set_ssl_config_service(new net::SSLConfigServiceDefaults);
283 main_context_->set_transport_security_state(
284 new net::TransportSecurityState());
285 http_server_properties_.reset(new net::HttpServerPropertiesImpl());
286 main_context_->set_http_server_properties(http_server_properties_.get());
287
288 // TODO(rdsmith): Note that the ".release()" calls below are leaking
289 // the objects in question; this should be fixed by having an object
290 // corresponding to URLRequestContextStorage that actually owns those
291 // objects. See http://crbug.com/523858.
292 std::unique_ptr<net::MappedHostResolver> mapped_host_resolver(
293 new net::MappedHostResolver(
294 net::HostResolver::CreateDefaultResolver(nullptr)));
295
296 main_context_->set_host_resolver(mapped_host_resolver.release());
297
298 if (!cert_verifier_)
299 cert_verifier_ = net::CertVerifier::CreateDefault();
300 main_context_->set_cert_verifier(cert_verifier_.get());
301
302 std::unique_ptr<net::MultiLogCTVerifier> ct_verifier =
303 base::MakeUnique<net::MultiLogCTVerifier>();
304 ct_verifier->AddLogs(net::ct::CreateLogVerifiersForKnownLogs());
305 main_context_->set_cert_transparency_verifier(ct_verifier.release());
306 main_context_->set_ct_policy_enforcer(new net::CTPolicyEnforcer());
307
308 main_context_->set_http_auth_handler_factory(
309 net::HttpAuthHandlerRegistryFactory::CreateDefault(
310 main_context_->host_resolver())
311 .release());
312 main_context_->set_proxy_service(
313 net::ProxyService::CreateUsingSystemProxyResolver(
314 std::move(proxy_config_service_), 0, nullptr)
315 .release());
316
317 // Cache
318 base::FilePath cache_path;
319 if (!PathService::Get(base::DIR_CACHE, &cache_path))
320 return;
321 cache_path = cache_path.Append(FILE_PATH_LITERAL("cronet"));
322 std::unique_ptr<net::HttpCache::DefaultBackend> main_backend(
323 new net::HttpCache::DefaultBackend(net::DISK_CACHE,
324 net::CACHE_BACKEND_SIMPLE, cache_path,
325 0, // Default cache size.
326 network_cache_thread_->task_runner()));
327
328 net::HttpNetworkSession::Params params;
329
330 params.host_resolver = main_context_->host_resolver();
331 params.cert_verifier = main_context_->cert_verifier();
332 params.cert_transparency_verifier =
333 main_context_->cert_transparency_verifier();
334 params.ct_policy_enforcer = main_context_->ct_policy_enforcer();
335 params.channel_id_service = main_context_->channel_id_service();
336 params.transport_security_state = main_context_->transport_security_state();
337 params.proxy_service = main_context_->proxy_service();
338 params.ssl_config_service = main_context_->ssl_config_service();
339 params.http_auth_handler_factory = main_context_->http_auth_handler_factory();
340 params.http_server_properties = main_context_->http_server_properties();
341 params.net_log = main_context_->net_log();
342 params.enable_http2 = http2_enabled();
343 params.enable_quic = quic_enabled();
344
345 for (const auto& quic_hint : quic_hints_) {
346 net::AlternativeService alternative_service(net::kProtoQUIC, "",
347 quic_hint.port());
348 url::SchemeHostPort quic_hint_server("https", quic_hint.host(),
349 quic_hint.port());
350 main_context_->http_server_properties()->SetAlternativeService(
351 quic_hint_server, alternative_service, base::Time::Max());
352 params.quic_host_whitelist.insert(quic_hint.host());
353 }
354
355 if (!params.channel_id_service) {
356 // The main context may not have a ChannelIDService, since it is lazily
357 // constructed. If not, build an ephemeral ChannelIDService with no backing
358 // disk store.
359 // TODO(ellyjones): support persisting ChannelID.
360 params.channel_id_service =
361 new net::ChannelIDService(new net::DefaultChannelIDStore(NULL),
362 base::WorkerPool::GetTaskRunner(true));
363 }
364
365 // TODO(mmenke): These really shouldn't be leaked.
366 // See https://crbug.com/523858.
367 net::HttpNetworkSession* http_network_session =
368 new net::HttpNetworkSession(params);
369 net::HttpCache* main_cache =
370 new net::HttpCache(http_network_session, std::move(main_backend),
371 true /* set_up_quic_server_info */);
372 main_context_->set_http_transaction_factory(main_cache);
373
374 net::URLRequestJobFactoryImpl* job_factory =
375 new net::URLRequestJobFactoryImpl;
376 main_context_->set_job_factory(job_factory);
377 main_context_->set_net_log(net_log_.get());
378 }
379
380 std::string CronetEnvironment::user_agent() {
381 const net::HttpUserAgentSettings* user_agent_settings =
382 main_context_->http_user_agent_settings();
383 if (!user_agent_settings) {
384 return nullptr;
385 }
386
387 return user_agent_settings->GetUserAgent();
388 }
389
390 std::vector<uint8_t> CronetEnvironment::GetHistogramDeltas() {
391 base::StatisticsRecorder::Initialize();
392 std::vector<uint8_t> data;
393 if (!HistogramManager::GetInstance()->GetDeltas(&data))
394 return std::vector<uint8_t>();
395 return data;
396 }
397
398 void CronetEnvironment::SetHostResolverRules(const std::string& rules) {
399 base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC,
400 base::WaitableEvent::InitialState::NOT_SIGNALED);
401 PostToNetworkThread(
402 FROM_HERE,
403 base::Bind(&CronetEnvironment::SetHostResolverRulesOnNetworkThread,
404 base::Unretained(this), rules, &event));
405 event.Wait();
406 }
407
408 void CronetEnvironment::SetHostResolverRulesOnNetworkThread(
409 const std::string& rules,
410 base::WaitableEvent* event) {
411 static_cast<net::MappedHostResolver*>(main_context_->host_resolver())
412 ->SetRulesFromString(rules);
413 event->Signal();
414 }
415
416 } // namespace cronet
OLDNEW
« no previous file with comments | « components/cronet/ios/cronet_environment.h ('k') | components/cronet/ios/cronet_environment.mm » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698