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

Side by Side Diff: net/http/http_server_properties_impl.cc

Issue 665083009: ABANDONED Handle multiple AlternateProtocols for each HostPortPair. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Another Cronet occurrence. Created 5 years, 11 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
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2012 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 "net/http/http_server_properties_impl.h" 5 #include "net/http/http_server_properties_impl.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/memory/scoped_ptr.h" 9 #include "base/memory/scoped_ptr.h"
10 #include "base/message_loop/message_loop.h" 10 #include "base/message_loop/message_loop.h"
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
43 return; 43 return;
44 // Add the entries from persisted data. 44 // Add the entries from persisted data.
45 for (std::vector<std::string>::reverse_iterator it = spdy_servers->rbegin(); 45 for (std::vector<std::string>::reverse_iterator it = spdy_servers->rbegin();
46 it != spdy_servers->rend(); ++it) { 46 it != spdy_servers->rend(); ++it) {
47 spdy_servers_map_.Put(*it, support_spdy); 47 spdy_servers_map_.Put(*it, support_spdy);
48 } 48 }
49 } 49 }
50 50
51 void HttpServerPropertiesImpl::InitializeAlternateProtocolServers( 51 void HttpServerPropertiesImpl::InitializeAlternateProtocolServers(
52 AlternateProtocolMap* alternate_protocol_map) { 52 AlternateProtocolMap* alternate_protocol_map) {
53 // Keep all the broken ones since those don't get persisted. 53 for (AlternateProtocolMap::iterator alternate_protocols =
54 for (AlternateProtocolMap::iterator it = alternate_protocol_map_.begin(); 54 alternate_protocol_map_.begin();
55 it != alternate_protocol_map_.end();) { 55 alternate_protocols != alternate_protocol_map_.end();) {
56 AlternateProtocolMap::iterator old_it = it; 56 // Keep all the broken ones since those don't get persisted.
57 ++it; 57 for (AlternateProtocols::iterator it = alternate_protocols->second.begin();
58 if (!old_it->second.is_broken) { 58 it != alternate_protocols->second.end();) {
59 alternate_protocol_map_.Erase(old_it); 59 if (!it->is_broken) {
60 it = alternate_protocols->second.erase(it);
61 } else {
62 ++it;
63 }
64 }
65 if (alternate_protocols->second.size() == 0) {
66 alternate_protocols = alternate_protocol_map_.Erase(alternate_protocols);
67 } else {
68 ++alternate_protocols;
60 } 69 }
61 } 70 }
62 71
63 // Add the entries from persisted data. 72 // Add the entries from persisted data.
64 for (AlternateProtocolMap::reverse_iterator it = 73 for (AlternateProtocolMap::reverse_iterator it =
65 alternate_protocol_map->rbegin(); 74 alternate_protocol_map->rbegin();
66 it != alternate_protocol_map->rend(); ++it) { 75 it != alternate_protocol_map->rend(); ++it) {
67 alternate_protocol_map_.Put(it->first, it->second); 76 alternate_protocol_map_.Put(it->first, it->second);
68 } 77 }
69 78
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
130 for (SpdyServerHostPortMap::const_iterator it = spdy_servers_map_.begin(); 139 for (SpdyServerHostPortMap::const_iterator it = spdy_servers_map_.begin();
131 it != spdy_servers_map_.end() && count < max_size; ++it) { 140 it != spdy_servers_map_.end() && count < max_size; ++it) {
132 const std::string spdy_server_host_port = it->first; 141 const std::string spdy_server_host_port = it->first;
133 if (it->second) { 142 if (it->second) {
134 spdy_server_list->Append(new base::StringValue(spdy_server_host_port)); 143 spdy_server_list->Append(new base::StringValue(spdy_server_host_port));
135 ++count; 144 ++count;
136 } 145 }
137 } 146 }
138 } 147 }
139 148
140 static const AlternateProtocolInfo* g_forced_alternate_protocol = NULL; 149 static AlternateProtocols* g_forced_alternate_protocol =
150 new AlternateProtocols();
141 151
142 // static 152 // static
143 void HttpServerPropertiesImpl::ForceAlternateProtocol( 153 void HttpServerPropertiesImpl::ForceAlternateProtocol(
144 const AlternateProtocolInfo& info) { 154 const AlternateProtocolInfo& info) {
155 DisableForcedAlternateProtocol();
145 // Note: we're going to leak this. 156 // Note: we're going to leak this.
146 if (g_forced_alternate_protocol) 157 g_forced_alternate_protocol->push_back(info);
147 delete g_forced_alternate_protocol;
148 g_forced_alternate_protocol = new AlternateProtocolInfo(info);
149 } 158 }
150 159
151 // static 160 // static
152 void HttpServerPropertiesImpl::DisableForcedAlternateProtocol() { 161 void HttpServerPropertiesImpl::DisableForcedAlternateProtocol() {
153 delete g_forced_alternate_protocol; 162 g_forced_alternate_protocol->clear();
154 g_forced_alternate_protocol = NULL;
155 } 163 }
156 164
157 base::WeakPtr<HttpServerProperties> HttpServerPropertiesImpl::GetWeakPtr() { 165 base::WeakPtr<HttpServerProperties> HttpServerPropertiesImpl::GetWeakPtr() {
158 return weak_ptr_factory_.GetWeakPtr(); 166 return weak_ptr_factory_.GetWeakPtr();
159 } 167 }
160 168
161 void HttpServerPropertiesImpl::Clear() { 169 void HttpServerPropertiesImpl::Clear() {
162 DCHECK(CalledOnValidThread()); 170 DCHECK(CalledOnValidThread());
163 spdy_servers_map_.Clear(); 171 spdy_servers_map_.Clear();
164 alternate_protocol_map_.Clear(); 172 alternate_protocol_map_.Clear();
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
218 226
219 void HttpServerPropertiesImpl::MaybeForceHTTP11(const HostPortPair& server, 227 void HttpServerPropertiesImpl::MaybeForceHTTP11(const HostPortPair& server,
220 SSLConfig* ssl_config) { 228 SSLConfig* ssl_config) {
221 if (RequiresHTTP11(server)) { 229 if (RequiresHTTP11(server)) {
222 ForceHTTP11(ssl_config); 230 ForceHTTP11(ssl_config);
223 } 231 }
224 } 232 }
225 233
226 bool HttpServerPropertiesImpl::HasAlternateProtocol( 234 bool HttpServerPropertiesImpl::HasAlternateProtocol(
227 const HostPortPair& server) { 235 const HostPortPair& server) {
228 if (g_forced_alternate_protocol) 236 if (!g_forced_alternate_protocol->empty())
229 return true; 237 return true;
230 AlternateProtocolMap::const_iterator it = alternate_protocol_map_.Get(server); 238 AlternateProtocolMap::const_iterator alternate_protocols =
231 if (it != alternate_protocol_map_.end()) 239 alternate_protocol_map_.Get(server);
232 return it->second.probability >= alternate_protocol_probability_threshold_; 240 if (alternate_protocols != alternate_protocol_map_.end()) {
241 for (AlternateProtocols::const_iterator alternate_protocol =
242 alternate_protocols->second.begin();
243 alternate_protocol != alternate_protocols->second.end();
244 alternate_protocol++) {
245 if (alternate_protocol->probability >=
246 alternate_protocol_probability_threshold_) {
247 return true;
248 }
249 }
250 }
233 251
234 auto canonical = GetCanonicalHost(server); 252 auto canonical = GetCanonicalHost(server);
235 if (canonical == canonical_host_to_origin_map_.end() || 253 if (canonical == canonical_host_to_origin_map_.end() ||
236 canonical->second.Equals(server)) { 254 canonical->second.Equals(server)) {
237 return false; 255 return false;
238 } 256 }
239 257
240 return HasAlternateProtocol(canonical->second); 258 return HasAlternateProtocol(canonical->second);
241 } 259 }
242 260
243 std::string HttpServerPropertiesImpl::GetCanonicalSuffix( 261 std::string HttpServerPropertiesImpl::GetCanonicalSuffix(
244 const HostPortPair& server) { 262 const HostPortPair& server) {
245 // If this host ends with a canonical suffix, then return the canonical 263 // If this host ends with a canonical suffix, then return the canonical
246 // suffix. 264 // suffix.
247 for (size_t i = 0; i < canonical_suffixes_.size(); ++i) { 265 for (size_t i = 0; i < canonical_suffixes_.size(); ++i) {
248 std::string canonical_suffix = canonical_suffixes_[i]; 266 std::string canonical_suffix = canonical_suffixes_[i];
249 if (EndsWith(server.host(), canonical_suffixes_[i], false)) { 267 if (EndsWith(server.host(), canonical_suffixes_[i], false)) {
250 return canonical_suffix; 268 return canonical_suffix;
251 } 269 }
252 } 270 }
253 return std::string(); 271 return std::string();
254 } 272 }
255 273
256 AlternateProtocolInfo 274 const AlternateProtocols& HttpServerPropertiesImpl::GetAlternateProtocols(
257 HttpServerPropertiesImpl::GetAlternateProtocol(
258 const HostPortPair& server) { 275 const HostPortPair& server) {
259 DCHECK(HasAlternateProtocol(server)); 276 DCHECK(HasAlternateProtocol(server));
260 277
261 // First check the map. 278 // First check the map.
262 AlternateProtocolMap::iterator it = alternate_protocol_map_.Get(server); 279 AlternateProtocolMap::iterator it = alternate_protocol_map_.Get(server);
263 if (it != alternate_protocol_map_.end()) 280 if (it != alternate_protocol_map_.end())
264 return it->second; 281 return it->second;
265 282
266 // Next check the canonical host. 283 // Next check the canonical host.
267 CanonicalHostMap::const_iterator canonical_host = GetCanonicalHost(server); 284 CanonicalHostMap::const_iterator canonical_host = GetCanonicalHost(server);
268 if (canonical_host != canonical_host_to_origin_map_.end()) 285 if (canonical_host != canonical_host_to_origin_map_.end())
269 return alternate_protocol_map_.Get(canonical_host->second)->second; 286 return alternate_protocol_map_.Get(canonical_host->second)->second;
270 287
271 // We must be forcing an alternate. 288 // We must be forcing an alternate.
272 DCHECK(g_forced_alternate_protocol); 289 DCHECK(!g_forced_alternate_protocol->empty());
273 return *g_forced_alternate_protocol; 290 return *g_forced_alternate_protocol;
274 } 291 }
275 292
276 void HttpServerPropertiesImpl::SetAlternateProtocol( 293 void HttpServerPropertiesImpl::AddAlternateProtocol(
277 const HostPortPair& server, 294 const HostPortPair& server,
278 uint16 alternate_port, 295 uint16 alternate_port,
279 AlternateProtocol alternate_protocol, 296 AlternateProtocol alternate_protocol,
280 double alternate_probability) { 297 double alternate_probability) {
281
282 AlternateProtocolInfo alternate(alternate_port, 298 AlternateProtocolInfo alternate(alternate_port,
283 alternate_protocol, 299 alternate_protocol,
284 alternate_probability); 300 alternate_probability);
285 if (HasAlternateProtocol(server)) { 301 // Do not call HasAlternateProtocol(), because we don't care about
286 const AlternateProtocolInfo existing_alternate = 302 // |g_forced_alternate_protocol|, or whether the alternate protocol
287 GetAlternateProtocol(server); 303 // probability is higher than the threshold.
288 304 AlternateProtocolMap::iterator map_it = alternate_protocol_map_.Get(server);
289 if (existing_alternate.is_broken) { 305 if (map_it != alternate_protocol_map_.end()) {
290 DVLOG(1) << "Ignore alternate protocol since it's known to be broken."; 306 AlternateProtocols existing_alternates = map_it->second;
291 return; 307 AlternateProtocols::iterator it;
308 for (it = existing_alternates.begin(); it != existing_alternates.end();
309 ++it) {
310 if (it->EqualsModuloProbabilityAndProtocol(alternate)) {
Bence 2015/01/30 21:24:50 This needs to be EqualsModuloProbability. We coul
311 break;
312 }
292 } 313 }
293 314
294 if (!existing_alternate.Equals(alternate)) { 315 if (it != existing_alternates.end()) {
295 LOG(WARNING) << "Changing the alternate protocol for: " 316 if (it->is_broken) {
296 << server.ToString() 317 DVLOG(1) << "Ignore alternate protocol since it's known to be broken.";
297 << " from [Port: " << existing_alternate.port 318 return;
298 << ", Protocol: " << existing_alternate.protocol 319 }
299 << ", Probability: " << existing_alternate.probability 320 if (it->probability != alternate_probability) {
300 << "] to [Port: " << alternate_port 321 LOG(WARNING) << "Changing the probability of alternate protocol for: "
301 << ", Protocol: " << alternate_protocol 322 << server.ToString() << " Port: " << it->port
302 << ", Probability: " << alternate_probability 323 << ", Protocol: " << it->protocol
303 << "]."; 324 << ", Probability from: " << it->probability
325 << " to: " << alternate_probability << ".";
326 it->probability = alternate_probability;
327 }
328 } else {
329 existing_alternates.push_back(alternate);
304 } 330 }
331
332 alternate_protocol_map_.Put(server, existing_alternates);
305 } else { 333 } else {
306 if (alternate_probability >= alternate_protocol_probability_threshold_) { 334 if (alternate_probability >= alternate_protocol_probability_threshold_) {
307 // TODO(rch): Consider the case where multiple requests are started 335 // TODO(rch): Consider the case where multiple requests are started
308 // before the first completes. In this case, only one of the jobs 336 // before the first completes. In this case, only one of the jobs
309 // would reach this code, whereas all of them should should have. 337 // would reach this code, whereas all of them should should have.
310 HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_MAPPING_MISSING); 338 HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_MAPPING_MISSING);
311 } 339 }
340 alternate_protocol_map_.Put(server,
341 AlternateProtocols(/*size=*/1, alternate));
312 } 342 }
313 343
314 alternate_protocol_map_.Put(server, alternate);
315
316 // If this host ends with a canonical suffix, then set it as the 344 // If this host ends with a canonical suffix, then set it as the
317 // canonical host. 345 // canonical host.
318 for (size_t i = 0; i < canonical_suffixes_.size(); ++i) { 346 for (size_t i = 0; i < canonical_suffixes_.size(); ++i) {
319 std::string canonical_suffix = canonical_suffixes_[i]; 347 std::string canonical_suffix = canonical_suffixes_[i];
320 if (EndsWith(server.host(), canonical_suffixes_[i], false)) { 348 if (EndsWith(server.host(), canonical_suffixes_[i], false)) {
321 HostPortPair canonical_host(canonical_suffix, server.port()); 349 HostPortPair canonical_host(canonical_suffix, server.port());
322 canonical_host_to_origin_map_[canonical_host] = server; 350 canonical_host_to_origin_map_[canonical_host] = server;
323 break; 351 break;
324 } 352 }
325 } 353 }
326 } 354 }
327 355
328 void HttpServerPropertiesImpl::SetBrokenAlternateProtocol( 356 void HttpServerPropertiesImpl::SetBrokenAlternateProtocol(
329 const HostPortPair& server) { 357 const HostPortPair& server,
330 AlternateProtocolMap::iterator it = alternate_protocol_map_.Get(server); 358 const AlternateProtocolInfo& broken_alternate_protocol) {
331 if (it == alternate_protocol_map_.end()) { 359 AddAlternateProtocol(server, broken_alternate_protocol.port,
332 if (!HasAlternateProtocol(server)) { 360 broken_alternate_protocol.protocol,
333 LOG(DFATAL) << "Trying to mark unknown alternate protocol broken."; 361 broken_alternate_protocol.probability);
334 return; 362 AlternateProtocolMap::iterator alternate_protocols =
363 alternate_protocol_map_.Get(server);
364 DCHECK(alternate_protocols != alternate_protocol_map_.end());
365 AlternateProtocols::iterator it;
366 for (it = alternate_protocols->second.begin();
367 it != alternate_protocols->second.end(); ++it) {
368 if (it->Equals(broken_alternate_protocol)) {
369 it->is_broken = true;
370 break;
335 } 371 }
336 // This server's alternate protocol information is coming from a canonical
337 // server. Add an entry in the map for this server explicitly so that
338 // it can be marked as broken.
339 it = alternate_protocol_map_.Put(server, GetAlternateProtocol(server));
340 } 372 }
341 it->second.is_broken = true; 373 DCHECK(it != alternate_protocols->second.end());
374
342 int count = ++broken_alternate_protocol_map_[server]; 375 int count = ++broken_alternate_protocol_map_[server];
343 base::TimeDelta delay = 376 base::TimeDelta delay =
344 base::TimeDelta::FromSeconds(kBrokenAlternateProtocolDelaySecs); 377 base::TimeDelta::FromSeconds(kBrokenAlternateProtocolDelaySecs);
345 BrokenAlternateProtocolEntry entry; 378 BrokenAlternateProtocolEntry entry;
346 entry.server = server; 379 entry.server = server;
347 entry.when = base::TimeTicks::Now() + delay * (1 << (count - 1)); 380 entry.when = base::TimeTicks::Now() + delay * (1 << (count - 1));
348 broken_alternate_protocol_list_.push_back(entry); 381 broken_alternate_protocol_list_.push_back(entry);
349 382
350 // Do not leave this host as canonical so that we don't infer the other 383 // Do not leave this host as canonical so that we don't infer the other
351 // hosts are also broken without testing them first. 384 // hosts are also broken without testing them first.
352 RemoveCanonicalHost(server); 385 RemoveCanonicalHost(server);
353 386
354 // If this is the only entry in the list, schedule an expiration task. 387 // If this is the only entry in the list, schedule an expiration task.
355 // Otherwse it will be rescheduled automatically when the pending 388 // Otherwise it will be rescheduled automatically when the pending task runs.
356 // task runs.
357 if (broken_alternate_protocol_list_.size() == 1) { 389 if (broken_alternate_protocol_list_.size() == 1) {
358 ScheduleBrokenAlternateProtocolMappingsExpiration(); 390 ScheduleBrokenAlternateProtocolMappingsExpiration();
359 } 391 }
360 } 392 }
361 393
362 bool HttpServerPropertiesImpl::WasAlternateProtocolRecentlyBroken( 394 bool HttpServerPropertiesImpl::WasAlternateProtocolRecentlyBroken(
363 const HostPortPair& server) { 395 const HostPortPair& server,
396 const AlternateProtocolInfo& alternate_protocol) {
364 return ContainsKey(broken_alternate_protocol_map_, server); 397 return ContainsKey(broken_alternate_protocol_map_, server);
365 } 398 }
366 399
367 void HttpServerPropertiesImpl::ConfirmAlternateProtocol( 400 void HttpServerPropertiesImpl::ConfirmAlternateProtocol(
368 const HostPortPair& server) { 401 const HostPortPair& server,
402 const AlternateProtocolInfo& alternate_protocol) {
369 broken_alternate_protocol_map_.erase(server); 403 broken_alternate_protocol_map_.erase(server);
370 } 404 }
371 405
372 void HttpServerPropertiesImpl::ClearAlternateProtocol( 406 void HttpServerPropertiesImpl::ClearAlternateProtocol(
373 const HostPortPair& server) { 407 const HostPortPair& server) {
374 AlternateProtocolMap::iterator it = alternate_protocol_map_.Peek(server); 408 AlternateProtocolMap::iterator it = alternate_protocol_map_.Peek(server);
375 if (it != alternate_protocol_map_.end()) 409 if (it != alternate_protocol_map_.end())
376 alternate_protocol_map_.Erase(it); 410 alternate_protocol_map_.Erase(it);
377 411
378 RemoveCanonicalHost(server); 412 RemoveCanonicalHost(server);
379 } 413 }
380 414
415 void HttpServerPropertiesImpl::ClearNonBrokenAlternateProtocols(
416 const HostPortPair& server) {
417 AlternateProtocolMap::iterator alternate_protocols =
418 alternate_protocol_map_.Peek(server);
419 if (alternate_protocols != alternate_protocol_map_.end()) {
420 for (AlternateProtocols::iterator it = alternate_protocols->second.begin();
421 it != alternate_protocols->second.end();) {
422 if (!it->is_broken) {
423 it = alternate_protocols->second.erase(it);
424 } else {
425 ++it;
426 }
427 }
428 if (alternate_protocols->second.size() == 0) {
429 alternate_protocols = alternate_protocol_map_.Erase(alternate_protocols);
430 RemoveCanonicalHost(server);
431 }
432 }
433 }
434
435 void HttpServerPropertiesImpl::RemoveAlternateProtocol(
436 const HostPortPair& server,
437 const AlternateProtocolInfo& alternate_protocol) {
438 AlternateProtocolMap::iterator alternate_protocols =
439 alternate_protocol_map_.Peek(server);
440 if (alternate_protocols == alternate_protocol_map_.end()) {
441 return;
442 }
443 for (AlternateProtocols::iterator it = alternate_protocols->second.begin();
444 it != alternate_protocols->second.end(); ++it) {
445 if (it->Equals(alternate_protocol)) {
446 alternate_protocols->second.erase(it);
447 break;
448 }
449 }
450 if (alternate_protocols->second.size() == 0) {
451 alternate_protocol_map_.Erase(alternate_protocols);
452 RemoveCanonicalHost(server);
453 }
454 }
455
381 const AlternateProtocolMap& 456 const AlternateProtocolMap&
382 HttpServerPropertiesImpl::alternate_protocol_map() const { 457 HttpServerPropertiesImpl::alternate_protocol_map() const {
383 return alternate_protocol_map_; 458 return alternate_protocol_map_;
384 } 459 }
385 460
386 const SettingsMap& HttpServerPropertiesImpl::GetSpdySettings( 461 const SettingsMap& HttpServerPropertiesImpl::GetSpdySettings(
387 const HostPortPair& host_port_pair) { 462 const HostPortPair& host_port_pair) {
388 SpdySettingsMap::iterator it = spdy_settings_map_.Get(host_port_pair); 463 SpdySettingsMap::iterator it = spdy_settings_map_.Get(host_port_pair);
389 if (it == spdy_settings_map_.end()) { 464 if (it == spdy_settings_map_.end()) {
390 CR_DEFINE_STATIC_LOCAL(SettingsMap, kEmptySettingsMap, ()); 465 CR_DEFINE_STATIC_LOCAL(SettingsMap, kEmptySettingsMap, ());
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
528 base::TimeDelta delay = when > now ? when - now : base::TimeDelta(); 603 base::TimeDelta delay = when > now ? when - now : base::TimeDelta();
529 base::MessageLoop::current()->PostDelayedTask( 604 base::MessageLoop::current()->PostDelayedTask(
530 FROM_HERE, 605 FROM_HERE,
531 base::Bind( 606 base::Bind(
532 &HttpServerPropertiesImpl::ExpireBrokenAlternateProtocolMappings, 607 &HttpServerPropertiesImpl::ExpireBrokenAlternateProtocolMappings,
533 weak_ptr_factory_.GetWeakPtr()), 608 weak_ptr_factory_.GetWeakPtr()),
534 delay); 609 delay);
535 } 610 }
536 611
537 } // namespace net 612 } // namespace net
OLDNEW
« no previous file with comments | « net/http/http_server_properties_impl.h ('k') | net/http/http_server_properties_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698