| Index: net/tools/get_server_time/get_server_time.cc
|
| diff --git a/net/tools/get_server_time/get_server_time.cc b/net/tools/get_server_time/get_server_time.cc
|
| deleted file mode 100644
|
| index 800bb34a1c40508193ff4d2abf2b63bc51bafac2..0000000000000000000000000000000000000000
|
| --- a/net/tools/get_server_time/get_server_time.cc
|
| +++ /dev/null
|
| @@ -1,325 +0,0 @@
|
| -// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
| -// Use of this source code is governed by a BSD-style license that can be
|
| -// found in the LICENSE file.
|
| -
|
| -// This is a small utility that snarfs the server time from the
|
| -// response headers of an http/https HEAD request and compares it to
|
| -// the local time.
|
| -//
|
| -// TODO(akalin): Also snarf the server time from the TLS handshake, if
|
| -// any (http://crbug.com/146090).
|
| -
|
| -#include <cstdio>
|
| -#include <cstdlib>
|
| -#include <string>
|
| -
|
| -#include "base/at_exit.h"
|
| -#include "base/basictypes.h"
|
| -#include "base/command_line.h"
|
| -#include "base/compiler_specific.h"
|
| -#include "base/format_macros.h"
|
| -#include "base/i18n/time_formatting.h"
|
| -#include "base/json/json_writer.h"
|
| -#include "base/logging.h"
|
| -#include "base/memory/ref_counted.h"
|
| -#include "base/memory/scoped_ptr.h"
|
| -#include "base/message_loop/message_loop.h"
|
| -#include "base/single_thread_task_runner.h"
|
| -#include "base/strings/string_number_conversions.h"
|
| -#include "base/strings/utf_string_conversions.h"
|
| -#include "base/time/time.h"
|
| -#include "base/values.h"
|
| -#include "build/build_config.h"
|
| -#include "net/base/net_errors.h"
|
| -#include "net/base/net_log.h"
|
| -#include "net/http/http_response_headers.h"
|
| -#include "net/url_request/url_fetcher.h"
|
| -#include "net/url_request/url_fetcher_delegate.h"
|
| -#include "net/url_request/url_request_context.h"
|
| -#include "net/url_request/url_request_context_builder.h"
|
| -#include "net/url_request/url_request_context_getter.h"
|
| -#include "net/url_request/url_request_status.h"
|
| -#include "url/gurl.h"
|
| -
|
| -#if defined(OS_MACOSX)
|
| -#include "base/mac/scoped_nsautorelease_pool.h"
|
| -#elif defined(OS_LINUX)
|
| -#include "net/proxy/proxy_config.h"
|
| -#include "net/proxy/proxy_config_service_fixed.h"
|
| -#endif
|
| -
|
| -using base::UTF16ToUTF8;
|
| -
|
| -namespace {
|
| -
|
| -// base::TimeTicks::Now() is documented to have a resolution of
|
| -// ~1-15ms.
|
| -const int64 kTicksResolutionMs = 15;
|
| -
|
| -// For the sources that are supported (HTTP date headers, TLS
|
| -// handshake), the resolution of the server time is 1 second.
|
| -const int64 kServerTimeResolutionMs = 1000;
|
| -
|
| -// Assume base::Time::Now() has the same resolution as
|
| -// base::TimeTicks::Now().
|
| -//
|
| -// TODO(akalin): Figure out the real resolution.
|
| -const int64 kTimeResolutionMs = kTicksResolutionMs;
|
| -
|
| -// Simply quits the current message loop when finished. Used to make
|
| -// URLFetcher synchronous.
|
| -class QuitDelegate : public net::URLFetcherDelegate {
|
| - public:
|
| - QuitDelegate() {}
|
| -
|
| - ~QuitDelegate() override {}
|
| -
|
| - // net::URLFetcherDelegate implementation.
|
| - void OnURLFetchComplete(const net::URLFetcher* source) override {
|
| - base::MessageLoop::current()->Quit();
|
| - }
|
| -
|
| - void OnURLFetchDownloadProgress(const net::URLFetcher* source,
|
| - int64 current,
|
| - int64 total) override {
|
| - NOTREACHED();
|
| - }
|
| -
|
| - void OnURLFetchUploadProgress(const net::URLFetcher* source,
|
| - int64 current,
|
| - int64 total) override {
|
| - NOTREACHED();
|
| - }
|
| -
|
| - private:
|
| - DISALLOW_COPY_AND_ASSIGN(QuitDelegate);
|
| -};
|
| -
|
| -// NetLog::ThreadSafeObserver implementation that simply prints events
|
| -// to the logs.
|
| -class PrintingLogObserver : public net::NetLog::ThreadSafeObserver {
|
| - public:
|
| - PrintingLogObserver() {}
|
| -
|
| - ~PrintingLogObserver() override {
|
| - // This is guaranteed to be safe as this program is single threaded.
|
| - net_log()->RemoveThreadSafeObserver(this);
|
| - }
|
| -
|
| - // NetLog::ThreadSafeObserver implementation:
|
| - void OnAddEntry(const net::NetLog::Entry& entry) override {
|
| - // The log level of the entry is unknown, so just assume it maps
|
| - // to VLOG(1).
|
| - if (!VLOG_IS_ON(1))
|
| - return;
|
| -
|
| - const char* const source_type =
|
| - net::NetLog::SourceTypeToString(entry.source().type);
|
| - const char* const event_type =
|
| - net::NetLog::EventTypeToString(entry.type());
|
| - const char* const event_phase =
|
| - net::NetLog::EventPhaseToString(entry.phase());
|
| - scoped_ptr<base::Value> params(entry.ParametersToValue());
|
| - std::string params_str;
|
| - if (params.get()) {
|
| - base::JSONWriter::Write(params.get(), ¶ms_str);
|
| - params_str.insert(0, ": ");
|
| - }
|
| -
|
| - VLOG(1) << source_type << "(" << entry.source().id << "): "
|
| - << event_type << ": " << event_phase << params_str;
|
| - }
|
| -
|
| - private:
|
| - DISALLOW_COPY_AND_ASSIGN(PrintingLogObserver);
|
| -};
|
| -
|
| -// Builds a URLRequestContext assuming there's only a single loop.
|
| -scoped_ptr<net::URLRequestContext>
|
| -BuildURLRequestContext(net::NetLog* net_log) {
|
| - net::URLRequestContextBuilder builder;
|
| -#if defined(OS_LINUX)
|
| - // On Linux, use a fixed ProxyConfigService, since the default one
|
| - // depends on glib.
|
| - //
|
| - // TODO(akalin): Remove this once http://crbug.com/146421 is fixed.
|
| - builder.set_proxy_config_service(
|
| - new net::ProxyConfigServiceFixed(net::ProxyConfig()));
|
| -#endif
|
| - scoped_ptr<net::URLRequestContext> context(builder.Build());
|
| - context->set_net_log(net_log);
|
| - return context.Pass();
|
| -}
|
| -
|
| -// Assuming that the time |server_time| was received from a server,
|
| -// that the request for the server was started on |start_ticks|, and
|
| -// that it ended on |end_ticks|, fills |server_now| with an estimate
|
| -// of the current time and |server_now_uncertainty| with a
|
| -// conservative estimate of the uncertainty.
|
| -void EstimateServerTimeNow(base::Time server_time,
|
| - base::TimeTicks start_ticks,
|
| - base::TimeTicks end_ticks,
|
| - base::Time* server_now,
|
| - base::TimeDelta* server_now_uncertainty) {
|
| - const base::TimeDelta delta_ticks = end_ticks - start_ticks;
|
| - const base::TimeTicks mid_ticks = start_ticks + delta_ticks / 2;
|
| - const base::TimeDelta estimated_elapsed = base::TimeTicks::Now() - mid_ticks;
|
| -
|
| - *server_now = server_time + estimated_elapsed;
|
| -
|
| - *server_now_uncertainty =
|
| - base::TimeDelta::FromMilliseconds(kServerTimeResolutionMs) +
|
| - delta_ticks + 3 * base::TimeDelta::FromMilliseconds(kTicksResolutionMs);
|
| -}
|
| -
|
| -// Assuming that the time of the server is |server_now| with
|
| -// uncertainty |server_now_uncertainty| and that the local time is
|
| -// |now|, fills |skew| with the skew of the local clock (i.e., add
|
| -// |*skew| to a client time to get a server time) and
|
| -// |skew_uncertainty| with a conservative estimate of the uncertainty.
|
| -void EstimateSkew(base::Time server_now,
|
| - base::TimeDelta server_now_uncertainty,
|
| - base::Time now,
|
| - base::TimeDelta now_uncertainty,
|
| - base::TimeDelta* skew,
|
| - base::TimeDelta* skew_uncertainty) {
|
| - *skew = server_now - now;
|
| - *skew_uncertainty = server_now_uncertainty + now_uncertainty;
|
| -}
|
| -
|
| -} // namespace
|
| -
|
| -int main(int argc, char* argv[]) {
|
| -#if defined(OS_MACOSX)
|
| - base::mac::ScopedNSAutoreleasePool pool;
|
| -#endif
|
| -
|
| - base::AtExitManager exit_manager;
|
| - base::CommandLine::Init(argc, argv);
|
| - logging::LoggingSettings settings;
|
| - settings.logging_dest = logging::LOG_TO_SYSTEM_DEBUG_LOG;
|
| - logging::InitLogging(settings);
|
| -
|
| - const base::CommandLine& parsed_command_line =
|
| - *base::CommandLine::ForCurrentProcess();
|
| - GURL url(parsed_command_line.GetSwitchValueASCII("url"));
|
| - if (!url.is_valid() ||
|
| - (url.scheme() != "http" && url.scheme() != "https")) {
|
| - std::fprintf(
|
| - stderr,
|
| - "Usage: %s --url=[http|https]://www.example.com [--v=[1|2]]\n",
|
| - argv[0]);
|
| - return EXIT_FAILURE;
|
| - }
|
| -
|
| - base::MessageLoopForIO main_loop;
|
| -
|
| - // NOTE: A NetworkChangeNotifier could be instantiated here, but
|
| - // that interferes with the request that will be sent; some
|
| - // implementations always send out an OnIPAddressChanged() message,
|
| - // which causes the DNS resolution to abort. It's simpler to just
|
| - // not instantiate one, since only a single request is sent anyway.
|
| -
|
| - // The declaration order for net_log and printing_log_observer is
|
| - // important. The destructor of PrintingLogObserver removes itself
|
| - // from net_log, so net_log must be available for entire lifetime of
|
| - // printing_log_observer.
|
| - net::NetLog net_log;
|
| - PrintingLogObserver printing_log_observer;
|
| - net_log.AddThreadSafeObserver(&printing_log_observer, net::NetLog::LOG_ALL);
|
| -
|
| - QuitDelegate delegate;
|
| - scoped_ptr<net::URLFetcher> fetcher(
|
| - net::URLFetcher::Create(url, net::URLFetcher::HEAD, &delegate));
|
| - scoped_ptr<net::URLRequestContext> url_request_context(
|
| - BuildURLRequestContext(&net_log));
|
| - fetcher->SetRequestContext(
|
| - // Since there's only a single thread, there's no need to worry
|
| - // about when the URLRequestContext gets created.
|
| - // The URLFetcher will take a reference on the object, and hence
|
| - // implicitly take ownership.
|
| - new net::TrivialURLRequestContextGetter(url_request_context.get(),
|
| - main_loop.message_loop_proxy()));
|
| - const base::Time start_time = base::Time::Now();
|
| - const base::TimeTicks start_ticks = base::TimeTicks::Now();
|
| -
|
| - fetcher->Start();
|
| - std::printf(
|
| - "Request started at %s (ticks = %" PRId64 ")\n",
|
| - UTF16ToUTF8(base::TimeFormatFriendlyDateAndTime(start_time)).c_str(),
|
| - start_ticks.ToInternalValue());
|
| -
|
| - // |delegate| quits |main_loop| when the request is done.
|
| - main_loop.Run();
|
| -
|
| - const base::Time end_time = base::Time::Now();
|
| - const base::TimeTicks end_ticks = base::TimeTicks::Now();
|
| -
|
| - std::printf(
|
| - "Request ended at %s (ticks = %" PRId64 ")\n",
|
| - UTF16ToUTF8(base::TimeFormatFriendlyDateAndTime(end_time)).c_str(),
|
| - end_ticks.ToInternalValue());
|
| -
|
| - const int64 delta_ticks_internal =
|
| - end_ticks.ToInternalValue() - start_ticks.ToInternalValue();
|
| - const base::TimeDelta delta_ticks = end_ticks - start_ticks;
|
| -
|
| - std::printf(
|
| - "Request took %" PRId64 " ticks (%.2f ms)\n",
|
| - delta_ticks_internal, delta_ticks.InMillisecondsF());
|
| -
|
| - const net::URLRequestStatus status = fetcher->GetStatus();
|
| - if (status.status() != net::URLRequestStatus::SUCCESS) {
|
| - LOG(ERROR) << "Request failed with error code: "
|
| - << net::ErrorToString(status.error());
|
| - return EXIT_FAILURE;
|
| - }
|
| -
|
| - const net::HttpResponseHeaders* const headers =
|
| - fetcher->GetResponseHeaders();
|
| - if (!headers) {
|
| - LOG(ERROR) << "Response does not have any headers";
|
| - return EXIT_FAILURE;
|
| - }
|
| -
|
| - void* iter = NULL;
|
| - std::string date_header;
|
| - while (headers->EnumerateHeader(&iter, "Date", &date_header)) {
|
| - std::printf("Got date header: %s\n", date_header.c_str());
|
| - }
|
| -
|
| - base::Time server_time;
|
| - if (!headers->GetDateValue(&server_time)) {
|
| - LOG(ERROR) << "Could not parse time from server response headers";
|
| - return EXIT_FAILURE;
|
| - }
|
| -
|
| - std::printf(
|
| - "Got time %s from server\n",
|
| - UTF16ToUTF8(base::TimeFormatFriendlyDateAndTime(server_time)).c_str());
|
| -
|
| - base::Time server_now;
|
| - base::TimeDelta server_now_uncertainty;
|
| - EstimateServerTimeNow(server_time, start_ticks, end_ticks,
|
| - &server_now, &server_now_uncertainty);
|
| - base::Time now = base::Time::Now();
|
| -
|
| - std::printf(
|
| - "According to the server, it is now %s with uncertainty %.2f ms\n",
|
| - UTF16ToUTF8(base::TimeFormatFriendlyDateAndTime(server_now)).c_str(),
|
| - server_now_uncertainty.InMillisecondsF());
|
| -
|
| - base::TimeDelta skew;
|
| - base::TimeDelta skew_uncertainty;
|
| - EstimateSkew(server_now, server_now_uncertainty, now,
|
| - base::TimeDelta::FromMilliseconds(kTimeResolutionMs),
|
| - &skew, &skew_uncertainty);
|
| -
|
| - std::printf(
|
| - "An estimate for the local clock skew is %.2f ms with "
|
| - "uncertainty %.2f ms\n",
|
| - skew.InMillisecondsF(),
|
| - skew_uncertainty.InMillisecondsF());
|
| -
|
| - return EXIT_SUCCESS;
|
| -}
|
|
|