Upstream version 5.34.104.0
[platform/framework/web/crosswalk.git] / src / content / browser / loader / detachable_resource_handler.cc
index 42c7d1f..88e402b 100644 (file)
@@ -5,6 +5,7 @@
 #include "content/browser/loader/detachable_resource_handler.h"
 
 #include "base/logging.h"
+#include "base/metrics/histogram.h"
 #include "base/time/time.h"
 #include "content/browser/loader/resource_request_info_impl.h"
 #include "net/base/io_buffer.h"
 #include "net/url_request/url_request_status.h"
 
 namespace {
+
 // This matches the maximum allocation size of AsyncResourceHandler.
 const int kReadBufSize = 32 * 1024;
-}
+
+// Enum type for <a ping> result histograms. Only add new values to the end.
+enum UMAPingResultType {
+  // The ping request completed successfully.
+  UMA_PING_RESULT_TYPE_SUCCESS = 0,
+  // The ping request received a response, but did not consume the entire body.
+  UMA_PING_RESULT_TYPE_RESPONSE_STARTED = 1,
+  // The ping request was canceled due to the internal timeout.
+  UMA_PING_RESULT_TYPE_TIMEDOUT = 2,
+  // The ping request was canceled for some other reason.
+  UMA_PING_RESULT_TYPE_CANCELED = 3,
+  // The ping request failed for some reason.
+  UMA_PING_RESULT_TYPE_FAILED = 4,
+  // The ping request was deleted before OnResponseCompleted.
+  UMA_PING_RESULT_TYPE_UNCOMPLETED = 5,
+
+  UMA_PING_RESULT_TYPE_MAX,
+};
+
+}  // namespace
 
 namespace content {
 
@@ -26,13 +47,51 @@ DetachableResourceHandler::DetachableResourceHandler(
       next_handler_(next_handler.Pass()),
       cancel_delay_(cancel_delay),
       is_deferred_(false),
-      is_finished_(false) {
+      is_finished_(false),
+      timed_out_(false),
+      response_started_(false),
+      status_(net::URLRequestStatus::IO_PENDING) {
   GetRequestInfo()->set_detachable_handler(this);
 }
 
 DetachableResourceHandler::~DetachableResourceHandler() {
   // Cleanup back-pointer stored on the request info.
   GetRequestInfo()->set_detachable_handler(NULL);
+
+  // Record the status of <a ping> requests.
+  // http://crbug.com/302816
+  if (GetRequestInfo()->GetResourceType() == ResourceType::PING) {
+    UMAPingResultType result_type = UMA_PING_RESULT_TYPE_MAX;
+
+    if (status_ == net::URLRequestStatus::SUCCESS) {
+      result_type = UMA_PING_RESULT_TYPE_SUCCESS;
+    } else if (response_started_) {
+      // However the request ended, bucket this under RESPONSE_STARTED because
+      // OnResponseStarted was received. Note: OnResponseCompleted is also sent
+      // when a request is canceled before completion, so it is possible to
+      // receive OnResponseCompleted without OnResponseStarted.
+      result_type = UMA_PING_RESULT_TYPE_RESPONSE_STARTED;
+    } else if (status_ == net::URLRequestStatus::IO_PENDING) {
+      // The request was deleted without OnResponseCompleted and before any
+      // response was received.
+      result_type = UMA_PING_RESULT_TYPE_UNCOMPLETED;
+    } else if (status_ == net::URLRequestStatus::CANCELED) {
+      if (timed_out_) {
+        result_type = UMA_PING_RESULT_TYPE_TIMEDOUT;
+      } else {
+        result_type = UMA_PING_RESULT_TYPE_CANCELED;
+      }
+    } else if (status_ == net::URLRequestStatus::FAILED) {
+      result_type = UMA_PING_RESULT_TYPE_FAILED;
+    }
+
+    if (result_type < UMA_PING_RESULT_TYPE_MAX) {
+      UMA_HISTOGRAM_ENUMERATION("Net.Ping_Result", result_type,
+                                UMA_PING_RESULT_TYPE_MAX);
+    } else {
+      NOTREACHED();
+    }
+  }
 }
 
 void DetachableResourceHandler::Detach() {
@@ -65,7 +124,7 @@ void DetachableResourceHandler::Detach() {
   // Time the request out if it takes too long.
   detached_timer_.reset(new base::OneShotTimer<DetachableResourceHandler>());
   detached_timer_->Start(
-      FROM_HERE, cancel_delay_, this, &DetachableResourceHandler::Cancel);
+      FROM_HERE, cancel_delay_, this, &DetachableResourceHandler::TimedOut);
 
   // Resume if necessary. The request may have been deferred, say, waiting on a
   // full buffer in AsyncResourceHandler. Now that it has been detached, resume
@@ -111,6 +170,15 @@ bool DetachableResourceHandler::OnResponseStarted(int request_id,
                                                   ResourceResponse* response,
                                                   bool* defer) {
   DCHECK(!is_deferred_);
+  DCHECK(!response_started_);
+  response_started_ = true;
+
+  // Record how long it takes for <a ping> to respond.
+  // http://crbug.com/302816
+  if (GetRequestInfo()->GetResourceType() == ResourceType::PING) {
+    UMA_HISTOGRAM_MEDIUM_TIMES("Net.Ping_ResponseStartedTime",
+                               time_since_start_.Elapsed());
+  }
 
   if (!next_handler_)
     return true;
@@ -184,6 +252,9 @@ void DetachableResourceHandler::OnResponseCompleted(
   // No DCHECK(!is_deferred_) as the request may have been cancelled while
   // deferred.
 
+  status_ = status.status();
+  DCHECK_NE(net::URLRequestStatus::IO_PENDING, status_);
+
   if (!next_handler_)
     return;
 
@@ -220,4 +291,9 @@ void DetachableResourceHandler::CancelWithError(int error_code) {
   controller()->CancelWithError(error_code);
 }
 
+void DetachableResourceHandler::TimedOut() {
+  timed_out_ = true;
+  controller()->Cancel();
+}
+
 }  // namespace content