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"
8 #include "base/memory/scoped_vector.h"
9 #include "base/metrics/sparse_histogram.h"
10 #include "base/stl_util.h"
11 #include "base/supports_user_data.h"
12 #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"
17 namespace domain_reliability
{
21 const char* kJsonMimeType
= "application/json; charset=utf-8";
23 class UploadUserData
: public base::SupportsUserData::Data
{
25 static net::URLFetcher::CreateDataCallback
CreateCreateDataCallback() {
26 return base::Bind(&UploadUserData::CreateUploadUserData
);
29 static const void* kUserDataKey
;
32 static base::SupportsUserData::Data
* CreateUploadUserData() {
33 return new UploadUserData();
37 const void* UploadUserData::kUserDataKey
=
38 static_cast<const void*>(&UploadUserData::kUserDataKey
);
40 class DomainReliabilityUploaderImpl
41 : public DomainReliabilityUploader
, net::URLFetcherDelegate
{
43 DomainReliabilityUploaderImpl(const scoped_refptr
<
44 net::URLRequestContextGetter
>& url_request_context_getter
)
45 : url_request_context_getter_(url_request_context_getter
) {}
47 virtual ~DomainReliabilityUploaderImpl() {
48 // Delete any in-flight URLFetchers.
49 STLDeleteContainerPairFirstPointers(
50 upload_callbacks_
.begin(), upload_callbacks_
.end());
53 // DomainReliabilityUploader implementation:
54 virtual void UploadReport(
55 const std::string
& report_json
,
56 const GURL
& upload_url
,
57 const DomainReliabilityUploader::UploadCallback
& callback
) OVERRIDE
{
58 VLOG(1) << "Uploading report to " << upload_url
;
59 VLOG(2) << "Report JSON: " << report_json
;
61 net::URLFetcher
* fetcher
=
62 net::URLFetcher::Create(0, upload_url
, net::URLFetcher::POST
, this);
63 fetcher
->SetRequestContext(url_request_context_getter_
);
64 fetcher
->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES
|
65 net::LOAD_DO_NOT_SAVE_COOKIES
);
66 fetcher
->SetUploadData(kJsonMimeType
, report_json
);
67 fetcher
->SetAutomaticallyRetryOn5xx(false);
68 fetcher
->SetURLRequestUserData(
69 UploadUserData::kUserDataKey
,
70 UploadUserData::CreateCreateDataCallback());
73 upload_callbacks_
[fetcher
] = callback
;
76 // net::URLFetcherDelegate implementation:
77 virtual void OnURLFetchComplete(
78 const net::URLFetcher
* fetcher
) OVERRIDE
{
81 UploadCallbackMap::iterator callback_it
= upload_callbacks_
.find(fetcher
);
82 DCHECK(callback_it
!= upload_callbacks_
.end());
84 VLOG(1) << "Upload finished with " << fetcher
->GetResponseCode();
86 UMA_HISTOGRAM_SPARSE_SLOWLY("DomainReliability.UploadResponseCode",
87 fetcher
->GetResponseCode());
89 bool success
= fetcher
->GetResponseCode() == 200;
90 callback_it
->second
.Run(success
);
92 delete callback_it
->first
;
93 upload_callbacks_
.erase(callback_it
);
97 using DomainReliabilityUploader::UploadCallback
;
98 typedef std::map
<const net::URLFetcher
*, UploadCallback
> UploadCallbackMap
;
100 scoped_refptr
<net::URLRequestContextGetter
> url_request_context_getter_
;
101 UploadCallbackMap upload_callbacks_
;
106 DomainReliabilityUploader::DomainReliabilityUploader() {}
107 DomainReliabilityUploader::~DomainReliabilityUploader() {}
110 scoped_ptr
<DomainReliabilityUploader
> DomainReliabilityUploader::Create(
111 const scoped_refptr
<net::URLRequestContextGetter
>&
112 url_request_context_getter
) {
113 return scoped_ptr
<DomainReliabilityUploader
>(
114 new DomainReliabilityUploaderImpl(url_request_context_getter
));
118 bool DomainReliabilityUploader::URLRequestIsUpload(
119 const net::URLRequest
& request
) {
120 return request
.GetUserData(UploadUserData::kUserDataKey
) != NULL
;
123 } // namespace domain_reliability