Index: components/reporting/core/browser/reporting_uploader.cc |
diff --git a/components/reporting/core/browser/reporting_uploader.cc b/components/reporting/core/browser/reporting_uploader.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..1ffcf9c6acb8af3aec70fdc41dd75d37b12c7bc1 |
--- /dev/null |
+++ b/components/reporting/core/browser/reporting_uploader.cc |
@@ -0,0 +1,80 @@ |
+// Copyright 2016 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+#include "components/reporting/core/browser/reporting_uploader.h" |
+ |
+#include "base/memory/ptr_util.h" |
+ |
+namespace { |
+const char kUploadContentType[] = "application/report"; |
+} // namespace |
+ |
+namespace reporting { |
+ |
+namespace { |
+ |
+ReportingUploader::Outcome ResponseCodeToOutcome(int response_code) { |
+ if (response_code >= 200 && response_code <= 299) |
+ return ReportingUploader::SUCCESS; |
+ if (response_code == 410) |
+ return ReportingUploader::REMOVE_ENDPOINT; |
+ return ReportingUploader::FAILURE; |
+} |
+ |
+class ReportingUploaderImpl : public ReportingUploader, |
+ net::URLFetcherDelegate { |
+ public: |
+ ReportingUploaderImpl(scoped_refptr<net::URLRequestContextGetter> context) {} |
+ ~ReportingUploaderImpl() override {} |
+ |
+ // Section 4.4. |
+ void AttemptDelivery(const GURL& url, |
+ const std::string& json, |
+ const Callback& callback) override { |
+ std::unique_ptr<net::URLFetcher> fetcher( |
+ net::URLFetcher::Create(url, net::URLFetcher::POST, this)); |
+ fetcher->SetRequestContext(context_.get()); |
+ fetcher->SetAutomaticallyRetryOn5xx(false); |
+ fetcher->SetUploadData(kUploadContentType, json); |
+ // This inherently sets mode = "no-cors", but that doesn't matter, because |
+ // the origins that are included in the upload don't actually get to see |
+ // the response. |
+ // |
+ // This inherently skips Service Worker, too. |
+ fetcher->Start(); |
+ |
+ // Have to grab this as a reference to ensure fetcher.get() happens before |
+ // std::move(fetcher). |
+ std::unique_ptr<Upload>& upload = uploads_[fetcher.get()]; |
+ upload = base::MakeUnique<Upload>(std::move(fetcher), callback); |
+ } |
+ |
+ // net::URLFetcherDelegate implementation: |
+ void OnURLFetchComplete(const net::URLFetcher* fetcher) override { |
+ UploadMap::iterator it = uploads_.find(fetcher); |
+ std::unique_ptr<Upload> upload = std::move(it->second); |
+ uploads_.erase(it); |
+ |
+ upload->second.Run(ResponseCodeToOutcome(fetcher->GetResponseCode())); |
+ // Deletes fetcher (upload->first) when upload goes out of scope and is |
+ // deleted. |
+ } |
+ |
+ private: |
+ using Upload = std::pair<std::unique_ptr<net::URLFetcher>, Callback>; |
+ using UploadMap = std::map<const net::URLFetcher*, std::unique_ptr<Upload>>; |
+ |
+ scoped_refptr<net::URLRequestContextGetter> context_; |
+ UploadMap uploads_; |
+}; |
+ |
+} // namespace |
+ |
+// static |
+std::unique_ptr<ReportingUploader> ReportingUploader::Create( |
+ scoped_refptr<net::URLRequestContextGetter> context) { |
+ return base::MakeUnique<ReportingUploaderImpl>(context); |
+} |
+ |
+} // namespace reporting |