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

Side by Side 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 unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2016 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 "net/reporting/reporting_uploader.h"
6
7 #include "base/callback_helpers.h"
8 #include "base/memory/ptr_util.h"
9 #include "base/metrics/histogram_macros.h"
10 #include "net/base/elements_upload_data_stream.h"
11 #include "net/base/load_flags.h"
12 #include "net/base/upload_bytes_element_reader.h"
13 #include "net/http/http_response_headers.h"
14 #include "net/url_request/redirect_info.h"
15 #include "net/url_request/url_request_context.h"
16
17 namespace net {
18
19 namespace {
20
21 ReportingUploader::Outcome ResponseCodeToOutcome(int response_code) {
22 if (response_code >= 200 && response_code <= 299)
23 return ReportingUploader::SUCCESS;
24 if (response_code == 410)
25 return ReportingUploader::REMOVE_ENDPOINT;
26 return ReportingUploader::FAILURE;
27 }
28
29 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
30 public:
31 ReportingUploaderImpl(const URLRequestContext* context) : context_(context) {
32 DCHECK(context_);
33 }
34
35 ~ReportingUploaderImpl() override {
36 for (auto& it : uploads_) {
37 base::ResetAndReturn(&it.second->second).Run(FAILURE);
38 it.second->first->Cancel();
39 }
40 uploads_.clear();
41 }
42
43 void StartUpload(const GURL& url,
44 const std::string& json,
45 const Callback& callback) override {
46 std::unique_ptr<URLRequest> request =
47 context_->CreateRequest(url, IDLE, this);
48
49 request->set_method("POST");
50
51 request->SetLoadFlags(LOAD_DISABLE_CACHE | LOAD_DO_NOT_SAVE_COOKIES |
52 LOAD_DO_NOT_SEND_COOKIES);
53
54 request->SetExtraRequestHeaderByName(HttpRequestHeaders::kContentType,
55 kUploadContentType, true);
56
57 std::vector<char> json_data(json.begin(), json.end());
58 std::unique_ptr<UploadElementReader> reader(
59 new UploadOwnedBytesElementReader(&json_data));
60 request->set_upload(
61 ElementsUploadDataStream::CreateWithReader(std::move(reader), 0));
62
63 // This inherently sets mode = "no-cors", but that doesn't matter, because
64 // the origins that are included in the upload don't actually get to see
65 // the response.
66 //
67 // 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
68 request->Start();
69
70 // Have to grab the unique_ptr* first to ensure request.get() happens
71 // before std::move(request).
72 std::unique_ptr<Upload>* upload = &uploads_[request.get()];
73 *upload = base::MakeUnique<Upload>(std::move(request), callback);
74 }
75
76 // 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.
77 void OnReceivedRedirect(URLRequest* request,
78 const RedirectInfo& redirect_info,
79 bool* defer_redirect) override {
80 if (!redirect_info.new_url.SchemeIsCryptographic()) {
81 request->Cancel();
82 return;
83 }
84 }
85
86 void OnAuthRequired(URLRequest* request,
87 AuthChallengeInfo* auth_info) override {
88 request->Cancel();
89 }
90
91 void OnCertificateRequested(URLRequest* request,
92 SSLCertRequestInfo* cert_request_info) override {
93 request->Cancel();
94 }
shivanisha 2017/03/28 19:57:14 Implementation of URLRequest::Delegate::OnSSLCerti
Julia Tuttle 2017/03/28 20:36:34 Done.
95
96 void OnResponseStarted(URLRequest* request, int net_error) override {
97 // Grab Upload from map, and hold on to it in a local unique_ptr so it's
98 // removed at the end of the method.
99 UploadMap::iterator it = uploads_.find(request);
100 DCHECK(it != uploads_.end());
101 std::unique_ptr<Upload> upload = std::move(it->second);
102 uploads_.erase(it);
103
104 // request->GetResponseCode() should work, but doesn't in the cases above
105 // where the request was canceled, so get the response code by hand.
106 // TODO(juliatuttle): Check if mmenke fixed this yet.
107 HttpResponseHeaders* headers = request->response_headers();
108 int response_code = headers ? headers->response_code() : 0;
109 Outcome outcome = ResponseCodeToOutcome(response_code);
110
111 upload->second.Run(outcome);
112
113 request->Cancel();
114 }
115
116 void OnReadCompleted(URLRequest* request, int bytes_read) override {
117 // Reporting doesn't need anything in the body of the response, so it
118 // doesn't read it, so it should never get OnReadCompleted calls.
119 NOTREACHED();
120 }
121
122 private:
123 using Upload = std::pair<std::unique_ptr<URLRequest>, Callback>;
124 using UploadMap = std::map<const URLRequest*, std::unique_ptr<Upload>>;
125
126 const URLRequestContext* context_;
127 UploadMap uploads_;
128 };
129
130 } // namespace
131
132 // static
133 const char ReportingUploader::kUploadContentType[] = "application/report";
134
135 ReportingUploader::~ReportingUploader() {}
136
137 // static
138 std::unique_ptr<ReportingUploader> ReportingUploader::Create(
139 const URLRequestContext* context) {
140 return base::MakeUnique<ReportingUploaderImpl>(context);
141 }
142
143 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698