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

Side by Side Diff: components/ntp_snippets/breaking_news/subscription_json_request.cc

Issue 2918513002: [NTP::Push] Add the classes for sending a breaking news subscription request (Closed)
Patch Set: bauerb@ comments. Created 3 years, 6 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 2017 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/ntp_snippets/breaking_news/subscription_json_request.h"
6
7 #include <algorithm>
8 #include <utility>
9 #include <vector>
fhorschig 2017/06/01 09:23:56 unused import
mamir 2017/06/01 14:52:31 Done.
10
11 #include "base/command_line.h"
fhorschig 2017/06/01 09:23:55 unused import
mamir 2017/06/01 14:52:31 Done.
12 #include "base/json/json_writer.h"
13 #include "base/memory/ptr_util.h"
14 #include "base/metrics/histogram_macros.h"
15 #include "base/metrics/sparse_histogram.h"
fhorschig 2017/06/01 09:23:56 Metrics includes unused
mamir 2017/06/01 14:52:31 Done.
16 #include "base/strings/stringprintf.h"
17 #include "base/time/clock.h"
fhorschig 2017/06/01 09:23:55 unused
mamir 2017/06/01 14:52:31 Acknowledged.
18 #include "base/values.h"
19 #include "components/data_use_measurement/core/data_use_user_data.h"
20 #include "components/ntp_snippets/category_info.h"
21 #include "components/ntp_snippets/features.h"
22 #include "components/ntp_snippets/user_classifier.h"
23 #include "components/signin/core/browser/profile_oauth2_token_service.h"
24 #include "components/signin/core/browser/signin_manager.h"
25 #include "components/signin/core/browser/signin_manager_base.h"
fhorschig 2017/06/01 09:23:56 unused: components/ntp_snippets/* components/signi
mamir 2017/06/01 14:52:31 Acknowledged.
26 #include "components/strings/grit/components_strings.h"
27 #include "components/variations/net/variations_http_headers.h"
28 #include "components/variations/variations_associated_data.h"
fhorschig 2017/06/01 09:23:55 unused?
mamir 2017/06/01 14:52:31 Acknowledged.
29 #include "net/base/load_flags.h"
30 #include "net/http/http_response_headers.h"
fhorschig 2017/06/01 09:23:56 unused?
mamir 2017/06/01 14:52:31 Acknowledged.
31 #include "net/http/http_status_code.h"
32 #include "net/traffic_annotation/network_traffic_annotation.h"
33 #include "net/url_request/url_fetcher.h"
34 #include "net/url_request/url_request_context_getter.h"
35 #include "third_party/icu/source/common/unicode/uloc.h"
36 #include "third_party/icu/source/common/unicode/utypes.h"
37 #include "ui/base/l10n/l10n_util.h"
fhorschig 2017/06/01 09:23:55 The last three imports seem unused as well ... ple
mamir 2017/06/01 14:52:31 Acknowledged.
38
39 using net::URLFetcher;
fhorschig 2017/06/01 09:23:56 either remove this or remove the net:: before ever
mamir 2017/06/01 14:52:30 Done.
40 using net::URLRequestContextGetter;
fhorschig 2017/06/01 09:23:55 either remove this or remove the net:: before ever
mamir 2017/06/01 14:52:31 Done.
41 using net::HttpRequestHeaders;
fhorschig 2017/06/01 09:23:55 either remove this or remove the net:: before ever
mamir 2017/06/01 14:52:31 Done.
42 using net::URLRequestStatus;
43
44 namespace ntp_snippets {
45
46 namespace internal {
47
48 SubscriptionJsonRequest::SubscriptionJsonRequest() : weak_ptr_factory_(this) {}
49
50 SubscriptionJsonRequest::~SubscriptionJsonRequest() {
51 if (!request_completed_callback_.is_null()) {
52 std::move(request_completed_callback_)
53 .Run(ntp_snippets::Status(ntp_snippets::StatusCode::TEMPORARY_ERROR,
54 "cancelled"));
55 }
56 }
57
58 void SubscriptionJsonRequest::Start(CompletedCallback callback) {
fhorschig 2017/06/01 09:23:55 What happens if you call this method twice? If I d
mamir 2017/06/01 14:52:31 Implemented option 2 after our offline discussion
59 request_completed_callback_ = std::move(callback);
60 url_fetcher_->Start();
61 }
62
63 ////////////////////////////////////////////////////////////////////////////////
64 // URLFetcherDelegate overrides
65 void SubscriptionJsonRequest::OnURLFetchComplete(
66 const net::URLFetcher* source) {
67 DCHECK_EQ(url_fetcher_.get(), source);
68 const URLRequestStatus& status = url_fetcher_->GetStatus();
69 int response = url_fetcher_->GetResponseCode();
70
71 if (!status.is_success()) {
72 std::move(request_completed_callback_)
73 .Run(ntp_snippets::Status(ntp_snippets::StatusCode::TEMPORARY_ERROR,
74 base::StringPrintf(" %d", status.error())));
fhorschig 2017/06/01 09:23:56 This produces really hard to debug Status states.
mamir 2017/06/01 14:52:31 Done.
75 } else if (response != net::HTTP_OK) {
76 std::move(request_completed_callback_)
77 .Run(ntp_snippets::Status(ntp_snippets::StatusCode::TEMPORARY_ERROR,
fhorschig 2017/06/01 09:23:56 nit: Is TEMPORARY_ERROR what we want to return? I
mamir 2017/06/01 14:52:31 Done.
78 base::StringPrintf(" %d", response)));
79 } else {
80 // request succeeded.
fhorschig 2017/06/01 09:23:56 nit: This obvious comment might be obvious.
mamir 2017/06/01 14:52:31 Done.
81 std::move(request_completed_callback_)
82 .Run(ntp_snippets::Status(ntp_snippets::StatusCode::SUCCESS, ""));
Bernhard Bauer 2017/06/01 09:31:23 Nit: Use an empty std::string() constructor instea
mamir 2017/06/01 14:52:31 Done.
83 }
84 }
85
86 SubscriptionJsonRequest::Builder::Builder() {}
87 SubscriptionJsonRequest::Builder::Builder(SubscriptionJsonRequest::Builder&&) =
88 default;
89 SubscriptionJsonRequest::Builder::~Builder() = default;
90
91 std::unique_ptr<SubscriptionJsonRequest>
92 SubscriptionJsonRequest::Builder::Build() const {
93 DCHECK(!url_.is_empty());
94 DCHECK(url_request_context_getter_);
95 auto request = base::WrapUnique(new SubscriptionJsonRequest());
96
97 std::string body = BuildBody();
98 std::string headers = BuildHeaders();
99 request->url_fetcher_ = BuildURLFetcher(request.get(), headers, body);
100
101 // Log the request for debugging network issues.
102 VLOG(1) << "Sending a subscription request to " << url_ << ":\n"
103 << headers << "\n"
104 << body;
105
106 return request;
107 }
108
109 SubscriptionJsonRequest::Builder& SubscriptionJsonRequest::Builder::SetToken(
110 const std::string& token) {
111 token_ = token;
112 return *this;
113 }
114
115 SubscriptionJsonRequest::Builder& SubscriptionJsonRequest::Builder::SetUrl(
116 const GURL& url) {
117 url_ = url;
118 return *this;
119 }
120
121 SubscriptionJsonRequest::Builder&
122 SubscriptionJsonRequest::Builder::SetUrlRequestContextGetter(
123 const scoped_refptr<net::URLRequestContextGetter>& context_getter) {
124 url_request_context_getter_ = context_getter;
125 return *this;
126 }
127
128 std::string SubscriptionJsonRequest::Builder::BuildHeaders() const {
129 net::HttpRequestHeaders headers;
130 headers.SetHeader("Content-Type", "application/json; charset=UTF-8");
131
132 // Add X-Client-Data header with experiment IDs from field trials.
133 // Note: It's OK to pass |is_signed_in| false if it's unknown, as it does
134 // not affect transmission of experiments coming from the variations server.
135 variations::AppendVariationHeaders(url_,
136 false, // incognito
137 false, // uma_enabled
138 false, // is_signed_in
139 &headers);
140 return headers.ToString();
141 }
142
143 std::string SubscriptionJsonRequest::Builder::BuildBody() const {
144 base::DictionaryValue request;
145 request.SetString("token", token_);
fhorschig 2017/06/01 09:23:55 You access a private member (namely url_fetcher_)
mamir 2017/06/01 14:52:31 Ignore as per our offline discussion.
146
147 std::string request_json;
148 bool success = base::JSONWriter::WriteWithOptions(
149 request, base::JSONWriter::OPTIONS_PRETTY_PRINT, &request_json);
fhorschig 2017/06/01 09:23:55 Can we drop the option? (in tests, you compare by
mamir 2017/06/01 14:52:31 Done.
150 DCHECK(success);
151 return request_json;
152 }
153
154 std::unique_ptr<net::URLFetcher>
155 SubscriptionJsonRequest::Builder::BuildURLFetcher(
156 net::URLFetcherDelegate* delegate,
157 const std::string& headers,
158 const std::string& body) const {
159 net::NetworkTrafficAnnotationTag traffic_annotation =
160 net::DefineNetworkTrafficAnnotation("gcm_subscription", R"(
161 semantics {
162 sender: "Subscribe for breaking news delivered via GCM push messages"
163 description:
164 "Chromium can receive breaking news via GCM push messages. "
165 "This request suscribes the client to receiving them."
166 trigger:
167 "Subscription takes place only once per profile lifetime. "
168 data:
169 "The subscription token that identifies this Chromium profile."
170 destination: GOOGLE_OWNED_SERVICE
171 }
172 policy {
173 cookies_allowed: false
174 setting:
175 "This feature cannot be disabled by settings now"
176 chrome_policy {
177 NTPContentSuggestionsEnabled {
178 policy_options {mode: MANDATORY}
179 NTPContentSuggestionsEnabled: false
180 }
181 }
182 })");
183 std::unique_ptr<net::URLFetcher> url_fetcher = net::URLFetcher::Create(
184 url_, net::URLFetcher::POST, delegate, traffic_annotation);
185 url_fetcher->SetRequestContext(url_request_context_getter_.get());
186 url_fetcher->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES |
187 net::LOAD_DO_NOT_SAVE_COOKIES);
188 data_use_measurement::DataUseUserData::AttachToFetcher(
189 url_fetcher.get(),
190 data_use_measurement::DataUseUserData::NTP_SNIPPETS_SUGGESTIONS);
191
192 url_fetcher->SetExtraRequestHeaders(headers);
193 url_fetcher->SetUploadData("application/json", body);
194
195 // Fetchers are sometimes cancelled because a network change was detected.
196 url_fetcher->SetAutomaticallyRetryOnNetworkChanges(3);
197 return url_fetcher;
198 }
199
200 } // namespace internal
201
202 } // namespace ntp_snippets
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698