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

Side by Side Diff: components/variations/variations_http_header_provider.cc

Issue 1530133005: Refactor VariationsHttpHeaderProvider. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Add missing include to srt_fetcher_win.cc. Created 5 years 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
1 // Copyright 2014 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/variations/net/variations_http_header_provider.h" 5 #include "components/variations/variations_http_header_provider.h"
6 6
7 #include <set> 7 #include <set>
8 #include <string> 8 #include <string>
9 #include <vector> 9 #include <vector>
10 10
11 #include "base/base64.h" 11 #include "base/base64.h"
12 #include "base/memory/singleton.h" 12 #include "base/memory/singleton.h"
13 #include "base/metrics/histogram_macros.h" 13 #include "base/metrics/histogram_macros.h"
14 #include "base/strings/string_number_conversions.h" 14 #include "base/strings/string_number_conversions.h"
15 #include "base/strings/string_split.h" 15 #include "base/strings/string_split.h"
16 #include "base/strings/string_util.h" 16 #include "base/strings/string_util.h"
17 #include "components/google/core/browser/google_util.h"
18 #include "components/variations/proto/client_variations.pb.h" 17 #include "components/variations/proto/client_variations.pb.h"
19 #include "net/base/registry_controlled_domains/registry_controlled_domain.h"
20 #include "net/http/http_request_headers.h"
21 #include "url/gurl.h"
22 18
23 namespace variations { 19 namespace variations {
24 20
25 namespace { 21 // static
26
27 const char* kSuffixesToSetHeadersFor[] = {
28 ".android.com",
29 ".doubleclick.com",
30 ".doubleclick.net",
31 ".ggpht.com",
32 ".googleadservices.com",
33 ".googleapis.com",
34 ".googlesyndication.com",
35 ".googleusercontent.com",
36 ".googlevideo.com",
37 ".gstatic.com",
38 ".ytimg.com",
39 };
40
41 const char kChromeUMAEnabled[] = "X-Chrome-UMA-Enabled";
42 const char kClientData[] = "X-Client-Data";
43
44 } // namespace
45
46 VariationsHttpHeaderProvider* VariationsHttpHeaderProvider::GetInstance() { 22 VariationsHttpHeaderProvider* VariationsHttpHeaderProvider::GetInstance() {
47 return base::Singleton<VariationsHttpHeaderProvider>::get(); 23 return base::Singleton<VariationsHttpHeaderProvider>::get();
48 } 24 }
49 25
50 void VariationsHttpHeaderProvider::AppendHeaders( 26 std::string VariationsHttpHeaderProvider::GetClientDataHeader() {
51 const GURL& url,
52 bool incognito,
53 bool uma_enabled,
54 net::HttpRequestHeaders* headers) {
55 // Note the criteria for attaching client experiment headers:
56 // 1. We only transmit to Google owned domains which can evaluate experiments.
57 // 1a. These include hosts which have a standard postfix such as:
58 // *.doubleclick.net or *.googlesyndication.com or
59 // exactly www.googleadservices.com or
60 // international TLD domains *.google.<TLD> or *.youtube.<TLD>.
61 // 2. Only transmit for non-Incognito profiles.
62 // 3. For the X-Chrome-UMA-Enabled bit, only set it if UMA is in fact enabled
63 // for this install of Chrome.
64 // 4. For the X-Client-Data header, only include non-empty variation IDs.
65 if (incognito || !ShouldAppendHeaders(url))
66 return;
67
68 if (uma_enabled)
69 headers->SetHeaderIfMissing(kChromeUMAEnabled, "1");
70
71 // Lazily initialize the header, if not already done, before attempting to 27 // Lazily initialize the header, if not already done, before attempting to
72 // transmit it. 28 // transmit it.
73 InitVariationIDsCacheIfNeeded(); 29 InitVariationIDsCacheIfNeeded();
74 30
75 std::string variation_ids_header_copy; 31 std::string variation_ids_header_copy;
76 { 32 {
77 base::AutoLock scoped_lock(lock_); 33 base::AutoLock scoped_lock(lock_);
78 variation_ids_header_copy = variation_ids_header_; 34 variation_ids_header_copy = variation_ids_header_;
79 } 35 }
80 36 return variation_ids_header_copy;
81 if (!variation_ids_header_copy.empty()) {
82 // Note that prior to M33 this header was named X-Chrome-Variations.
83 headers->SetHeaderIfMissing(kClientData, variation_ids_header_copy);
84 }
85 } 37 }
86 38
87 bool VariationsHttpHeaderProvider::SetDefaultVariationIds( 39 bool VariationsHttpHeaderProvider::SetDefaultVariationIds(
88 const std::string& variation_ids) { 40 const std::string& variation_ids) {
89 default_variation_ids_set_.clear(); 41 default_variation_ids_set_.clear();
90 default_trigger_id_set_.clear(); 42 default_trigger_id_set_.clear();
91 for (const base::StringPiece& entry : base::SplitStringPiece( 43 for (const base::StringPiece& entry : base::SplitStringPiece(
92 variation_ids, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL)) { 44 variation_ids, ",", base::TRIM_WHITESPACE, base::SPLIT_WANT_ALL)) {
93 if (entry.empty()) { 45 if (entry.empty()) {
94 default_variation_ids_set_.clear(); 46 default_variation_ids_set_.clear();
95 default_trigger_id_set_.clear(); 47 default_trigger_id_set_.clear();
96 return false; 48 return false;
97 } 49 }
98 bool trigger_id = 50 bool trigger_id =
99 base::StartsWith(entry, "t", base::CompareCase::SENSITIVE); 51 base::StartsWith(entry, "t", base::CompareCase::SENSITIVE);
100 // Remove the "t" prefix if it's there. 52 // Remove the "t" prefix if it's there.
101 base::StringPiece trimmed_entry = trigger_id ? entry.substr(1) : entry; 53 base::StringPiece trimmed_entry = trigger_id ? entry.substr(1) : entry;
102 54
103 int variation_id = 0; 55 int variation_id = 0;
104 if (!base::StringToInt(trimmed_entry, &variation_id)) { 56 if (!base::StringToInt(trimmed_entry, &variation_id)) {
105 default_variation_ids_set_.clear(); 57 default_variation_ids_set_.clear();
106 default_trigger_id_set_.clear(); 58 default_trigger_id_set_.clear();
107 return false; 59 return false;
108 } 60 }
109 if (trigger_id) 61 if (trigger_id)
110 default_trigger_id_set_.insert(variation_id); 62 default_trigger_id_set_.insert(variation_id);
111 else 63 else
112 default_variation_ids_set_.insert(variation_id); 64 default_variation_ids_set_.insert(variation_id);
113 } 65 }
114 return true; 66 return true;
115 } 67 }
116 68
117 std::set<std::string> VariationsHttpHeaderProvider::GetVariationHeaderNames()
118 const {
119 std::set<std::string> headers;
120 headers.insert(kChromeUMAEnabled);
121 headers.insert(kClientData);
122 return headers;
123 }
124
125 void VariationsHttpHeaderProvider::ResetForTesting() { 69 void VariationsHttpHeaderProvider::ResetForTesting() {
126 base::AutoLock scoped_lock(lock_); 70 base::AutoLock scoped_lock(lock_);
127 71
128 // Stop observing field trials so that it can be restarted when this is 72 // Stop observing field trials so that it can be restarted when this is
129 // re-inited. Note: This is a no-op if this is not currently observing. 73 // re-inited. Note: This is a no-op if this is not currently observing.
130 base::FieldTrialList::RemoveObserver(this); 74 base::FieldTrialList::RemoveObserver(this);
131 variation_ids_cache_initialized_ = false; 75 variation_ids_cache_initialized_ = false;
132 } 76 }
133 77
134 VariationsHttpHeaderProvider::VariationsHttpHeaderProvider() 78 VariationsHttpHeaderProvider::VariationsHttpHeaderProvider()
135 : variation_ids_cache_initialized_(false) { 79 : variation_ids_cache_initialized_(false) {}
136 }
137 80
138 VariationsHttpHeaderProvider::~VariationsHttpHeaderProvider() { 81 VariationsHttpHeaderProvider::~VariationsHttpHeaderProvider() {}
139 }
140 82
141 void VariationsHttpHeaderProvider::OnFieldTrialGroupFinalized( 83 void VariationsHttpHeaderProvider::OnFieldTrialGroupFinalized(
142 const std::string& trial_name, 84 const std::string& trial_name,
143 const std::string& group_name) { 85 const std::string& group_name) {
144 VariationID new_id = 86 VariationID new_id =
145 GetGoogleVariationID(GOOGLE_WEB_PROPERTIES, trial_name, group_name); 87 GetGoogleVariationID(GOOGLE_WEB_PROPERTIES, trial_name, group_name);
146 VariationID new_trigger_id = GetGoogleVariationID( 88 VariationID new_trigger_id = GetGoogleVariationID(
147 GOOGLE_WEB_PROPERTIES_TRIGGER, trial_name, group_name); 89 GOOGLE_WEB_PROPERTIES_TRIGGER, trial_name, group_name);
148 if (new_id == EMPTY_ID && new_trigger_id == EMPTY_ID) 90 if (new_id == EMPTY_ID && new_trigger_id == EMPTY_ID)
149 return; 91 return;
150 92
151 base::AutoLock scoped_lock(lock_); 93 base::AutoLock scoped_lock(lock_);
152 if (new_id != EMPTY_ID) 94 if (new_id != EMPTY_ID)
153 variation_ids_set_.insert(new_id); 95 variation_ids_set_.insert(new_id);
154 if (new_trigger_id != EMPTY_ID) 96 if (new_trigger_id != EMPTY_ID)
155 variation_trigger_ids_set_.insert(new_trigger_id); 97 variation_trigger_ids_set_.insert(new_trigger_id);
156 98
157 UpdateVariationIDsHeaderValue(); 99 UpdateVariationIDsHeaderValue();
158 } 100 }
159 101
160 void VariationsHttpHeaderProvider::OnSyntheticTrialsChanged( 102 void VariationsHttpHeaderProvider::OnSyntheticTrialsChanged(
161 const std::vector<metrics::SyntheticTrialGroup>& groups) { 103 const std::vector<SyntheticTrialGroup>& groups) {
162 base::AutoLock scoped_lock(lock_); 104 base::AutoLock scoped_lock(lock_);
163 105
164 synthetic_variation_ids_set_.clear(); 106 synthetic_variation_ids_set_.clear();
165 for (const metrics::SyntheticTrialGroup& group : groups) { 107 for (const SyntheticTrialGroup& group : groups) {
166 const VariationID id = 108 const VariationID id =
167 GetGoogleVariationIDFromHashes(GOOGLE_WEB_PROPERTIES, group.id); 109 GetGoogleVariationIDFromHashes(GOOGLE_WEB_PROPERTIES, group.id);
168 if (id != EMPTY_ID) 110 if (id != EMPTY_ID)
169 synthetic_variation_ids_set_.insert(id); 111 synthetic_variation_ids_set_.insert(id);
170 } 112 }
171 UpdateVariationIDsHeaderValue(); 113 UpdateVariationIDsHeaderValue();
172 } 114 }
173 115
174 void VariationsHttpHeaderProvider::InitVariationIDsCacheIfNeeded() { 116 void VariationsHttpHeaderProvider::InitVariationIDsCacheIfNeeded() {
175 base::AutoLock scoped_lock(lock_); 117 base::AutoLock scoped_lock(lock_);
176 if (variation_ids_cache_initialized_) 118 if (variation_ids_cache_initialized_)
177 return; 119 return;
178 120
179 // Register for additional cache updates. This is done first to avoid a race 121 // Register for additional cache updates. This is done first to avoid a race
180 // that could cause registered FieldTrials to be missed. 122 // that could cause registered FieldTrials to be missed.
181 DCHECK(base::MessageLoop::current()); 123 DCHECK(base::MessageLoop::current());
182 base::FieldTrialList::AddObserver(this); 124 base::FieldTrialList::AddObserver(this);
183 125
184 base::TimeTicks before_time = base::TimeTicks::Now(); 126 base::TimeTicks before_time = base::TimeTicks::Now();
185 127
186 base::FieldTrial::ActiveGroups initial_groups; 128 base::FieldTrial::ActiveGroups initial_groups;
187 base::FieldTrialList::GetActiveFieldTrialGroups(&initial_groups); 129 base::FieldTrialList::GetActiveFieldTrialGroups(&initial_groups);
188 for (base::FieldTrial::ActiveGroups::const_iterator it = 130 for (base::FieldTrial::ActiveGroups::const_iterator it =
189 initial_groups.begin(); 131 initial_groups.begin();
190 it != initial_groups.end(); ++it) { 132 it != initial_groups.end(); ++it) {
191 const VariationID id = 133 const VariationID id = GetGoogleVariationID(GOOGLE_WEB_PROPERTIES,
192 GetGoogleVariationID(GOOGLE_WEB_PROPERTIES, it->trial_name, 134 it->trial_name, it->group_name);
193 it->group_name);
194 if (id != EMPTY_ID) 135 if (id != EMPTY_ID)
195 variation_ids_set_.insert(id); 136 variation_ids_set_.insert(id);
196 137
197 const VariationID trigger_id = 138 const VariationID trigger_id = GetGoogleVariationID(
198 GetGoogleVariationID(GOOGLE_WEB_PROPERTIES_TRIGGER, it->trial_name, 139 GOOGLE_WEB_PROPERTIES_TRIGGER, it->trial_name, it->group_name);
199 it->group_name);
200 if (trigger_id != EMPTY_ID) 140 if (trigger_id != EMPTY_ID)
201 variation_trigger_ids_set_.insert(trigger_id); 141 variation_trigger_ids_set_.insert(trigger_id);
202 } 142 }
203 UpdateVariationIDsHeaderValue(); 143 UpdateVariationIDsHeaderValue();
204 144
205 UMA_HISTOGRAM_CUSTOM_COUNTS( 145 UMA_HISTOGRAM_CUSTOM_COUNTS(
206 "Variations.HeaderConstructionTime", 146 "Variations.HeaderConstructionTime",
207 (base::TimeTicks::Now() - before_time).InMicroseconds(), 147 (base::TimeTicks::Now() - before_time).InMicroseconds(), 0,
208 0, 148 base::TimeDelta::FromSeconds(1).InMicroseconds(), 50);
209 base::TimeDelta::FromSeconds(1).InMicroseconds(),
210 50);
211 149
212 variation_ids_cache_initialized_ = true; 150 variation_ids_cache_initialized_ = true;
213 } 151 }
214 152
215 void VariationsHttpHeaderProvider::UpdateVariationIDsHeaderValue() { 153 void VariationsHttpHeaderProvider::UpdateVariationIDsHeaderValue() {
216 lock_.AssertAcquired(); 154 lock_.AssertAcquired();
217 155
218 // The header value is a serialized protobuffer of Variation IDs which is 156 // The header value is a serialized protobuffer of Variation IDs which is
219 // base64 encoded before transmitting as a string. 157 // base64 encoded before transmitting as a string.
220 variation_ids_header_.clear(); 158 variation_ids_header_.clear();
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
258 196
259 std::string hashed; 197 std::string hashed;
260 base::Base64Encode(serialized, &hashed); 198 base::Base64Encode(serialized, &hashed);
261 // If successful, swap the header value with the new one. 199 // If successful, swap the header value with the new one.
262 // Note that the list of IDs and the header could be temporarily out of sync 200 // Note that the list of IDs and the header could be temporarily out of sync
263 // if IDs are added as the header is recreated. The receiving servers are OK 201 // if IDs are added as the header is recreated. The receiving servers are OK
264 // with such discrepancies. 202 // with such discrepancies.
265 variation_ids_header_ = hashed; 203 variation_ids_header_ = hashed;
266 } 204 }
267 205
268 // static
269 bool VariationsHttpHeaderProvider::ShouldAppendHeaders(const GURL& url) {
270 if (google_util::IsGoogleDomainUrl(url, google_util::ALLOW_SUBDOMAIN,
271 google_util::ALLOW_NON_STANDARD_PORTS)) {
272 return true;
273 }
274
275 if (!url.is_valid() || !url.SchemeIsHTTPOrHTTPS())
276 return false;
277
278 // Some domains don't have international TLD extensions, so testing for them
279 // is very straight forward.
280 const std::string host = url.host();
281 for (size_t i = 0; i < arraysize(kSuffixesToSetHeadersFor); ++i) {
282 if (base::EndsWith(host, kSuffixesToSetHeadersFor[i],
283 base::CompareCase::INSENSITIVE_ASCII))
284 return true;
285 }
286
287 return google_util::IsYoutubeDomainUrl(url, google_util::ALLOW_SUBDOMAIN,
288 google_util::ALLOW_NON_STANDARD_PORTS);
289 }
290
291 } // namespace variations 206 } // namespace variations
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698