Update To 11.40.268.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/base/net_errors.h"
15 #include "net/url_request/url_fetcher.h"
16 #include "net/url_request/url_fetcher_delegate.h"
17 #include "net/url_request/url_request_context_getter.h"
18
19 namespace domain_reliability {
20
21 namespace {
22
23 const char* kJsonMimeType = "application/json; charset=utf-8";
24
25 class UploadUserData : public base::SupportsUserData::Data {
26  public:
27   static net::URLFetcher::CreateDataCallback CreateCreateDataCallback() {
28     return base::Bind(&UploadUserData::CreateUploadUserData);
29   }
30
31   static const void* kUserDataKey;
32
33  private:
34   static base::SupportsUserData::Data* CreateUploadUserData() {
35     return new UploadUserData();
36   }
37 };
38
39 const void* UploadUserData::kUserDataKey =
40     static_cast<const void*>(&UploadUserData::kUserDataKey);
41
42 class DomainReliabilityUploaderImpl
43     : public DomainReliabilityUploader, net::URLFetcherDelegate {
44  public:
45   DomainReliabilityUploaderImpl(const scoped_refptr<
46       net::URLRequestContextGetter>& url_request_context_getter)
47       : url_request_context_getter_(url_request_context_getter),
48         discard_uploads_(true) {}
49
50   ~DomainReliabilityUploaderImpl() override {
51     // Delete any in-flight URLFetchers.
52     STLDeleteContainerPairFirstPointers(
53         upload_callbacks_.begin(), upload_callbacks_.end());
54   }
55
56   // DomainReliabilityUploader implementation:
57   void UploadReport(
58       const std::string& report_json,
59       const GURL& upload_url,
60       const DomainReliabilityUploader::UploadCallback& callback) override {
61     VLOG(1) << "Uploading report to " << upload_url;
62     VLOG(2) << "Report JSON: " << report_json;
63
64     if (discard_uploads_) {
65       VLOG(1) << "Discarding report instead of uploading.";
66       callback.Run(true);
67       return;
68     }
69
70     net::URLFetcher* fetcher =
71         net::URLFetcher::Create(0, upload_url, net::URLFetcher::POST, this);
72     fetcher->SetRequestContext(url_request_context_getter_.get());
73     fetcher->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES |
74                           net::LOAD_DO_NOT_SAVE_COOKIES);
75     fetcher->SetUploadData(kJsonMimeType, report_json);
76     fetcher->SetAutomaticallyRetryOn5xx(false);
77     fetcher->SetURLRequestUserData(
78         UploadUserData::kUserDataKey,
79         UploadUserData::CreateCreateDataCallback());
80     fetcher->Start();
81
82     upload_callbacks_[fetcher] = callback;
83   }
84
85   void set_discard_uploads(bool discard_uploads) override {
86     discard_uploads_ = discard_uploads;
87     VLOG(1) << "Setting discard_uploads to " << discard_uploads;
88   }
89
90   // net::URLFetcherDelegate implementation:
91   void OnURLFetchComplete(const net::URLFetcher* fetcher) override {
92     DCHECK(fetcher);
93
94     UploadCallbackMap::iterator callback_it = upload_callbacks_.find(fetcher);
95     DCHECK(callback_it != upload_callbacks_.end());
96
97     int net_error;
98     {
99       const net::URLRequestStatus& status = fetcher->GetStatus();
100       switch (status.status()) {
101         case net::URLRequestStatus::SUCCESS:
102           net_error = net::OK;
103           break;
104         case net::URLRequestStatus::CANCELED:
105           net_error = net::ERR_ABORTED;
106           break;
107         case net::URLRequestStatus::FAILED:
108           net_error = status.error();
109           break;
110         default:
111           NOTREACHED();
112           net_error = net::ERR_FAILED;
113           break;
114       }
115     }
116     int http_response_code = fetcher->GetResponseCode();
117
118     VLOG(1) << "Upload finished with net error " << net_error <<
119                " and HTTP response code " << http_response_code;
120
121     UMA_HISTOGRAM_SPARSE_SLOWLY("DomainReliability.UploadResponseCode",
122                                 http_response_code);
123     UMA_HISTOGRAM_SPARSE_SLOWLY("DomainReliability.UploadNetError",
124                                 -net_error);
125
126     callback_it->second.Run(http_response_code == 200);
127
128     delete callback_it->first;
129     upload_callbacks_.erase(callback_it);
130   }
131
132  private:
133   using DomainReliabilityUploader::UploadCallback;
134   typedef std::map<const net::URLFetcher*, UploadCallback> UploadCallbackMap;
135
136   scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_;
137   UploadCallbackMap upload_callbacks_;
138   bool discard_uploads_;
139 };
140
141 }  // namespace
142
143 DomainReliabilityUploader::DomainReliabilityUploader() {}
144 DomainReliabilityUploader::~DomainReliabilityUploader() {}
145
146 // static
147 scoped_ptr<DomainReliabilityUploader> DomainReliabilityUploader::Create(
148     const scoped_refptr<net::URLRequestContextGetter>&
149         url_request_context_getter) {
150   return scoped_ptr<DomainReliabilityUploader>(
151       new DomainReliabilityUploaderImpl(url_request_context_getter));
152 }
153
154 // static
155 bool DomainReliabilityUploader::URLRequestIsUpload(
156     const net::URLRequest& request) {
157   return request.GetUserData(UploadUserData::kUserDataKey) != NULL;
158 }
159
160 }  // namespace domain_reliability