Upstream version 7.36.149.0
[platform/framework/web/crosswalk.git] / src / components / domain_reliability / monitor.cc
index 8f0b8cd..29b276d 100644 (file)
@@ -5,9 +5,13 @@
 #include "components/domain_reliability/monitor.h"
 
 #include "base/command_line.h"
+#include "base/logging.h"
 #include "base/message_loop/message_loop.h"
 #include "base/single_thread_task_runner.h"
+#include "base/time/time.h"
+#include "components/domain_reliability/baked_in_configs.h"
 #include "content/public/browser/browser_thread.h"
+#include "net/base/load_flags.h"
 #include "net/url_request/url_request.h"
 #include "net/url_request/url_request_context.h"
 #include "net/url_request/url_request_context_getter.h"
@@ -28,7 +32,7 @@ class TrivialURLRequestContextGetter : public net::URLRequestContextGetter {
       : context_(context),
         main_task_runner_(main_task_runner) {}
 
-  // net::URLRequestContextGEtter implementation:
+  // net::URLRequestContextGetter implementation:
   virtual net::URLRequestContext* GetURLRequestContext() OVERRIDE {
     return context_;
   }
@@ -50,13 +54,15 @@ class TrivialURLRequestContextGetter : public net::URLRequestContextGetter {
 namespace domain_reliability {
 
 DomainReliabilityMonitor::DomainReliabilityMonitor(
-    net::URLRequestContext* url_request_context)
+    net::URLRequestContext* url_request_context,
+    const std::string& upload_reporter_string)
     : time_(new ActualTime()),
       url_request_context_getter_(scoped_refptr<net::URLRequestContextGetter>(
           new TrivialURLRequestContextGetter(
               url_request_context,
               content::BrowserThread::GetMessageLoopProxyForThread(
                   content::BrowserThread::IO)))),
+      upload_reporter_string_(upload_reporter_string),
       scheduler_params_(
           DomainReliabilityScheduler::Params::GetFromFieldTrialsOrDefaults()),
       dispatcher_(time_.get()),
@@ -67,6 +73,7 @@ DomainReliabilityMonitor::DomainReliabilityMonitor(
 
 DomainReliabilityMonitor::DomainReliabilityMonitor(
     net::URLRequestContext* url_request_context,
+    const std::string& upload_reporter_string,
     scoped_ptr<MockableTime> time)
     : time_(time.Pass()),
       url_request_context_getter_(scoped_refptr<net::URLRequestContextGetter>(
@@ -74,6 +81,7 @@ DomainReliabilityMonitor::DomainReliabilityMonitor(
               url_request_context,
               content::BrowserThread::GetMessageLoopProxyForThread(
                   content::BrowserThread::IO)))),
+      upload_reporter_string_(upload_reporter_string),
       scheduler_params_(
           DomainReliabilityScheduler::Params::GetFromFieldTrialsOrDefaults()),
       dispatcher_(time_.get()),
@@ -84,15 +92,28 @@ DomainReliabilityMonitor::DomainReliabilityMonitor(
 
 DomainReliabilityMonitor::~DomainReliabilityMonitor() {
   DCHECK(OnIOThread());
-  STLDeleteContainerPairSecondPointers(
-      contexts_.begin(), contexts_.end());
+  STLDeleteContainerPairSecondPointers(contexts_.begin(), contexts_.end());
+}
+
+void DomainReliabilityMonitor::AddBakedInConfigs() {
+  base::Time now = base::Time::Now();
+  for (size_t i = 0; kBakedInJsonConfigs[i]; ++i) {
+    std::string json(kBakedInJsonConfigs[i]);
+    scoped_ptr<const DomainReliabilityConfig> config =
+        DomainReliabilityConfig::FromJSON(json);
+    if (config && config->IsExpired(now)) {
+      LOG(WARNING) << "Baked-in Domain Reliability config for "
+                   << config->domain << " is expired.";
+      continue;
+    }
+    AddContext(config.Pass());
+  }
 }
 
 void DomainReliabilityMonitor::OnBeforeRedirect(net::URLRequest* request) {
   DCHECK(OnIOThread());
-  RequestInfo request_info(*request);
   // Record the redirect itself in addition to the final request.
-  OnRequestLegComplete(request_info);
+  OnRequestLegComplete(RequestInfo(*request));
 }
 
 void DomainReliabilityMonitor::OnCompleted(net::URLRequest* request,
@@ -101,20 +122,17 @@ void DomainReliabilityMonitor::OnCompleted(net::URLRequest* request,
   if (!started)
     return;
   RequestInfo request_info(*request);
-  OnRequestLegComplete(request_info);
+  if (request_info.DefinitelyReachedNetwork()) {
+    OnRequestLegComplete(request_info);
+    // A request was just using the network, so now is a good time to run any
+    // pending and eligible uploads.
+    dispatcher_.RunEligibleTasks();
+  }
 }
 
 DomainReliabilityContext* DomainReliabilityMonitor::AddContextForTesting(
     scoped_ptr<const DomainReliabilityConfig> config) {
-  DomainReliabilityContext*& context_ref = contexts_[config->domain];
-  DCHECK(!context_ref);
-  context_ref = new DomainReliabilityContext(
-      time_.get(),
-      scheduler_params_,
-      &dispatcher_,
-      uploader_.get(),
-      config.Pass());
-  return context_ref;
+  return AddContext(config.Pass());
 }
 
 DomainReliabilityMonitor::RequestInfo::RequestInfo() {}
@@ -125,7 +143,9 @@ DomainReliabilityMonitor::RequestInfo::RequestInfo(
       status(request.status()),
       response_code(-1),
       socket_address(request.GetSocketAddress()),
-      was_cached(request.was_cached()) {
+      was_cached(request.was_cached()),
+      load_flags(request.load_flags()),
+      is_upload(DomainReliabilityUploader::URLRequestIsUpload(request)) {
   request.GetLoadTimingInfo(&load_timing_info);
   // Can't get response code of a canceled request -- there's no transaction.
   if (status.status() != net::URLRequestStatus::CANCELED)
@@ -134,21 +154,57 @@ DomainReliabilityMonitor::RequestInfo::RequestInfo(
 
 DomainReliabilityMonitor::RequestInfo::~RequestInfo() {}
 
+bool DomainReliabilityMonitor::RequestInfo::DefinitelyReachedNetwork() const {
+  return status.status() != net::URLRequestStatus::CANCELED && !was_cached;
+}
+
+DomainReliabilityContext* DomainReliabilityMonitor::AddContext(
+    scoped_ptr<const DomainReliabilityConfig> config) {
+  DCHECK(config);
+  DCHECK(config->IsValid());
+
+  // Grab a copy of the domain before transferring ownership of |config|.
+  std::string domain = config->domain;
+
+  DomainReliabilityContext* context =
+      new DomainReliabilityContext(time_.get(),
+                                   scheduler_params_,
+                                   upload_reporter_string_,
+                                   &dispatcher_,
+                                   uploader_.get(),
+                                   config.Pass());
+
+  std::pair<ContextMap::iterator, bool> map_it =
+      contexts_.insert(make_pair(domain, context));
+  // Make sure the domain wasn't already in the map.
+  DCHECK(map_it.second);
+
+  return map_it.first->second;
+}
+
 void DomainReliabilityMonitor::OnRequestLegComplete(
     const RequestInfo& request) {
-  if (request.was_cached ||
-      request.status.status() == net::URLRequestStatus::CANCELED) {
+  if (!request.DefinitelyReachedNetwork())
+    return;
+
+  // Don't monitor requests that are not sending cookies, since sending a beacon
+  // for such requests may allow the server to correlate that request with the
+  // user (by correlating a particular config).
+  if (request.load_flags & net::LOAD_DO_NOT_SEND_COOKIES)
+    return;
+
+  // Don't monitor requests that were, themselves, Domain Reliability uploads,
+  // to avoid infinite chains of uploads.
+  if (request.is_upload)
     return;
-  }
 
-  std::map<std::string, DomainReliabilityContext*>::iterator it =
-      contexts_.find(request.url.host());
+  ContextMap::iterator it = contexts_.find(request.url.host());
   if (it == contexts_.end())
     return;
   DomainReliabilityContext* context = it->second;
 
   std::string beacon_status;
-  bool got_status = DomainReliabilityUtil::GetBeaconStatus(
+  bool got_status = GetDomainReliabilityBeaconStatus(
       request.status.error(),
       request.response_code,
       &beacon_status);
@@ -161,8 +217,8 @@ void DomainReliabilityMonitor::OnRequestLegComplete(
   beacon.server_ip = request.socket_address.host();
   beacon.http_response_code = request.response_code;
   beacon.start_time = request.load_timing_info.request_start;
-  beacon.elapsed = time_->Now() - beacon.start_time;
-  context->AddBeacon(beacon, request.url);
+  beacon.elapsed = time_->NowTicks() - beacon.start_time;
+  context->OnBeacon(request.url, beacon);
 }
 
 }  // namespace domain_reliability