Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(217)

Unified Diff: net/reporting/reporting_uploader.cc

Issue 2723563002: Reporting: Implement uploader. (Closed)
Patch Set: rebase Created 3 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: net/reporting/reporting_uploader.cc
diff --git a/net/reporting/reporting_uploader.cc b/net/reporting/reporting_uploader.cc
new file mode 100644
index 0000000000000000000000000000000000000000..adcc9112fc7b9c444d66150892675f4e3b07d476
--- /dev/null
+++ b/net/reporting/reporting_uploader.cc
@@ -0,0 +1,143 @@
+// 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 "net/reporting/reporting_uploader.h"
+
+#include "base/callback_helpers.h"
+#include "base/memory/ptr_util.h"
+#include "base/metrics/histogram_macros.h"
+#include "net/base/elements_upload_data_stream.h"
+#include "net/base/load_flags.h"
+#include "net/base/upload_bytes_element_reader.h"
+#include "net/http/http_response_headers.h"
+#include "net/url_request/redirect_info.h"
+#include "net/url_request/url_request_context.h"
+
+namespace net {
+
+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, URLRequest::Delegate {
shivanisha 2017/03/28 19:57:14 Why is this class definition inside the anonymous
Julia Tuttle 2017/03/28 20:36:34 It could, but I consider it an implementation deta
+ public:
+ ReportingUploaderImpl(const URLRequestContext* context) : context_(context) {
+ DCHECK(context_);
+ }
+
+ ~ReportingUploaderImpl() override {
+ for (auto& it : uploads_) {
+ base::ResetAndReturn(&it.second->second).Run(FAILURE);
+ it.second->first->Cancel();
+ }
+ uploads_.clear();
+ }
+
+ void StartUpload(const GURL& url,
+ const std::string& json,
+ const Callback& callback) override {
+ std::unique_ptr<URLRequest> request =
+ context_->CreateRequest(url, IDLE, this);
+
+ request->set_method("POST");
+
+ request->SetLoadFlags(LOAD_DISABLE_CACHE | LOAD_DO_NOT_SAVE_COOKIES |
+ LOAD_DO_NOT_SEND_COOKIES);
+
+ request->SetExtraRequestHeaderByName(HttpRequestHeaders::kContentType,
+ kUploadContentType, true);
+
+ std::vector<char> json_data(json.begin(), json.end());
+ std::unique_ptr<UploadElementReader> reader(
+ new UploadOwnedBytesElementReader(&json_data));
+ request->set_upload(
+ ElementsUploadDataStream::CreateWithReader(std::move(reader), 0));
+
+ // 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.
shivanisha 2017/03/28 19:57:14 This question is for my own understanding: what is
Julia Tuttle 2017/03/28 20:36:34 The Reporting spec requires report delivery reques
+ request->Start();
+
+ // Have to grab the unique_ptr* first to ensure request.get() happens
+ // before std::move(request).
+ std::unique_ptr<Upload>* upload = &uploads_[request.get()];
+ *upload = base::MakeUnique<Upload>(std::move(request), callback);
+ }
+
+ // URLRequest::Delegate implementation:
shivanisha 2017/03/28 19:57:14 new line after this comment as it applies to all t
Julia Tuttle 2017/03/28 20:36:34 Done.
+ void OnReceivedRedirect(URLRequest* request,
+ const RedirectInfo& redirect_info,
+ bool* defer_redirect) override {
+ if (!redirect_info.new_url.SchemeIsCryptographic()) {
+ request->Cancel();
+ return;
+ }
+ }
+
+ void OnAuthRequired(URLRequest* request,
+ AuthChallengeInfo* auth_info) override {
+ request->Cancel();
+ }
+
+ void OnCertificateRequested(URLRequest* request,
+ SSLCertRequestInfo* cert_request_info) override {
+ request->Cancel();
+ }
shivanisha 2017/03/28 19:57:14 Implementation of URLRequest::Delegate::OnSSLCerti
Julia Tuttle 2017/03/28 20:36:34 Done.
+
+ void OnResponseStarted(URLRequest* request, int net_error) override {
+ // Grab Upload from map, and hold on to it in a local unique_ptr so it's
+ // removed at the end of the method.
+ UploadMap::iterator it = uploads_.find(request);
+ DCHECK(it != uploads_.end());
+ std::unique_ptr<Upload> upload = std::move(it->second);
+ uploads_.erase(it);
+
+ // request->GetResponseCode() should work, but doesn't in the cases above
+ // where the request was canceled, so get the response code by hand.
+ // TODO(juliatuttle): Check if mmenke fixed this yet.
+ HttpResponseHeaders* headers = request->response_headers();
+ int response_code = headers ? headers->response_code() : 0;
+ Outcome outcome = ResponseCodeToOutcome(response_code);
+
+ upload->second.Run(outcome);
+
+ request->Cancel();
+ }
+
+ void OnReadCompleted(URLRequest* request, int bytes_read) override {
+ // Reporting doesn't need anything in the body of the response, so it
+ // doesn't read it, so it should never get OnReadCompleted calls.
+ NOTREACHED();
+ }
+
+ private:
+ using Upload = std::pair<std::unique_ptr<URLRequest>, Callback>;
+ using UploadMap = std::map<const URLRequest*, std::unique_ptr<Upload>>;
+
+ const URLRequestContext* context_;
+ UploadMap uploads_;
+};
+
+} // namespace
+
+// static
+const char ReportingUploader::kUploadContentType[] = "application/report";
+
+ReportingUploader::~ReportingUploader() {}
+
+// static
+std::unique_ptr<ReportingUploader> ReportingUploader::Create(
+ const URLRequestContext* context) {
+ return base::MakeUnique<ReportingUploaderImpl>(context);
+}
+
+} // namespace net

Powered by Google App Engine
This is Rietveld 408576698