Upstream version 8.37.180.0
[platform/framework/web/crosswalk.git] / src / components / domain_reliability / uploader.cc
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
3 // found in the LICENSE file.
4
5 #include "components/domain_reliability/uploader.h"
6
7 #include "base/bind.h"
8 #include "base/callback.h"
9 #include "base/memory/scoped_vector.h"
10 #include "base/metrics/sparse_histogram.h"
11 #include "base/stl_util.h"
12 #include "base/supports_user_data.h"
13 #include "net/base/load_flags.h"
14 #include "net/url_request/url_fetcher.h"
15 #include "net/url_request/url_fetcher_delegate.h"
16 #include "net/url_request/url_request_context_getter.h"
17
18 namespace domain_reliability {
19
20 namespace {
21
22 const char* kJsonMimeType = "application/json; charset=utf-8";
23
24 class UploadUserData : public base::SupportsUserData::Data {
25  public:
26   static net::URLFetcher::CreateDataCallback CreateCreateDataCallback() {
27     return base::Bind(&UploadUserData::CreateUploadUserData);
28   }
29
30   static const void* kUserDataKey;
31
32  private:
33   static base::SupportsUserData::Data* CreateUploadUserData() {
34     return new UploadUserData();
35   }
36 };
37
38 const void* UploadUserData::kUserDataKey =
39     static_cast<const void*>(&UploadUserData::kUserDataKey);
40
41 class DomainReliabilityUploaderImpl
42     : public DomainReliabilityUploader, net::URLFetcherDelegate {
43  public:
44   DomainReliabilityUploaderImpl(const scoped_refptr<
45       net::URLRequestContextGetter>& url_request_context_getter)
46       : url_request_context_getter_(url_request_context_getter) {}
47
48   virtual ~DomainReliabilityUploaderImpl() {
49     // Delete any in-flight URLFetchers.
50     STLDeleteContainerPairFirstPointers(
51         upload_callbacks_.begin(), upload_callbacks_.end());
52   }
53
54   // DomainReliabilityUploader implementation:
55   virtual void UploadReport(
56       const std::string& report_json,
57       const GURL& upload_url,
58       const DomainReliabilityUploader::UploadCallback& callback) OVERRIDE {
59     VLOG(1) << "Uploading report to " << upload_url;
60     VLOG(2) << "Report JSON: " << report_json;
61
62     net::URLFetcher* fetcher =
63         net::URLFetcher::Create(0, upload_url, net::URLFetcher::POST, this);
64     fetcher->SetRequestContext(url_request_context_getter_);
65     fetcher->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES |
66                           net::LOAD_DO_NOT_SAVE_COOKIES);
67     fetcher->SetUploadData(kJsonMimeType, report_json);
68     fetcher->SetAutomaticallyRetryOn5xx(false);
69     fetcher->SetURLRequestUserData(
70         UploadUserData::kUserDataKey,
71         UploadUserData::CreateCreateDataCallback());
72     fetcher->Start();
73
74     upload_callbacks_[fetcher] = callback;
75   }
76
77   // net::URLFetcherDelegate implementation:
78   virtual void OnURLFetchComplete(
79       const net::URLFetcher* fetcher) OVERRIDE {
80     DCHECK(fetcher);
81
82     UploadCallbackMap::iterator callback_it = upload_callbacks_.find(fetcher);
83     DCHECK(callback_it != upload_callbacks_.end());
84
85     VLOG(1) << "Upload finished with " << fetcher->GetResponseCode();
86
87     UMA_HISTOGRAM_SPARSE_SLOWLY("DomainReliability.UploadResponseCode",
88                                 fetcher->GetResponseCode());
89
90     bool success = fetcher->GetResponseCode() == 200;
91     callback_it->second.Run(success);
92
93     delete callback_it->first;
94     upload_callbacks_.erase(callback_it);
95   }
96
97  private:
98   using DomainReliabilityUploader::UploadCallback;
99   typedef std::map<const net::URLFetcher*, UploadCallback> UploadCallbackMap;
100
101   scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_;
102   UploadCallbackMap upload_callbacks_;
103 };
104
105 }  // namespace
106
107 DomainReliabilityUploader::DomainReliabilityUploader() {}
108 DomainReliabilityUploader::~DomainReliabilityUploader() {}
109
110 // static
111 scoped_ptr<DomainReliabilityUploader> DomainReliabilityUploader::Create(
112     const scoped_refptr<net::URLRequestContextGetter>&
113         url_request_context_getter) {
114   return scoped_ptr<DomainReliabilityUploader>(
115       new DomainReliabilityUploaderImpl(url_request_context_getter));
116 }
117
118 // static
119 bool DomainReliabilityUploader::URLRequestIsUpload(
120     const net::URLRequest& request) {
121   return request.GetUserData(UploadUserData::kUserDataKey) != NULL;
122 }
123
124 }  // namespace domain_reliability