blob: 7112b5f016ee8440970a19b42e66171359bb58d6 [file] [log] [blame]
[email protected]bda8e362014-03-24 18:21:031// 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"
[email protected]d1acfe02014-04-24 17:15:298#include "base/memory/scoped_vector.h"
[email protected]d9df3b82014-04-08 23:44:009#include "base/metrics/sparse_histogram.h"
[email protected]bda8e362014-03-24 18:21:0310#include "base/stl_util.h"
[email protected]d1acfe02014-04-24 17:15:2911#include "base/supports_user_data.h"
[email protected]bda8e362014-03-24 18:21:0312#include "net/base/load_flags.h"
13#include "net/url_request/url_fetcher.h"
14#include "net/url_request/url_fetcher_delegate.h"
15#include "net/url_request/url_request_context_getter.h"
16
17namespace domain_reliability {
18
19namespace {
20
[email protected]d1acfe02014-04-24 17:15:2921class UploadUserData : public base::SupportsUserData::Data {
22 public:
23 static net::URLFetcher::CreateDataCallback CreateCreateDataCallback() {
24 return base::Bind(&UploadUserData::CreateUploadUserData);
25 }
26
27 static const void* kUserDataKey;
28
29 private:
30 static base::SupportsUserData::Data* CreateUploadUserData() {
31 return new UploadUserData();
32 }
33};
34
35const void* UploadUserData::kUserDataKey =
36 static_cast<const void*>(&UploadUserData::kUserDataKey);
37
[email protected]bda8e362014-03-24 18:21:0338class DomainReliabilityUploaderImpl
39 : public DomainReliabilityUploader, net::URLFetcherDelegate {
40 public:
41 DomainReliabilityUploaderImpl(
42 scoped_refptr<net::URLRequestContextGetter> url_request_context_getter)
43 : url_request_context_getter_(url_request_context_getter) {}
44
45 virtual ~DomainReliabilityUploaderImpl() {
46 // Delete any in-flight URLFetchers.
47 STLDeleteContainerPairFirstPointers(
48 upload_callbacks_.begin(), upload_callbacks_.end());
49 }
50
51 // DomainReliabilityUploader implementation:
52 virtual void UploadReport(
53 const std::string& report_json,
54 const GURL& upload_url,
55 const DomainReliabilityUploader::UploadCallback& callback) OVERRIDE {
56 VLOG(1) << "Uploading report to " << upload_url;
57 VLOG(2) << "Report JSON: " << report_json;
58
59 net::URLFetcher* fetcher =
60 net::URLFetcher::Create(0, upload_url, net::URLFetcher::POST, this);
61 fetcher->SetRequestContext(url_request_context_getter_);
62 fetcher->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES |
63 net::LOAD_DO_NOT_SAVE_COOKIES);
64 fetcher->SetUploadData("text/json", report_json);
65 fetcher->SetAutomaticallyRetryOn5xx(false);
[email protected]d1acfe02014-04-24 17:15:2966 fetcher->SetURLRequestUserData(
67 UploadUserData::kUserDataKey,
68 UploadUserData::CreateCreateDataCallback());
[email protected]bda8e362014-03-24 18:21:0369 fetcher->Start();
70
71 upload_callbacks_[fetcher] = callback;
72 }
73
74 // net::URLFetcherDelegate implementation:
75 virtual void OnURLFetchComplete(
76 const net::URLFetcher* fetcher) OVERRIDE {
77 DCHECK(fetcher);
78
79 UploadCallbackMap::iterator callback_it = upload_callbacks_.find(fetcher);
80 DCHECK(callback_it != upload_callbacks_.end());
81
82 VLOG(1) << "Upload finished with " << fetcher->GetResponseCode();
83
[email protected]d9df3b82014-04-08 23:44:0084 UMA_HISTOGRAM_SPARSE_SLOWLY("DomainReliability.UploadResponseCode",
85 fetcher->GetResponseCode());
86
[email protected]bda8e362014-03-24 18:21:0387 bool success = fetcher->GetResponseCode() == 200;
88 callback_it->second.Run(success);
89
90 delete callback_it->first;
91 upload_callbacks_.erase(callback_it);
92 }
93
94 private:
95 using DomainReliabilityUploader::UploadCallback;
96 typedef std::map<const net::URLFetcher*, UploadCallback> UploadCallbackMap;
97
98 scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_;
99 UploadCallbackMap upload_callbacks_;
100};
101
102} // namespace
103
104DomainReliabilityUploader::DomainReliabilityUploader() {}
105
106DomainReliabilityUploader::~DomainReliabilityUploader() {}
107
108// static
109scoped_ptr<DomainReliabilityUploader> DomainReliabilityUploader::Create(
110 scoped_refptr<net::URLRequestContextGetter> url_request_context_getter) {
111 return scoped_ptr<DomainReliabilityUploader>(
112 new DomainReliabilityUploaderImpl(url_request_context_getter));
113}
114
[email protected]d1acfe02014-04-24 17:15:29115// static
116bool DomainReliabilityUploader::URLRequestIsUpload(
117 const net::URLRequest& request) {
118 return request.GetUserData(UploadUserData::kUserDataKey) != NULL;
119}
120
[email protected]bda8e362014-03-24 18:21:03121} // namespace domain_reliability