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

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: Re: 18. Created 5 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
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 do not 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 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
169 const HostPortPair& host_port_pair) { 178 const HostPortPair& host_port_pair) {
170 DCHECK(CalledOnValidThread()); 179 DCHECK(CalledOnValidThread());
171 if (host_port_pair.host().empty()) 180 if (host_port_pair.host().empty())
172 return false; 181 return false;
173 182
174 SpdyServerHostPortMap::iterator spdy_host_port = 183 SpdyServerHostPortMap::iterator spdy_host_port =
175 spdy_servers_map_.Get(host_port_pair.ToString()); 184 spdy_servers_map_.Get(host_port_pair.ToString());
176 if (spdy_host_port != spdy_servers_map_.end() && spdy_host_port->second) 185 if (spdy_host_port != spdy_servers_map_.end() && spdy_host_port->second)
177 return true; 186 return true;
178 187
179 const AlternateProtocolInfo info = GetAlternateProtocol(host_port_pair); 188 const AlternateProtocols alternates = GetAlternateProtocols(host_port_pair);
180 return info.protocol == QUIC; 189 for (const AlternateProtocolInfo& alternate : alternates) {
190 if (alternate.protocol == QUIC) {
191 return true;
192 }
193 }
194 return false;
181 } 195 }
182 196
183 void HttpServerPropertiesImpl::SetSupportsSpdy( 197 void HttpServerPropertiesImpl::SetSupportsSpdy(
184 const HostPortPair& host_port_pair, 198 const HostPortPair& host_port_pair,
185 bool support_spdy) { 199 bool support_spdy) {
186 DCHECK(CalledOnValidThread()); 200 DCHECK(CalledOnValidThread());
187 if (host_port_pair.host().empty()) 201 if (host_port_pair.host().empty())
188 return; 202 return;
189 203
190 SpdyServerHostPortMap::iterator spdy_host_port = 204 SpdyServerHostPortMap::iterator spdy_host_port =
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after
228 // suffix. 242 // suffix.
229 for (size_t i = 0; i < canonical_suffixes_.size(); ++i) { 243 for (size_t i = 0; i < canonical_suffixes_.size(); ++i) {
230 std::string canonical_suffix = canonical_suffixes_[i]; 244 std::string canonical_suffix = canonical_suffixes_[i];
231 if (EndsWith(host, canonical_suffixes_[i], false)) { 245 if (EndsWith(host, canonical_suffixes_[i], false)) {
232 return canonical_suffix; 246 return canonical_suffix;
233 } 247 }
234 } 248 }
235 return std::string(); 249 return std::string();
236 } 250 }
237 251
238 AlternateProtocolInfo HttpServerPropertiesImpl::GetAlternateProtocol( 252 AlternateProtocols HttpServerPropertiesImpl::GetAlternateProtocols(
239 const HostPortPair& server) { 253 const HostPortPair& server) {
240 AlternateProtocolMap::const_iterator it = 254 AlternateProtocols alternate_protocols_above_threshold;
255 AlternateProtocolMap::const_iterator const alternate_protocols =
241 GetAlternateProtocolIterator(server); 256 GetAlternateProtocolIterator(server);
242 if (it != alternate_protocol_map_.end() && 257 if (alternate_protocols != alternate_protocol_map_.end()) {
243 it->second.probability >= alternate_protocol_probability_threshold_) 258 for (const AlternateProtocolInfo& alternate : alternate_protocols->second) {
244 return it->second; 259 if (alternate.probability >= alternate_protocol_probability_threshold_)
260 alternate_protocols_above_threshold.push_back(alternate);
261 }
262 return alternate_protocols_above_threshold;
263 }
245 264
246 if (g_forced_alternate_protocol) 265 if (g_forced_alternate_protocol) {
247 return *g_forced_alternate_protocol; 266 alternate_protocols_above_threshold.push_back(*g_forced_alternate_protocol);
267 }
248 268
249 AlternateProtocolInfo uninitialized_alternate_protocol; 269 return alternate_protocols_above_threshold;
250 return uninitialized_alternate_protocol;
251 } 270 }
252 271
253 void HttpServerPropertiesImpl::SetAlternateProtocol( 272 void HttpServerPropertiesImpl::AddAlternateProtocol(
254 const HostPortPair& server, 273 const HostPortPair& server,
255 uint16 alternate_port, 274 uint16 alternate_port,
256 AlternateProtocol alternate_protocol, 275 AlternateProtocol alternate_protocol,
257 double alternate_probability) { 276 double alternate_probability) {
258 277 if (!IsAlternateProtocolValid(alternate_protocol))
278 return;
259 AlternateProtocolInfo alternate(alternate_port, 279 AlternateProtocolInfo alternate(alternate_port,
260 alternate_protocol, 280 alternate_protocol,
261 alternate_probability); 281 alternate_probability);
262 AlternateProtocolMap::const_iterator it = 282 AlternateProtocolMap::const_iterator map_it =
263 GetAlternateProtocolIterator(server); 283 alternate_protocol_map_.Get(server);
264 if (it != alternate_protocol_map_.end()) { 284 if (map_it != alternate_protocol_map_.end()) {
265 const AlternateProtocolInfo existing_alternate = it->second; 285 AlternateProtocols existing_alternates = map_it->second;
266 286 AlternateProtocols::iterator it;
267 if (existing_alternate.is_broken) { 287 for (it = existing_alternates.begin(); it != existing_alternates.end();
268 DVLOG(1) << "Ignore alternate protocol since it's known to be broken."; 288 ++it) {
269 return; 289 if (it->EqualsModuloProbability(alternate)) {
290 break;
291 }
270 } 292 }
271 293
272 if (!existing_alternate.Equals(alternate)) { 294 if (it != existing_alternates.end()) {
273 LOG(WARNING) << "Changing the alternate protocol for: " 295 if (it->is_broken) {
274 << server.ToString() 296 DVLOG(1) << "Ignore alternate protocol since it's known to be broken.";
275 << " from [Port: " << existing_alternate.port 297 return;
276 << ", Protocol: " << existing_alternate.protocol 298 }
277 << ", Probability: " << existing_alternate.probability 299 if (it->probability != alternate_probability) {
278 << "] to [Port: " << alternate_port 300 LOG(WARNING) << "Changing alternate protocol probability from "
279 << ", Protocol: " << alternate_protocol 301 << it->ToString() << server.ToString()
280 << ", Probability: " << alternate_probability 302 << " Port: " << it->port << " to " << alternate.ToString()
281 << "]."; 303 << ".";
304 it->probability = alternate_probability;
305 } else {
306 // Alternate protocol is identical to existing one.
307 return;
308 }
309 } else {
310 existing_alternates.push_back(alternate);
282 } 311 }
312
313 alternate_protocol_map_.Put(server, existing_alternates);
283 } else { 314 } else {
284 if (alternate_probability >= alternate_protocol_probability_threshold_) { 315 if (alternate_probability >= alternate_protocol_probability_threshold_) {
285 // TODO(rch): Consider the case where multiple requests are started 316 // TODO(rch): Consider the case where multiple requests are started
286 // before the first completes. In this case, only one of the jobs 317 // before the first completes. In this case, only one of the jobs
287 // would reach this code, whereas all of them should should have. 318 // would reach this code, whereas all of them should should have.
288 HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_MAPPING_MISSING); 319 HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_MAPPING_MISSING);
289 } 320 }
321 alternate_protocol_map_.Put(server,
322 AlternateProtocols(/*size=*/1, alternate));
290 } 323 }
291 324
292 alternate_protocol_map_.Put(server, alternate);
293
294 // If this host ends with a canonical suffix, then set it as the 325 // If this host ends with a canonical suffix, then set it as the
295 // canonical host. 326 // canonical host.
296 for (size_t i = 0; i < canonical_suffixes_.size(); ++i) { 327 for (size_t i = 0; i < canonical_suffixes_.size(); ++i) {
297 std::string canonical_suffix = canonical_suffixes_[i]; 328 std::string canonical_suffix = canonical_suffixes_[i];
298 if (EndsWith(server.host(), canonical_suffixes_[i], false)) { 329 if (EndsWith(server.host(), canonical_suffixes_[i], false)) {
299 HostPortPair canonical_host(canonical_suffix, server.port()); 330 HostPortPair canonical_host(canonical_suffix, server.port());
300 canonical_host_to_origin_map_[canonical_host] = server; 331 canonical_host_to_origin_map_[canonical_host] = server;
301 break; 332 break;
302 } 333 }
303 } 334 }
304 } 335 }
305 336
306 void HttpServerPropertiesImpl::SetBrokenAlternateProtocol( 337 void HttpServerPropertiesImpl::SetBrokenAlternateProtocol(
307 const HostPortPair& server) { 338 const HostPortPair& server,
308 AlternateProtocolMap::iterator it = alternate_protocol_map_.Get(server); 339 const AlternateProtocolInfo& broken_alternate_protocol) {
309 const AlternateProtocolInfo alternate = GetAlternateProtocol(server); 340 if (!IsAlternateProtocolValid(broken_alternate_protocol.protocol))
310 if (it == alternate_protocol_map_.end()) { 341 return;
311 if (alternate.protocol == UNINITIALIZED_ALTERNATE_PROTOCOL) { 342 AddAlternateProtocol(server, broken_alternate_protocol.port,
312 LOG(DFATAL) << "Trying to mark unknown alternate protocol broken."; 343 broken_alternate_protocol.protocol,
313 return; 344 broken_alternate_protocol.probability);
345 AlternateProtocolMap::iterator alternate_protocols =
346 alternate_protocol_map_.Get(server);
347 DCHECK(alternate_protocols != alternate_protocol_map_.end());
348 AlternateProtocols::iterator it;
349 for (it = alternate_protocols->second.begin();
350 it != alternate_protocols->second.end(); ++it) {
351 if (it->Equals(broken_alternate_protocol)) {
352 it->is_broken = true;
353 break;
314 } 354 }
315 // This server's alternate protocol information is coming from a canonical
316 // server. Add an entry in the map for this server explicitly so that
317 // it can be marked as broken.
318 it = alternate_protocol_map_.Put(server, alternate);
319 } 355 }
320 it->second.is_broken = true; 356 DCHECK(it != alternate_protocols->second.end());
321 const BrokenAlternateProtocolEntry entry(server, alternate.port, 357
322 alternate.protocol); 358 const BrokenAlternateProtocolEntry entry(server,
359 broken_alternate_protocol.port,
360 broken_alternate_protocol.protocol);
323 int count = ++broken_alternate_protocol_map_[entry]; 361 int count = ++broken_alternate_protocol_map_[entry];
324 base::TimeDelta delay = 362 base::TimeDelta delay =
325 base::TimeDelta::FromSeconds(kBrokenAlternateProtocolDelaySecs); 363 base::TimeDelta::FromSeconds(kBrokenAlternateProtocolDelaySecs);
326 base::TimeTicks when = base::TimeTicks::Now() + delay * (1 << (count - 1)); 364 base::TimeTicks when = base::TimeTicks::Now() + delay * (1 << (count - 1));
327 broken_alternate_protocol_list_.push_back( 365 broken_alternate_protocol_list_.push_back(
328 BrokenAlternateProtocolEntryWithTime(entry, when)); 366 BrokenAlternateProtocolEntryWithTime(entry, when));
329 367
330 // Do not leave this host as canonical so that we don't infer the other 368 // Do not leave this host as canonical so that we don't infer the other
331 // hosts are also broken without testing them first. 369 // hosts are also broken without testing them first.
332 RemoveCanonicalHost(server); 370 RemoveCanonicalHost(server);
333 371
334 // If this is the only entry in the list, schedule an expiration task. 372 // If this is the only entry in the list, schedule an expiration task.
335 // Otherwise it will be rescheduled automatically when the pending task runs. 373 // Otherwise it will be rescheduled automatically when the pending task runs.
336 if (broken_alternate_protocol_list_.size() == 1) { 374 if (broken_alternate_protocol_list_.size() == 1) {
337 ScheduleBrokenAlternateProtocolMappingsExpiration(); 375 ScheduleBrokenAlternateProtocolMappingsExpiration();
338 } 376 }
339 } 377 }
340 378
341 bool HttpServerPropertiesImpl::WasAlternateProtocolRecentlyBroken( 379 bool HttpServerPropertiesImpl::WasAlternateProtocolRecentlyBroken(
342 const HostPortPair& server) { 380 const HostPortPair& server,
343 const AlternateProtocolInfo alternate_protocol = GetAlternateProtocol(server); 381 const AlternateProtocolInfo& alternate_protocol) const {
344 if (alternate_protocol.protocol == UNINITIALIZED_ALTERNATE_PROTOCOL)
345 return false;
346 const BrokenAlternateProtocolEntry entry(server, alternate_protocol.port, 382 const BrokenAlternateProtocolEntry entry(server, alternate_protocol.port,
347 alternate_protocol.protocol); 383 alternate_protocol.protocol);
348 return ContainsKey(broken_alternate_protocol_map_, entry); 384 return ContainsKey(broken_alternate_protocol_map_, entry);
349 } 385 }
350 386
351 void HttpServerPropertiesImpl::ConfirmAlternateProtocol( 387 void HttpServerPropertiesImpl::ConfirmAlternateProtocol(
352 const HostPortPair& server) { 388 const HostPortPair& server,
353 const AlternateProtocolInfo alternate_protocol = GetAlternateProtocol(server); 389 const AlternateProtocolInfo& alternate_protocol) {
354 if (alternate_protocol.protocol == UNINITIALIZED_ALTERNATE_PROTOCOL)
355 return;
356 const BrokenAlternateProtocolEntry entry(server, alternate_protocol.port, 390 const BrokenAlternateProtocolEntry entry(server, alternate_protocol.port,
357 alternate_protocol.protocol); 391 alternate_protocol.protocol);
358 broken_alternate_protocol_map_.erase(entry); 392 broken_alternate_protocol_map_.erase(entry);
359 } 393 }
360 394
361 void HttpServerPropertiesImpl::ClearAlternateProtocol( 395 void HttpServerPropertiesImpl::ClearAlternateProtocols(
362 const HostPortPair& server) { 396 const HostPortPair& server) {
363 AlternateProtocolMap::iterator it = alternate_protocol_map_.Peek(server); 397 AlternateProtocolMap::iterator it = alternate_protocol_map_.Peek(server);
364 if (it != alternate_protocol_map_.end()) 398 if (it != alternate_protocol_map_.end())
365 alternate_protocol_map_.Erase(it); 399 alternate_protocol_map_.Erase(it);
366 400
367 RemoveCanonicalHost(server); 401 RemoveCanonicalHost(server);
368 } 402 }
369 403
404 void HttpServerPropertiesImpl::ClearNonBrokenAlternateProtocols(
405 const HostPortPair& server) {
406 AlternateProtocolMap::iterator alternate_protocols =
407 alternate_protocol_map_.Peek(server);
408 if (alternate_protocols == alternate_protocol_map_.end()) {
409 return;
410 }
411 for (AlternateProtocols::iterator it = alternate_protocols->second.begin();
412 it != alternate_protocols->second.end();) {
413 if (!it->is_broken) {
414 it = alternate_protocols->second.erase(it);
415 } else {
416 ++it;
417 }
418 }
419 if (alternate_protocols->second.size() == 0) {
420 alternate_protocol_map_.Erase(alternate_protocols);
421 RemoveCanonicalHost(server);
422 }
423 }
424
425 void HttpServerPropertiesImpl::RemoveAlternateProtocol(
426 const HostPortPair& server,
427 const AlternateProtocolInfo& alternate_protocol) {
428 AlternateProtocolMap::iterator alternate_protocols =
429 alternate_protocol_map_.Peek(server);
430 if (alternate_protocols == alternate_protocol_map_.end()) {
431 return;
432 }
433 for (AlternateProtocols::iterator it = alternate_protocols->second.begin();
434 it != alternate_protocols->second.end(); ++it) {
435 if (it->EqualsModuloProbability(alternate_protocol)) {
436 alternate_protocols->second.erase(it);
437 break;
438 }
439 }
440 if (alternate_protocols->second.size() == 0) {
441 alternate_protocol_map_.Erase(alternate_protocols);
442 RemoveCanonicalHost(server);
443 }
444 }
445
370 const AlternateProtocolMap& 446 const AlternateProtocolMap&
371 HttpServerPropertiesImpl::alternate_protocol_map() const { 447 HttpServerPropertiesImpl::alternate_protocol_map() const {
372 return alternate_protocol_map_; 448 return alternate_protocol_map_;
373 } 449 }
374 450
375 const SettingsMap& HttpServerPropertiesImpl::GetSpdySettings( 451 const SettingsMap& HttpServerPropertiesImpl::GetSpdySettings(
376 const HostPortPair& host_port_pair) { 452 const HostPortPair& host_port_pair) {
377 SpdySettingsMap::iterator it = spdy_settings_map_.Get(host_port_pair); 453 SpdySettingsMap::iterator it = spdy_settings_map_.Get(host_port_pair);
378 if (it == spdy_settings_map_.end()) { 454 if (it == spdy_settings_map_.end()) {
379 CR_DEFINE_STATIC_LOCAL(SettingsMap, kEmptySettingsMap, ()); 455 CR_DEFINE_STATIC_LOCAL(SettingsMap, kEmptySettingsMap, ());
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
506 base::TimeTicks now = base::TimeTicks::Now(); 582 base::TimeTicks now = base::TimeTicks::Now();
507 while (!broken_alternate_protocol_list_.empty()) { 583 while (!broken_alternate_protocol_list_.empty()) {
508 BrokenAlternateProtocolEntryWithTime entry_with_time = 584 BrokenAlternateProtocolEntryWithTime entry_with_time =
509 broken_alternate_protocol_list_.front(); 585 broken_alternate_protocol_list_.front();
510 if (now < entry_with_time.when) { 586 if (now < entry_with_time.when) {
511 break; 587 break;
512 } 588 }
513 589
514 const BrokenAlternateProtocolEntry& entry = 590 const BrokenAlternateProtocolEntry& entry =
515 entry_with_time.broken_alternate_protocol_entry; 591 entry_with_time.broken_alternate_protocol_entry;
516 ClearAlternateProtocol(entry.server); 592 const AlternateProtocolInfo alternate_protocol(entry.port, entry.protocol,
593 1.0);
594 RemoveAlternateProtocol(entry.server, alternate_protocol);
517 broken_alternate_protocol_list_.pop_front(); 595 broken_alternate_protocol_list_.pop_front();
518 } 596 }
519 ScheduleBrokenAlternateProtocolMappingsExpiration(); 597 ScheduleBrokenAlternateProtocolMappingsExpiration();
520 } 598 }
521 599
522 void 600 void
523 HttpServerPropertiesImpl::ScheduleBrokenAlternateProtocolMappingsExpiration() { 601 HttpServerPropertiesImpl::ScheduleBrokenAlternateProtocolMappingsExpiration() {
524 if (broken_alternate_protocol_list_.empty()) { 602 if (broken_alternate_protocol_list_.empty()) {
525 return; 603 return;
526 } 604 }
527 base::TimeTicks now = base::TimeTicks::Now(); 605 base::TimeTicks now = base::TimeTicks::Now();
528 base::TimeTicks when = broken_alternate_protocol_list_.front().when; 606 base::TimeTicks when = broken_alternate_protocol_list_.front().when;
529 base::TimeDelta delay = when > now ? when - now : base::TimeDelta(); 607 base::TimeDelta delay = when > now ? when - now : base::TimeDelta();
530 base::MessageLoop::current()->PostDelayedTask( 608 base::MessageLoop::current()->PostDelayedTask(
531 FROM_HERE, 609 FROM_HERE,
532 base::Bind( 610 base::Bind(
533 &HttpServerPropertiesImpl::ExpireBrokenAlternateProtocolMappings, 611 &HttpServerPropertiesImpl::ExpireBrokenAlternateProtocolMappings,
534 weak_ptr_factory_.GetWeakPtr()), 612 weak_ptr_factory_.GetWeakPtr()),
535 delay); 613 delay);
536 } 614 }
537 615
538 } // namespace net 616 } // 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