[Media Router] Add integration tests and e2e tests for media router and presentation...
[chromium-blink-merge.git] / components / domain_reliability / uploader.cc
blob031dac5bc35f7ffbe6cd97cf06aad0c37e6fc94d
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.
5 #include "components/domain_reliability/uploader.h"
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 "components/domain_reliability/util.h"
14 #include "net/base/load_flags.h"
15 #include "net/base/net_errors.h"
16 #include "net/http/http_response_headers.h"
17 #include "net/http/http_util.h"
18 #include "net/url_request/url_fetcher.h"
19 #include "net/url_request/url_fetcher_delegate.h"
20 #include "net/url_request/url_request_context_getter.h"
22 namespace domain_reliability {
24 namespace {
26 const char* kJsonMimeType = "application/json; charset=utf-8";
28 class UploadUserData : public base::SupportsUserData::Data {
29 public:
30 static net::URLFetcher::CreateDataCallback CreateCreateDataCallback() {
31 return base::Bind(&UploadUserData::CreateUploadUserData);
34 static const void* kUserDataKey;
36 private:
37 static base::SupportsUserData::Data* CreateUploadUserData() {
38 return new UploadUserData();
42 const void* UploadUserData::kUserDataKey =
43 static_cast<const void*>(&UploadUserData::kUserDataKey);
45 class DomainReliabilityUploaderImpl
46 : public DomainReliabilityUploader, net::URLFetcherDelegate {
47 public:
48 DomainReliabilityUploaderImpl(
49 MockableTime* time,
50 const scoped_refptr<
51 net::URLRequestContextGetter>& url_request_context_getter)
52 : time_(time),
53 url_request_context_getter_(url_request_context_getter),
54 discard_uploads_(true) {}
56 ~DomainReliabilityUploaderImpl() override {
57 // Delete any in-flight URLFetchers.
58 STLDeleteContainerPairFirstPointers(
59 upload_callbacks_.begin(), upload_callbacks_.end());
62 // DomainReliabilityUploader implementation:
63 void UploadReport(
64 const std::string& report_json,
65 const GURL& upload_url,
66 const DomainReliabilityUploader::UploadCallback& callback) override {
67 VLOG(1) << "Uploading report to " << upload_url;
68 VLOG(2) << "Report JSON: " << report_json;
70 if (discard_uploads_) {
71 VLOG(1) << "Discarding report instead of uploading.";
72 UploadResult result;
73 result.status = UploadResult::SUCCESS;
74 callback.Run(result);
75 return;
78 net::URLFetcher* fetcher =
79 net::URLFetcher::Create(0, upload_url, net::URLFetcher::POST, this)
80 .release();
81 fetcher->SetRequestContext(url_request_context_getter_.get());
82 fetcher->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES |
83 net::LOAD_DO_NOT_SAVE_COOKIES);
84 fetcher->SetUploadData(kJsonMimeType, report_json);
85 fetcher->SetAutomaticallyRetryOn5xx(false);
86 fetcher->SetURLRequestUserData(
87 UploadUserData::kUserDataKey,
88 UploadUserData::CreateCreateDataCallback());
89 fetcher->Start();
91 upload_callbacks_[fetcher] = callback;
94 void set_discard_uploads(bool discard_uploads) override {
95 discard_uploads_ = discard_uploads;
96 VLOG(1) << "Setting discard_uploads to " << discard_uploads;
99 // net::URLFetcherDelegate implementation:
100 void OnURLFetchComplete(const net::URLFetcher* fetcher) override {
101 DCHECK(fetcher);
103 UploadCallbackMap::iterator callback_it = upload_callbacks_.find(fetcher);
104 DCHECK(callback_it != upload_callbacks_.end());
106 int net_error = GetNetErrorFromURLRequestStatus(fetcher->GetStatus());
107 int http_response_code = fetcher->GetResponseCode();
108 base::TimeDelta retry_after;
110 std::string retry_after_string;
111 if (fetcher->GetResponseHeaders() &&
112 fetcher->GetResponseHeaders()->EnumerateHeader(nullptr,
113 "Retry-After",
114 &retry_after_string)) {
115 net::HttpUtil::ParseRetryAfterHeader(retry_after_string,
116 time_->Now(),
117 &retry_after);
121 VLOG(1) << "Upload finished with net error " << net_error
122 << ", response code " << http_response_code
123 << ", retry after " << retry_after;
125 UMA_HISTOGRAM_SPARSE_SLOWLY("DomainReliability.UploadResponseCode",
126 http_response_code);
127 UMA_HISTOGRAM_SPARSE_SLOWLY("DomainReliability.UploadNetError",
128 -net_error);
130 UploadResult result;
131 GetUploadResultFromResponseDetails(net_error,
132 http_response_code,
133 retry_after,
134 &result);
135 callback_it->second.Run(result);
137 delete callback_it->first;
138 upload_callbacks_.erase(callback_it);
141 private:
142 using DomainReliabilityUploader::UploadCallback;
143 typedef std::map<const net::URLFetcher*, UploadCallback> UploadCallbackMap;
145 MockableTime* time_;
146 scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_;
147 UploadCallbackMap upload_callbacks_;
148 bool discard_uploads_;
151 } // namespace
153 DomainReliabilityUploader::DomainReliabilityUploader() {}
154 DomainReliabilityUploader::~DomainReliabilityUploader() {}
156 // static
157 scoped_ptr<DomainReliabilityUploader> DomainReliabilityUploader::Create(
158 MockableTime* time,
159 const scoped_refptr<net::URLRequestContextGetter>&
160 url_request_context_getter) {
161 return scoped_ptr<DomainReliabilityUploader>(
162 new DomainReliabilityUploaderImpl(time, url_request_context_getter));
165 // static
166 bool DomainReliabilityUploader::URLRequestIsUpload(
167 const net::URLRequest& request) {
168 return request.GetUserData(UploadUserData::kUserDataKey) != nullptr;
171 } // namespace domain_reliability