Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "components/network_time/network_time_tracker.h" | 5 #include "components/network_time/network_time_tracker.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 #include <string> | 8 #include <string> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| 11 #include "base/feature_list.h" | 11 #include "base/feature_list.h" |
| 12 #include "base/i18n/time_formatting.h" | 12 #include "base/i18n/time_formatting.h" |
| 13 #include "base/json/json_reader.h" | 13 #include "base/json/json_reader.h" |
| 14 #include "base/logging.h" | 14 #include "base/logging.h" |
| 15 #include "base/message_loop/message_loop.h" | 15 #include "base/message_loop/message_loop.h" |
| 16 #include "base/metrics/histogram_macros.h" | |
| 17 #include "base/metrics/sparse_histogram.h" | |
| 16 #include "base/rand_util.h" | 18 #include "base/rand_util.h" |
| 17 #include "base/run_loop.h" | 19 #include "base/run_loop.h" |
| 18 #include "base/strings/string_number_conversions.h" | 20 #include "base/strings/string_number_conversions.h" |
| 19 #include "base/strings/utf_string_conversions.h" | 21 #include "base/strings/utf_string_conversions.h" |
| 20 #include "base/time/tick_clock.h" | 22 #include "base/time/tick_clock.h" |
| 21 #include "build/build_config.h" | 23 #include "build/build_config.h" |
| 22 #include "components/client_update_protocol/ecdsa.h" | 24 #include "components/client_update_protocol/ecdsa.h" |
| 23 #include "components/network_time/network_time_pref_names.h" | 25 #include "components/network_time/network_time_pref_names.h" |
| 24 #include "components/prefs/pref_registry_simple.h" | 26 #include "components/prefs/pref_registry_simple.h" |
| 25 #include "components/prefs/pref_service.h" | 27 #include "components/prefs/pref_service.h" |
| (...skipping 334 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 360 time_fetcher_->SaveResponseWithWriter( | 362 time_fetcher_->SaveResponseWithWriter( |
| 361 std::unique_ptr<net::URLFetcherResponseWriter>( | 363 std::unique_ptr<net::URLFetcherResponseWriter>( |
| 362 new SizeLimitingStringWriter(max_response_size_))); | 364 new SizeLimitingStringWriter(max_response_size_))); |
| 363 DCHECK(getter_); | 365 DCHECK(getter_); |
| 364 time_fetcher_->SetRequestContext(getter_.get()); | 366 time_fetcher_->SetRequestContext(getter_.get()); |
| 365 // Not expecting any cookies, but just in case. | 367 // Not expecting any cookies, but just in case. |
| 366 time_fetcher_->SetLoadFlags(net::LOAD_BYPASS_CACHE | net::LOAD_DISABLE_CACHE | | 368 time_fetcher_->SetLoadFlags(net::LOAD_BYPASS_CACHE | net::LOAD_DISABLE_CACHE | |
| 367 net::LOAD_DO_NOT_SAVE_COOKIES | | 369 net::LOAD_DO_NOT_SAVE_COOKIES | |
| 368 net::LOAD_DO_NOT_SEND_COOKIES | | 370 net::LOAD_DO_NOT_SEND_COOKIES | |
| 369 net::LOAD_DO_NOT_SEND_AUTH_DATA); | 371 net::LOAD_DO_NOT_SEND_AUTH_DATA); |
| 372 | |
| 373 UMA_HISTOGRAM_BOOLEAN("NetworkTimeTracker.UpdateTimeFetchAttempted", true); | |
| 374 | |
| 370 time_fetcher_->Start(); | 375 time_fetcher_->Start(); |
| 371 fetch_started_ = tick_clock_->NowTicks(); | 376 fetch_started_ = tick_clock_->NowTicks(); |
| 372 | 377 |
| 373 timer_.Stop(); // Restarted in OnURLFetchComplete(). | 378 timer_.Stop(); // Restarted in OnURLFetchComplete(). |
| 374 } | 379 } |
| 375 | 380 |
| 376 bool NetworkTimeTracker::UpdateTimeFromResponse() { | 381 bool NetworkTimeTracker::UpdateTimeFromResponse() { |
| 377 if (time_fetcher_->GetStatus().status() != net::URLRequestStatus::SUCCESS && | 382 if (time_fetcher_->GetStatus().status() != net::URLRequestStatus::SUCCESS || |
| 378 time_fetcher_->GetResponseCode() != 200) { | 383 time_fetcher_->GetResponseCode() != 200) { |
| 379 DVLOG(1) << "fetch failed, status=" << time_fetcher_->GetStatus().status() | 384 DVLOG(1) << "fetch failed, status=" << time_fetcher_->GetStatus().status() |
| 380 << ",code=" << time_fetcher_->GetResponseCode(); | 385 << ",code=" << time_fetcher_->GetResponseCode(); |
| 386 // The error code is negated because net errors are negative, but | |
| 387 // the corresponding histogram enum is positive. | |
| 388 UMA_HISTOGRAM_SPARSE_SLOWLY("NetworkTimeTracker.UpdateTimeFetchFailed", | |
| 389 -time_fetcher_->GetStatus().error()); | |
| 381 return false; | 390 return false; |
| 382 } | 391 } |
| 383 | 392 |
| 393 const char kHistogramName[] = "NetworkTimeTracker.UpdateTimeFetchValid"; | |
| 394 | |
| 384 std::string response_body; | 395 std::string response_body; |
| 385 if (!time_fetcher_->GetResponseAsString(&response_body)) { | 396 if (!time_fetcher_->GetResponseAsString(&response_body)) { |
| 386 DVLOG(1) << "failed to get response"; | 397 DVLOG(1) << "failed to get response"; |
| 398 UMA_HISTOGRAM_BOOLEAN(kHistogramName, false); | |
|
Steven Holte
2016/07/28 19:22:46
This macro uses a static pointer to the underlying
estark
2016/07/28 20:30:49
Done.
| |
| 387 return false; | 399 return false; |
| 388 } | 400 } |
| 389 DCHECK(query_signer_); | 401 DCHECK(query_signer_); |
| 390 if (!query_signer_->ValidateResponse(response_body, | 402 if (!query_signer_->ValidateResponse(response_body, |
| 391 GetServerProof(time_fetcher_.get()))) { | 403 GetServerProof(time_fetcher_.get()))) { |
| 392 DVLOG(1) << "invalid signature"; | 404 DVLOG(1) << "invalid signature"; |
| 405 UMA_HISTOGRAM_BOOLEAN(kHistogramName, false); | |
| 393 return false; | 406 return false; |
| 394 } | 407 } |
| 395 response_body = response_body.substr(5); // Skips leading )]}'\n | 408 response_body = response_body.substr(5); // Skips leading )]}'\n |
| 396 std::unique_ptr<base::Value> value = base::JSONReader::Read(response_body); | 409 std::unique_ptr<base::Value> value = base::JSONReader::Read(response_body); |
| 397 if (!value) { | 410 if (!value) { |
| 398 DVLOG(1) << "bad JSON"; | 411 DVLOG(1) << "bad JSON"; |
| 412 UMA_HISTOGRAM_BOOLEAN(kHistogramName, false); | |
| 399 return false; | 413 return false; |
| 400 } | 414 } |
| 401 const base::DictionaryValue* dict; | 415 const base::DictionaryValue* dict; |
| 402 if (!value->GetAsDictionary(&dict)) { | 416 if (!value->GetAsDictionary(&dict)) { |
| 403 DVLOG(1) << "not a dictionary"; | 417 DVLOG(1) << "not a dictionary"; |
| 418 UMA_HISTOGRAM_BOOLEAN(kHistogramName, false); | |
| 404 return false; | 419 return false; |
| 405 } | 420 } |
| 406 double current_time_millis; | 421 double current_time_millis; |
| 407 if (!dict->GetDouble("current_time_millis", ¤t_time_millis)) { | 422 if (!dict->GetDouble("current_time_millis", ¤t_time_millis)) { |
| 408 DVLOG(1) << "no current_time_millis"; | 423 DVLOG(1) << "no current_time_millis"; |
| 424 UMA_HISTOGRAM_BOOLEAN(kHistogramName, false); | |
| 409 return false; | 425 return false; |
| 410 } | 426 } |
| 427 | |
| 428 UMA_HISTOGRAM_BOOLEAN(kHistogramName, true); | |
| 429 | |
| 411 // There is a "server_nonce" key here too, but it serves no purpose other than | 430 // There is a "server_nonce" key here too, but it serves no purpose other than |
| 412 // to make the server's response unpredictable. | 431 // to make the server's response unpredictable. |
| 413 base::Time current_time = base::Time::FromJsTime(current_time_millis); | 432 base::Time current_time = base::Time::FromJsTime(current_time_millis); |
| 414 base::TimeDelta resolution = | 433 base::TimeDelta resolution = |
| 415 base::TimeDelta::FromMilliseconds(1) + | 434 base::TimeDelta::FromMilliseconds(1) + |
| 416 base::TimeDelta::FromSeconds(kTimeServerMaxSkewSeconds); | 435 base::TimeDelta::FromSeconds(kTimeServerMaxSkewSeconds); |
| 417 base::TimeDelta latency = tick_clock_->NowTicks() - fetch_started_; | 436 base::TimeDelta latency = tick_clock_->NowTicks() - fetch_started_; |
| 418 UpdateNetworkTime(current_time, resolution, latency, tick_clock_->NowTicks()); | 437 UpdateNetworkTime(current_time, resolution, latency, tick_clock_->NowTicks()); |
| 419 return true; | 438 return true; |
| 420 } | 439 } |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 456 base::Time network_time; | 475 base::Time network_time; |
| 457 if (!GetNetworkTime(&network_time, nullptr)) { | 476 if (!GetNetworkTime(&network_time, nullptr)) { |
| 458 return true; | 477 return true; |
| 459 } | 478 } |
| 460 | 479 |
| 461 // Otherwise, make the decision at random. | 480 // Otherwise, make the decision at random. |
| 462 return base::RandDouble() < RandomQueryProbability(); | 481 return base::RandDouble() < RandomQueryProbability(); |
| 463 } | 482 } |
| 464 | 483 |
| 465 } // namespace network_time | 484 } // namespace network_time |
| OLD | NEW |