[go: nahoru, domu]

blob: d3a97e40f7ee637e8bfa2a54f16836c03c92a292 [file] [log] [blame]
mef06eab3e82016-04-14 22:45:491// 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
mef06eab3e82016-04-14 22:45:499#include "base/atomicops.h"
Misha Efimova33615a2017-07-12 19:47:1510#include "base/bind.h"
mef06eab3e82016-04-14 22:45:4911#include "base/command_line.h"
kapishnikovf7b513092016-07-08 23:42:5512#include "base/feature_list.h"
mef06eab3e82016-04-14 22:45:4913#include "base/files/file_path.h"
14#include "base/files/file_util.h"
Eric Roman84702922017-07-11 19:07:3715#include "base/files/scoped_file.h"
mef06eab3e82016-04-14 22:45:4916#include "base/mac/foundation_util.h"
17#include "base/macros.h"
Alexander Timin4f9c35c2018-11-01 20:15:2018#include "base/message_loop/message_loop.h"
mef06eab3e82016-04-14 22:45:4919#include "base/path_service.h"
fdoray6ef45cf2016-08-25 15:36:3720#include "base/single_thread_task_runner.h"
mef06eab3e82016-04-14 22:45:4921#include "base/synchronization/waitable_event.h"
kapishnikov46532f32017-10-23 08:54:4622#include "base/threading/thread_restrictions.h"
Misha Efimova0b0fe612018-10-02 14:23:4423#include "components/cronet/cronet_buildflags.h"
Paul Jensen6a1ea3a2018-08-24 14:46:4124#include "components/cronet/cronet_global_state.h"
kapishnikov8de94362017-08-30 14:40:5925#include "components/cronet/cronet_prefs_manager.h"
mef254963db2016-10-20 21:48:0726#include "components/cronet/histogram_manager.h"
mef06eab3e82016-04-14 22:45:4927#include "components/prefs/pref_filter.h"
mef3c84be92016-11-19 00:06:5628#include "ios/net/cookies/cookie_store_ios.h"
Mohammad Refaat41032802017-10-06 04:15:5729#include "ios/net/cookies/cookie_store_ios_client.h"
Mike Doughertye107171852017-07-12 17:56:2530#include "ios/web/public/global_state/ios_global_state.h"
Mike Doughertyfc4bf312017-08-18 17:06:5931#include "ios/web/public/global_state/ios_global_state_configuration.h"
mef254963db2016-10-20 21:48:0732#include "ios/web/public/user_agent.h"
Matt Menked732ea42019-03-08 12:05:0033#include "net/base/http_user_agent_settings.h"
mef06eab3e82016-04-14 22:45:4934#include "net/base/network_change_notifier.h"
Lily Houghton5a1a9112017-08-10 17:21:5535#include "net/base/url_util.h"
mef4c515e142016-09-06 18:16:3036#include "net/cert/cert_verifier.h"
mef06eab3e82016-04-14 22:45:4937#include "net/dns/host_resolver.h"
38#include "net/dns/mapped_host_resolver.h"
mef06eab3e82016-04-14 22:45:4939#include "net/http/http_server_properties_impl.h"
40#include "net/http/http_stream_factory.h"
lilyhoughton4e23c362016-12-09 19:04:3441#include "net/http/http_transaction_factory.h"
mef06eab3e82016-04-14 22:45:4942#include "net/http/http_util.h"
Misha Efimova33615a2017-07-12 19:47:1543#include "net/log/file_net_log_observer.h"
mef06eab3e82016-04-14 22:45:4944#include "net/log/net_log.h"
mikecironef22f9812016-10-04 03:40:1945#include "net/log/net_log_capture_mode.h"
kapishnikovd0c68602017-08-31 02:50:5046#include "net/log/net_log_util.h"
Lily Houghtonffe89daa02018-03-09 18:30:0347#include "net/proxy_resolution/proxy_resolution_service.h"
mef06eab3e82016-04-14 22:45:4948#include "net/socket/ssl_client_socket.h"
mef2989c372017-01-06 18:35:5949#include "net/ssl/channel_id_service.h"
David Benjaminbd37c172018-07-11 17:24:5750#include "net/ssl/ssl_key_logger_impl.h"
Victor Vasiliev6bb59d22019-03-08 21:34:5151#include "net/third_party/quiche/src/quic/core/quic_versions.h"
lilyhoughton4e23c362016-12-09 19:04:3452#include "net/url_request/url_request_context.h"
53#include "net/url_request/url_request_context_builder.h"
mef06eab3e82016-04-14 22:45:4954#include "net/url_request/url_request_context_storage.h"
55#include "net/url_request/url_request_job_factory_impl.h"
zhongyi3d4a55e72016-04-22 20:36:4656#include "url/scheme_host_port.h"
mef06eab3e82016-04-14 22:45:4957#include "url/url_util.h"
58
kapishnikovbd670932017-10-13 16:57:3859#if !defined(__has_feature) || !__has_feature(objc_arc)
60#error "This file requires ARC support."
61#endif
62
mef06eab3e82016-04-14 22:45:4963namespace {
64
mef254963db2016-10-20 21:48:0765// Request context getter for Cronet.
66class CronetURLRequestContextGetter : public net::URLRequestContextGetter {
67 public:
68 CronetURLRequestContextGetter(
69 cronet::CronetEnvironment* environment,
70 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner)
71 : environment_(environment), task_runner_(task_runner) {}
72
73 net::URLRequestContext* GetURLRequestContext() override {
74 DCHECK(environment_);
75 return environment_->GetURLRequestContext();
76 }
77
78 scoped_refptr<base::SingleThreadTaskRunner> GetNetworkTaskRunner()
79 const override {
80 return task_runner_;
81 }
82
83 private:
84 // Must be called on the IO thread.
85 ~CronetURLRequestContextGetter() override {}
86
87 cronet::CronetEnvironment* environment_;
88 scoped_refptr<base::SingleThreadTaskRunner> task_runner_;
89 DISALLOW_COPY_AND_ASSIGN(CronetURLRequestContextGetter);
90};
91
Mohammad Refaat41032802017-10-06 04:15:5792// Cronet implementation of net::CookieStoreIOSClient.
93// Used to provide Cronet Network IO TaskRunner.
94class CronetCookieStoreIOSClient : public net::CookieStoreIOSClient {
95 public:
96 CronetCookieStoreIOSClient(
97 const scoped_refptr<base::SequencedTaskRunner>& task_runner)
98 : task_runner_(task_runner) {}
99
100 scoped_refptr<base::SequencedTaskRunner> GetTaskRunner() const override {
101 return task_runner_;
102 }
103
104 private:
105 ~CronetCookieStoreIOSClient() override {}
106
107 scoped_refptr<base::SequencedTaskRunner> task_runner_;
108 DISALLOW_COPY_AND_ASSIGN(CronetCookieStoreIOSClient);
109};
110
Misha Efimova33615a2017-07-12 19:47:15111void SignalEvent(base::WaitableEvent* event) {
112 event->Signal();
113}
114
115// TODO(eroman): Creating the file(s) for a netlog is an internal detail for
116// FileNetLogObsever. This code assumes that the unbounded format is being used,
117// which writes a single file at |path| (creating or overwriting it).
118bool IsNetLogPathValid(const base::FilePath& path) {
119 base::ScopedFILE file(base::OpenFile(path, "w"));
120 return !!file;
121}
122
mef06eab3e82016-04-14 22:45:49123} // namespace
124
125namespace cronet {
126
kapishnikov9f98c432018-01-12 23:24:08127const double CronetEnvironment::kKeepDefaultThreadPriority = -1;
128
129base::SingleThreadTaskRunner* CronetEnvironment::GetNetworkThreadTaskRunner()
130 const {
Mike Doughertyfc4bf312017-08-18 17:06:59131 if (network_io_thread_) {
132 return network_io_thread_->task_runner().get();
133 }
134 return ios_global_state::GetSharedNetworkIOThreadTaskRunner().get();
135}
136
Brett Wilson190fd2ac2017-09-12 05:04:30137void CronetEnvironment::PostToNetworkThread(const base::Location& from_here,
138 const base::Closure& task) {
Mike Doughertyfc4bf312017-08-18 17:06:59139 GetNetworkThreadTaskRunner()->PostTask(from_here, task);
mef06eab3e82016-04-14 22:45:49140}
141
mef06eab3e82016-04-14 22:45:49142net::URLRequestContext* CronetEnvironment::GetURLRequestContext() const {
143 return main_context_.get();
144}
145
mef254963db2016-10-20 21:48:07146net::URLRequestContextGetter* CronetEnvironment::GetURLRequestContextGetter()
147 const {
148 return main_context_getter_.get();
149}
150
lilyhoughton214b3a22017-01-09 19:42:02151bool CronetEnvironment::StartNetLog(base::FilePath::StringType file_name,
mef06eab3e82016-04-14 22:45:49152 bool log_bytes) {
Misha Efimova33615a2017-07-12 19:47:15153 if (file_name.empty())
lilyhoughton214b3a22017-01-09 19:42:02154 return false;
155
156 base::FilePath path(file_name);
Misha Efimova33615a2017-07-12 19:47:15157 if (!IsNetLogPathValid(path)) {
Eric Roman84702922017-07-11 19:07:37158 LOG(ERROR) << "Can not start NetLog to " << path.value() << ": "
159 << strerror(errno);
160 return false;
161 }
162
lilyhoughton214b3a22017-01-09 19:42:02163 LOG(WARNING) << "Starting NetLog to " << path.value();
Misha Efimova33615a2017-07-12 19:47:15164 PostToNetworkThread(FROM_HERE,
165 base::Bind(&CronetEnvironment::StartNetLogOnNetworkThread,
166 base::Unretained(this), path, log_bytes));
lilyhoughton214b3a22017-01-09 19:42:02167
168 return true;
mef06eab3e82016-04-14 22:45:49169}
170
Misha Efimova33615a2017-07-12 19:47:15171void CronetEnvironment::StartNetLogOnNetworkThread(const base::FilePath& path,
lilyhoughton214b3a22017-01-09 19:42:02172 bool log_bytes) {
mef06eab3e82016-04-14 22:45:49173 DCHECK(net_log_);
174
Misha Efimova33615a2017-07-12 19:47:15175 if (file_net_log_observer_)
mef06eab3e82016-04-14 22:45:49176 return;
177
mef06eab3e82016-04-14 22:45:49178 net::NetLogCaptureMode capture_mode =
179 log_bytes ? net::NetLogCaptureMode::IncludeSocketBytes()
180 : net::NetLogCaptureMode::Default();
181
Misha Efimova33615a2017-07-12 19:47:15182 file_net_log_observer_ =
183 net::FileNetLogObserver::CreateUnbounded(path, nullptr);
184 file_net_log_observer_->StartObserving(main_context_->net_log(),
185 capture_mode);
lilyhoughton214b3a22017-01-09 19:42:02186 LOG(WARNING) << "Started NetLog";
mef06eab3e82016-04-14 22:45:49187}
188
189void CronetEnvironment::StopNetLog() {
gab5600d5b2016-06-08 21:44:41190 base::WaitableEvent log_stopped_event(
191 base::WaitableEvent::ResetPolicy::MANUAL,
192 base::WaitableEvent::InitialState::NOT_SIGNALED);
mef06eab3e82016-04-14 22:45:49193 PostToNetworkThread(FROM_HERE,
194 base::Bind(&CronetEnvironment::StopNetLogOnNetworkThread,
195 base::Unretained(this), &log_stopped_event));
196 log_stopped_event.Wait();
197}
198
199void CronetEnvironment::StopNetLogOnNetworkThread(
200 base::WaitableEvent* log_stopped_event) {
Misha Efimova33615a2017-07-12 19:47:15201 if (file_net_log_observer_) {
mef06eab3e82016-04-14 22:45:49202 DLOG(WARNING) << "Stopped NetLog.";
Misha Efimova33615a2017-07-12 19:47:15203 file_net_log_observer_->StopObserving(
kapishnikovd0c68602017-08-31 02:50:50204 GetNetLogInfo(), base::BindOnce(&SignalEvent, log_stopped_event));
Misha Efimova33615a2017-07-12 19:47:15205 file_net_log_observer_.reset();
206 } else {
207 log_stopped_event->Signal();
mef06eab3e82016-04-14 22:45:49208 }
mef06eab3e82016-04-14 22:45:49209}
210
kapishnikovd0c68602017-08-31 02:50:50211std::unique_ptr<base::DictionaryValue> CronetEnvironment::GetNetLogInfo()
212 const {
213 std::unique_ptr<base::DictionaryValue> net_info =
214 net::GetNetInfo(main_context_.get(), net::NET_INFO_ALL_SOURCES);
215 if (effective_experimental_options_) {
216 net_info->Set("cronetExperimentalParams",
217 effective_experimental_options_->CreateDeepCopy());
218 }
219 return net_info;
220}
221
mef06eab3e82016-04-14 22:45:49222net::HttpNetworkSession* CronetEnvironment::GetHttpNetworkSession(
223 net::URLRequestContext* context) {
224 DCHECK(context);
225 if (!context->http_transaction_factory())
226 return nullptr;
227
228 return context->http_transaction_factory()->GetSession();
229}
230
231void CronetEnvironment::AddQuicHint(const std::string& host,
232 int port,
233 int alternate_port) {
234 DCHECK(port == alternate_port);
235 quic_hints_.push_back(net::HostPortPair(host, port));
236}
237
mef254963db2016-10-20 21:48:07238CronetEnvironment::CronetEnvironment(const std::string& user_agent,
239 bool user_agent_partial)
mef06eab3e82016-04-14 22:45:49240 : http2_enabled_(false),
241 quic_enabled_(false),
Brad Lassey250b6242017-07-10 14:19:57242 brotli_enabled_(false),
lilyhoughton5ed6b50f2017-01-19 22:04:04243 http_cache_(URLRequestContextConfig::HttpCacheType::DISK),
mef254963db2016-10-20 21:48:07244 user_agent_(user_agent),
245 user_agent_partial_(user_agent_partial),
lilyhoughton41c31a682017-06-28 16:54:09246 net_log_(new net::NetLog),
kapishnikov9f98c432018-01-12 23:24:08247 enable_pkp_bypass_for_local_trust_anchors_(true),
248 network_thread_priority_(kKeepDefaultThreadPriority) {}
mef06eab3e82016-04-14 22:45:49249
250void CronetEnvironment::Start() {
mef06eab3e82016-04-14 22:45:49251 // Threads setup.
kapishnikov8de94362017-08-30 14:40:59252 file_thread_.reset(new base::Thread("Chrome File Thread"));
253 file_thread_->StartWithOptions(
mef06eab3e82016-04-14 22:45:49254 base::Thread::Options(base::MessageLoop::TYPE_IO, 0));
Mike Doughertyfc4bf312017-08-18 17:06:59255 // Fetching the task_runner will create the shared thread if necessary.
256 scoped_refptr<base::SingleThreadTaskRunner> task_runner =
257 ios_global_state::GetSharedNetworkIOThreadTaskRunner();
258 if (!task_runner) {
kapishnikov26333882017-09-08 14:25:56259 network_io_thread_.reset(
260 new CronetNetworkThread("Chrome Network IO Thread", this));
Mike Doughertyfc4bf312017-08-18 17:06:59261 network_io_thread_->StartWithOptions(
262 base::Thread::Options(base::MessageLoop::TYPE_IO, 0));
263 }
mef06eab3e82016-04-14 22:45:49264
Mohammad Refaat41032802017-10-06 04:15:57265 net::SetCookieStoreIOSClient(new CronetCookieStoreIOSClient(
266 CronetEnvironment::GetNetworkThreadTaskRunner()));
267
mef254963db2016-10-20 21:48:07268 main_context_getter_ = new CronetURLRequestContextGetter(
Mike Doughertyfc4bf312017-08-18 17:06:59269 this, CronetEnvironment::GetNetworkThreadTaskRunner());
mef06eab3e82016-04-14 22:45:49270 base::subtle::MemoryBarrier();
271 PostToNetworkThread(FROM_HERE,
272 base::Bind(&CronetEnvironment::InitializeOnNetworkThread,
273 base::Unretained(this)));
274}
275
kapishnikov26333882017-09-08 14:25:56276void CronetEnvironment::CleanUpOnNetworkThread() {
lilyhoughton94bde172017-05-08 17:25:16277 // TODO(lilyhoughton) make unregistering of this work.
mef3c84be92016-11-19 00:06:56278 // net::HTTPProtocolHandlerDelegate::SetInstance(nullptr);
lilyhoughton8c4ab792017-01-18 15:34:15279
lilyhoughton94bde172017-05-08 17:25:16280 // TODO(lilyhoughton) this can only be run once, so right now leaking it.
281 // Should be be called when the _last_ CronetEnvironment is destroyed.
282 // base::TaskScheduler* ts = base::TaskScheduler::GetInstance();
283 // if (ts)
284 // ts->Shutdown();
285
kapishnikov8de94362017-08-30 14:40:59286 if (cronet_prefs_manager_) {
287 cronet_prefs_manager_->PrepareForShutdown();
288 }
289
Matt Menke258cfcb2017-10-05 22:54:32290 // TODO(lilyhoughton) this should be smarter about making sure there are no
291 // pending requests, etc.
292 main_context_.reset();
293
kapishnikov8de94362017-08-30 14:40:59294 // cronet_prefs_manager_ should be deleted on the network thread.
kapishnikov26333882017-09-08 14:25:56295 cronet_prefs_manager_.reset();
kapishnikov8de94362017-08-30 14:40:59296}
lilyhoughton94bde172017-05-08 17:25:16297
kapishnikov8de94362017-08-30 14:40:59298CronetEnvironment::~CronetEnvironment() {
kapishnikov26333882017-09-08 14:25:56299 // Deleting a thread blocks the current thread and waits until all pending
300 // tasks are completed.
301 network_io_thread_.reset();
kapishnikov46532f32017-10-23 08:54:46302 file_thread_.reset();
mef06eab3e82016-04-14 22:45:49303}
304
305void CronetEnvironment::InitializeOnNetworkThread() {
Mike Doughertyfc4bf312017-08-18 17:06:59306 DCHECK(GetNetworkThreadTaskRunner()->BelongsToCurrentThread());
kapishnikov46532f32017-10-23 08:54:46307 base::DisallowBlocking();
mef254963db2016-10-20 21:48:07308
lilyhoughton214b3a22017-01-09 19:42:02309 static bool ssl_key_log_file_set = false;
310 if (!ssl_key_log_file_set && !ssl_key_log_file_name_.empty()) {
311 ssl_key_log_file_set = true;
lilyhoughton3c82bec2017-04-26 18:53:15312 base::FilePath ssl_key_log_file(ssl_key_log_file_name_);
David Benjaminbd37c172018-07-11 17:24:57313 net::SSLClientSocket::SetSSLKeyLogger(
314 std::make_unique<net::SSLKeyLoggerImpl>(ssl_key_log_file));
lilyhoughton214b3a22017-01-09 19:42:02315 }
316
mef254963db2016-10-20 21:48:07317 if (user_agent_partial_)
318 user_agent_ = web::BuildUserAgentFromProduct(user_agent_);
319
mef06eab3e82016-04-14 22:45:49320 // Cache
kapishnikov8de94362017-08-30 14:40:59321 base::FilePath storage_path;
Avi Drissmanf617d012018-05-02 18:48:53322 if (!base::PathService::Get(base::DIR_CACHE, &storage_path))
mef06eab3e82016-04-14 22:45:49323 return;
kapishnikov8de94362017-08-30 14:40:59324 storage_path = storage_path.Append(FILE_PATH_LITERAL("cronet"));
mef06eab3e82016-04-14 22:45:49325
lilyhoughton14e2a1f12017-01-11 14:50:27326 URLRequestContextConfigBuilder context_config_builder;
327 context_config_builder.enable_quic = quic_enabled_; // Enable QUIC.
Lily Houghton2d8a8ff2017-12-20 16:00:26328 context_config_builder.quic_user_agent_id =
329 getDefaultQuicUserAgentId(); // QUIC User Agent ID.
lilyhoughton14e2a1f12017-01-11 14:50:27330 context_config_builder.enable_spdy = http2_enabled_; // Enable HTTP/2.
Lily Houghton2d8a8ff2017-12-20 16:00:26331 context_config_builder.http_cache = http_cache_; // Set HTTP cache.
lilyhoughton14e2a1f12017-01-11 14:50:27332 context_config_builder.storage_path =
kapishnikov8de94362017-08-30 14:40:59333 storage_path.value(); // Storage path for http cache and prefs storage.
Misha Efimovd4ab38302018-01-30 23:56:42334 context_config_builder.accept_language =
335 accept_language_; // Accept-Language request header field.
lilyhoughton14e2a1f12017-01-11 14:50:27336 context_config_builder.user_agent =
337 user_agent_; // User-Agent request header field.
lilyhoughton3c82bec2017-04-26 18:53:15338 context_config_builder.experimental_options =
339 experimental_options_; // Set experimental Cronet options.
lilyhoughton14e2a1f12017-01-11 14:50:27340 context_config_builder.mock_cert_verifier = std::move(
341 mock_cert_verifier_); // MockCertVerifier to use for testing purposes.
Paul Jensen6a1ea3a2018-08-24 14:46:41342 if (network_thread_priority_ != kKeepDefaultThreadPriority)
343 context_config_builder.network_thread_priority = network_thread_priority_;
lilyhoughton14e2a1f12017-01-11 14:50:27344 std::unique_ptr<URLRequestContextConfig> config =
345 context_config_builder.Build();
mef06eab3e82016-04-14 22:45:49346
kapishnikoveac2ab02017-06-19 22:20:29347 config->pkp_list = std::move(pkp_list_);
348
lilyhoughton4e23c362016-12-09 19:04:34349 net::URLRequestContextBuilder context_builder;
mef06eab3e82016-04-14 22:45:49350
kapishnikoveac2ab02017-06-19 22:20:29351 // Explicitly disable the persister for Cronet to avoid persistence of dynamic
352 // HPKP. This is a safety measure ensuring that nobody enables the
353 // persistence of HPKP by specifying transport_security_persister_path in the
354 // future.
355 context_builder.set_transport_security_persister_path(base::FilePath());
356
David Benjamindc2f4b02017-07-27 23:59:02357 config->ConfigureURLRequestContextBuilder(&context_builder, net_log_.get());
lilyhoughton4e23c362016-12-09 19:04:34358
kapishnikovd0c68602017-08-31 02:50:50359 effective_experimental_options_ =
360 std::move(config->effective_experimental_options);
361
Eric Orth9ded7fe2019-03-22 16:32:38362 // TODO(crbug.com/934402): Use a shared HostResolverManager instead of a
363 // global HostResolver.
lilyhoughton4e23c362016-12-09 19:04:34364 std::unique_ptr<net::MappedHostResolver> mapped_host_resolver(
365 new net::MappedHostResolver(
Eric Orth9ded7fe2019-03-22 16:32:38366 net::HostResolver::CreateStandaloneResolver(nullptr)));
lilyhoughton4e23c362016-12-09 19:04:34367
kapishnikov8de94362017-08-30 14:40:59368 if (!config->storage_path.empty()) {
369 cronet_prefs_manager_ = std::make_unique<CronetPrefsManager>(
370 config->storage_path, GetNetworkThreadTaskRunner(),
371 file_thread_->task_runner(), false /* nqe */, false /* host_cache */,
372 net_log_.get(), &context_builder);
373 }
374
lilyhoughton4e23c362016-12-09 19:04:34375 context_builder.set_host_resolver(std::move(mapped_host_resolver));
376
mef674565162017-02-10 18:44:24377 // TODO(690969): This behavior matches previous behavior of CookieStoreIOS in
378 // CrNet, but should change to adhere to App's Cookie Accept Policy instead
379 // of changing it.
380 [[NSHTTPCookieStorage sharedHTTPCookieStorage]
381 setCookieAcceptPolicy:NSHTTPCookieAcceptPolicyAlways];
Helen Li8c7c8be2018-08-24 13:59:40382 auto cookie_store = std::make_unique<net::CookieStoreIOS>(
383 [NSHTTPCookieStorage sharedHTTPCookieStorage], nullptr /* net_log */);
Nick Harperb7f127d2018-12-04 19:54:05384 context_builder.SetCookieStore(std::move(cookie_store));
mef2989c372017-01-06 18:35:59385
kapishnikov8de94362017-08-30 14:40:59386 context_builder.set_enable_brotli(brotli_enabled_);
387 main_context_ = context_builder.Build();
zhongyie537a002017-06-27 16:48:21388
mef06eab3e82016-04-14 22:45:49389 for (const auto& quic_hint : quic_hints_) {
Lily Houghton5a1a9112017-08-10 17:21:55390 url::CanonHostInfo host_info;
391 std::string canon_host(net::CanonicalizeHost(quic_hint.host(), &host_info));
392 if (!host_info.IsIPAddress() &&
393 !net::IsCanonicalizedHostCompliant(canon_host)) {
394 LOG(ERROR) << "Invalid QUIC hint host: " << quic_hint.host();
395 continue;
396 }
397
gcasto899886f2016-11-18 13:54:03398 net::AlternativeService alternative_service(net::kProtoQUIC, "",
399 quic_hint.port());
Lily Houghton5a1a9112017-08-10 17:21:55400
zhongyi3d4a55e72016-04-22 20:36:46401 url::SchemeHostPort quic_hint_server("https", quic_hint.host(),
402 quic_hint.port());
kapishnikov8de94362017-08-30 14:40:59403 main_context_->http_server_properties()->SetQuicAlternativeService(
zhongyie537a002017-06-27 16:48:21404 quic_hint_server, alternative_service, base::Time::Max(),
Ryan Hamilton8d9ee76e2018-05-29 23:52:52405 quic::QuicTransportVersionVector());
mef06eab3e82016-04-14 22:45:49406 }
407
lilyhoughton41c31a682017-06-28 16:54:09408 main_context_->transport_security_state()
409 ->SetEnablePublicKeyPinningBypassForLocalTrustAnchors(
410 enable_pkp_bypass_for_local_trust_anchors_);
411
412 // Iterate trhough PKP configuration for every host.
Donna Wu7ea51c22017-06-20 08:34:52413 for (const auto& pkp : config->pkp_list) {
kapishnikoveac2ab02017-06-19 22:20:29414 // Add the host pinning.
415 main_context_->transport_security_state()->AddHPKP(
416 pkp->host, pkp->expiration_date, pkp->include_subdomains,
417 pkp->pin_hashes, GURL::EmptyGURL());
418 }
mef06eab3e82016-04-14 22:45:49419}
420
kapishnikov9f98c432018-01-12 23:24:08421void CronetEnvironment::SetNetworkThreadPriority(double priority) {
422 DCHECK_LE(priority, 1.0);
423 DCHECK_GE(priority, 0.0);
424 network_thread_priority_ = priority;
425 if (network_io_thread_) {
426 PostToNetworkThread(
427 FROM_HERE,
428 base::BindRepeating(
429 &CronetEnvironment::SetNetworkThreadPriorityOnNetworkThread,
430 base::Unretained(this), priority));
431 }
432}
433
mef06eab3e82016-04-14 22:45:49434std::string CronetEnvironment::user_agent() {
435 const net::HttpUserAgentSettings* user_agent_settings =
436 main_context_->http_user_agent_settings();
437 if (!user_agent_settings) {
438 return nullptr;
439 }
440
441 return user_agent_settings->GetUserAgent();
442}
443
mef254963db2016-10-20 21:48:07444std::vector<uint8_t> CronetEnvironment::GetHistogramDeltas() {
mef254963db2016-10-20 21:48:07445 std::vector<uint8_t> data;
Misha Efimova0b0fe612018-10-02 14:23:44446#if BUILDFLAG(DISABLE_HISTOGRAM_SUPPORT)
447 NOTREACHED() << "Histogram support is disabled";
448#else // BUILDFLAG(DISABLE_HISTOGRAM_SUPPORT)
mef254963db2016-10-20 21:48:07449 if (!HistogramManager::GetInstance()->GetDeltas(&data))
450 return std::vector<uint8_t>();
Misha Efimova0b0fe612018-10-02 14:23:44451#endif // BUILDFLAG(DISABLE_HISTOGRAM_SUPPORT)
mef254963db2016-10-20 21:48:07452 return data;
453}
454
gcasto67ace932016-11-10 21:44:49455void CronetEnvironment::SetHostResolverRules(const std::string& rules) {
456 base::WaitableEvent event(base::WaitableEvent::ResetPolicy::AUTOMATIC,
457 base::WaitableEvent::InitialState::NOT_SIGNALED);
458 PostToNetworkThread(
459 FROM_HERE,
460 base::Bind(&CronetEnvironment::SetHostResolverRulesOnNetworkThread,
461 base::Unretained(this), rules, &event));
462 event.Wait();
463}
464
465void CronetEnvironment::SetHostResolverRulesOnNetworkThread(
466 const std::string& rules,
467 base::WaitableEvent* event) {
468 static_cast<net::MappedHostResolver*>(main_context_->host_resolver())
469 ->SetRulesFromString(rules);
470 event->Signal();
471}
472
kapishnikov9f98c432018-01-12 23:24:08473void CronetEnvironment::SetNetworkThreadPriorityOnNetworkThread(
474 double priority) {
475 DCHECK(GetNetworkThreadTaskRunner()->BelongsToCurrentThread());
Paul Jensen6a1ea3a2018-08-24 14:46:41476 cronet::SetNetworkThreadPriorityOnNetworkThread(priority);
kapishnikov9f98c432018-01-12 23:24:08477}
478
lilyhoughton52f8be32016-12-15 20:33:48479std::string CronetEnvironment::getDefaultQuicUserAgentId() const {
480 return base::SysNSStringToUTF8([[NSBundle mainBundle]
481 objectForInfoDictionaryKey:@"CFBundleDisplayName"]) +
482 " Cronet/" + CRONET_VERSION;
483}
484
kapishnikov8de94362017-08-30 14:40:59485base::SingleThreadTaskRunner* CronetEnvironment::GetFileThreadRunnerForTesting()
486 const {
487 return file_thread_->task_runner().get();
488}
489
kapishnikov9f98c432018-01-12 23:24:08490base::SingleThreadTaskRunner*
491CronetEnvironment::GetNetworkThreadRunnerForTesting() const {
492 return GetNetworkThreadTaskRunner();
493}
494
kapishnikov26333882017-09-08 14:25:56495CronetEnvironment::CronetNetworkThread::CronetNetworkThread(
496 const std::string& name,
497 cronet::CronetEnvironment* cronet_environment)
498 : base::Thread(name), cronet_environment_(cronet_environment) {}
499
500CronetEnvironment::CronetNetworkThread::~CronetNetworkThread() {
501 Stop();
502}
503
504void CronetEnvironment::CronetNetworkThread::CleanUp() {
505 cronet_environment_->CleanUpOnNetworkThread();
506}
507
mef06eab3e82016-04-14 22:45:49508} // namespace cronet