OLD | NEW |
---|---|
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 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
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 // Keep all the broken ones since those don't get persisted. |
54 for (AlternateProtocolMap::iterator it = alternate_protocol_map_.begin(); | 54 for (AlternateProtocolMap::iterator it = alternate_protocol_map_.begin(); |
55 it != alternate_protocol_map_.end();) { | 55 it != alternate_protocol_map_.end();) { |
56 if (it->second.is_broken) { | 56 const AlternativeService alternative_service( |
57 it->second.protocol, it->first.host(), it->second.port); | |
58 if (IsAlternativeServiceBroken(alternative_service)) { | |
57 ++it; | 59 ++it; |
58 } else { | 60 } else { |
59 it = alternate_protocol_map_.Erase(it); | 61 it = alternate_protocol_map_.Erase(it); |
60 } | 62 } |
61 } | 63 } |
62 | 64 |
63 // Add the entries from persisted data. | 65 // Add the entries from persisted data. |
64 for (AlternateProtocolMap::reverse_iterator it = | 66 for (AlternateProtocolMap::reverse_iterator it = |
65 alternate_protocol_map->rbegin(); | 67 alternate_protocol_map->rbegin(); |
66 it != alternate_protocol_map->rend(); ++it) { | 68 it != alternate_protocol_map->rend(); ++it) { |
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
248 | 250 |
249 AlternateProtocolInfo uninitialized_alternate_protocol; | 251 AlternateProtocolInfo uninitialized_alternate_protocol; |
250 return uninitialized_alternate_protocol; | 252 return uninitialized_alternate_protocol; |
251 } | 253 } |
252 | 254 |
253 void HttpServerPropertiesImpl::SetAlternateProtocol( | 255 void HttpServerPropertiesImpl::SetAlternateProtocol( |
254 const HostPortPair& server, | 256 const HostPortPair& server, |
255 uint16 alternate_port, | 257 uint16 alternate_port, |
256 AlternateProtocol alternate_protocol, | 258 AlternateProtocol alternate_protocol, |
257 double alternate_probability) { | 259 double alternate_probability) { |
260 const AlternativeService alternative_service(alternate_protocol, | |
261 server.host(), alternate_port); | |
262 if (IsAlternativeServiceBroken(alternative_service)) { | |
263 DVLOG(1) << "Ignore alternative service since it is known to be broken."; | |
264 return; | |
265 } | |
258 | 266 |
259 AlternateProtocolInfo alternate(alternate_port, | 267 const AlternateProtocolInfo alternate(alternate_port, alternate_protocol, |
260 alternate_protocol, | 268 alternate_probability); |
261 alternate_probability); | |
262 AlternateProtocolMap::const_iterator it = | 269 AlternateProtocolMap::const_iterator it = |
263 GetAlternateProtocolIterator(server); | 270 GetAlternateProtocolIterator(server); |
264 if (it != alternate_protocol_map_.end()) { | 271 if (it != alternate_protocol_map_.end()) { |
265 const AlternateProtocolInfo existing_alternate = it->second; | 272 const AlternateProtocolInfo existing_alternate = it->second; |
266 | 273 |
267 if (existing_alternate.is_broken) { | |
268 DVLOG(1) << "Ignore alternate protocol since it's known to be broken."; | |
269 return; | |
270 } | |
271 | |
272 if (!existing_alternate.Equals(alternate)) { | 274 if (!existing_alternate.Equals(alternate)) { |
273 LOG(WARNING) << "Changing the alternate protocol for: " | 275 LOG(WARNING) << "Changing the alternate protocol for: " |
274 << server.ToString() | 276 << server.ToString() |
275 << " from [Port: " << existing_alternate.port | 277 << " from [Port: " << existing_alternate.port |
276 << ", Protocol: " << existing_alternate.protocol | 278 << ", Protocol: " << existing_alternate.protocol |
277 << ", Probability: " << existing_alternate.probability | 279 << ", Probability: " << existing_alternate.probability |
278 << "] to [Port: " << alternate_port | 280 << "] to [Port: " << alternate_port |
279 << ", Protocol: " << alternate_protocol | 281 << ", Protocol: " << alternate_protocol |
280 << ", Probability: " << alternate_probability | 282 << ", Probability: " << alternate_probability |
281 << "]."; | 283 << "]."; |
(...skipping 28 matching lines...) Expand all Loading... | |
310 if (it == alternate_protocol_map_.end()) { | 312 if (it == alternate_protocol_map_.end()) { |
311 if (alternate.protocol == UNINITIALIZED_ALTERNATE_PROTOCOL) { | 313 if (alternate.protocol == UNINITIALIZED_ALTERNATE_PROTOCOL) { |
312 LOG(DFATAL) << "Trying to mark unknown alternate protocol broken."; | 314 LOG(DFATAL) << "Trying to mark unknown alternate protocol broken."; |
313 return; | 315 return; |
314 } | 316 } |
315 // This server's alternate protocol information is coming from a canonical | 317 // 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 | 318 // server. Add an entry in the map for this server explicitly so that |
317 // it can be marked as broken. | 319 // it can be marked as broken. |
318 it = alternate_protocol_map_.Put(server, alternate); | 320 it = alternate_protocol_map_.Put(server, alternate); |
319 } | 321 } |
320 it->second.is_broken = true; | |
321 const AlternativeService alternative_service(alternate.protocol, | 322 const AlternativeService alternative_service(alternate.protocol, |
322 server.host(), alternate.port); | 323 server.host(), alternate.port); |
323 int count = ++recently_broken_alternative_services_[alternative_service]; | 324 int count = ++recently_broken_alternative_services_[alternative_service]; |
324 base::TimeDelta delay = | 325 base::TimeDelta delay = |
325 base::TimeDelta::FromSeconds(kBrokenAlternateProtocolDelaySecs); | 326 base::TimeDelta::FromSeconds(kBrokenAlternateProtocolDelaySecs); |
326 base::TimeTicks when = base::TimeTicks::Now() + delay * (1 << (count - 1)); | 327 base::TimeTicks when = base::TimeTicks::Now() + delay * (1 << (count - 1)); |
327 auto result = broken_alternative_services_.insert( | 328 auto result = broken_alternative_services_.insert( |
328 std::make_pair(alternative_service, when)); | 329 std::make_pair(alternative_service, when)); |
329 // Return if alternative service is already in expiration queue. | 330 // Return if alternative service is already in expiration queue. |
330 if (!result.second) { | 331 if (!result.second) { |
331 return; | 332 return; |
332 } | 333 } |
333 | 334 |
334 // Do not leave this host as canonical so that we don't infer the other | 335 // Do not leave this host as canonical so that we don't infer the other |
335 // hosts are also broken without testing them first. | 336 // hosts are also broken without testing them first. |
336 RemoveCanonicalHost(server); | 337 RemoveCanonicalHost(server); |
337 | 338 |
338 // If this is the only entry in the list, schedule an expiration task. | 339 // If this is the only entry in the list, schedule an expiration task. |
339 // Otherwise it will be rescheduled automatically when the pending task runs. | 340 // Otherwise it will be rescheduled automatically when the pending task runs. |
340 if (broken_alternative_services_.size() == 1) { | 341 if (broken_alternative_services_.size() == 1) { |
341 ScheduleBrokenAlternateProtocolMappingsExpiration(); | 342 ScheduleBrokenAlternateProtocolMappingsExpiration(); |
342 } | 343 } |
343 } | 344 } |
344 | 345 |
346 bool HttpServerPropertiesImpl::IsAlternativeServiceBroken( | |
347 const AlternativeService& alternative_service) { | |
348 return broken_alternative_services_.find(alternative_service) != | |
Ryan Hamilton
2015/03/10 21:05:46
Can you do this instead:
return ContainsKey(broke
Bence
2015/03/10 21:46:13
Done.
| |
349 broken_alternative_services_.end(); | |
350 } | |
351 | |
345 bool HttpServerPropertiesImpl::WasAlternateProtocolRecentlyBroken( | 352 bool HttpServerPropertiesImpl::WasAlternateProtocolRecentlyBroken( |
346 const HostPortPair& server) { | 353 const HostPortPair& server) { |
347 const AlternateProtocolInfo alternate_protocol = GetAlternateProtocol(server); | 354 const AlternateProtocolInfo alternate_protocol = GetAlternateProtocol(server); |
348 if (alternate_protocol.protocol == UNINITIALIZED_ALTERNATE_PROTOCOL) | 355 if (alternate_protocol.protocol == UNINITIALIZED_ALTERNATE_PROTOCOL) |
349 return false; | 356 return false; |
350 const AlternativeService alternative_service( | 357 const AlternativeService alternative_service( |
351 alternate_protocol.protocol, server.host(), alternate_protocol.port); | 358 alternate_protocol.protocol, server.host(), alternate_protocol.port); |
352 return ContainsKey(recently_broken_alternative_services_, | 359 return ContainsKey(recently_broken_alternative_services_, |
353 alternative_service); | 360 alternative_service); |
354 } | 361 } |
355 | 362 |
356 void HttpServerPropertiesImpl::ConfirmAlternateProtocol( | 363 void HttpServerPropertiesImpl::ConfirmAlternateProtocol( |
357 const HostPortPair& server) { | 364 const HostPortPair& server) { |
358 const AlternateProtocolInfo alternate_protocol = GetAlternateProtocol(server); | 365 const AlternateProtocolInfo alternate_protocol = GetAlternateProtocol(server); |
359 if (alternate_protocol.protocol == UNINITIALIZED_ALTERNATE_PROTOCOL) | 366 if (alternate_protocol.protocol == UNINITIALIZED_ALTERNATE_PROTOCOL) |
360 return; | 367 return; |
361 const AlternativeService alternative_service( | 368 const AlternativeService alternative_service( |
362 alternate_protocol.protocol, server.host(), alternate_protocol.port); | 369 alternate_protocol.protocol, server.host(), alternate_protocol.port); |
363 recently_broken_alternative_services_.erase(alternative_service); | 370 ignore_result(broken_alternative_services_.erase(alternative_service)); |
Ryan Hamilton
2015/03/10 21:05:46
is ignore_result required?
Bence
2015/03/10 21:46:13
erase(Key) returns size_t, so it makes sense, but
Ryan Hamilton
2015/03/10 22:15:26
I think I'd remove it since we don't typically do
Bence
2015/03/10 22:54:41
Done.
| |
371 ignore_result( | |
372 recently_broken_alternative_services_.erase(alternative_service)); | |
364 } | 373 } |
365 | 374 |
366 void HttpServerPropertiesImpl::ClearAlternateProtocol( | 375 void HttpServerPropertiesImpl::ClearAlternateProtocol( |
367 const HostPortPair& server) { | 376 const HostPortPair& server) { |
377 RemoveCanonicalHost(server); | |
378 | |
368 AlternateProtocolMap::iterator it = alternate_protocol_map_.Peek(server); | 379 AlternateProtocolMap::iterator it = alternate_protocol_map_.Peek(server); |
369 if (it != alternate_protocol_map_.end()) | 380 if (it == alternate_protocol_map_.end()) { |
370 alternate_protocol_map_.Erase(it); | 381 return; |
382 } | |
383 const AlternativeService alternative_service( | |
384 it->second.protocol, it->first.host(), it->second.port); | |
385 alternate_protocol_map_.Erase(it); | |
371 | 386 |
372 RemoveCanonicalHost(server); | 387 // The following is temporary to keep the existing semantics, which is that if |
388 // there is a broken alternative service in the mapping, then this method | |
389 // leaves it in a non-broken, but recently broken state. | |
390 // | |
391 // TODO(bnc): | |
392 // 1. Verify and document the class invariant that no broken alternative | |
393 // service can be in the mapping. | |
394 // 2. Remove the rest of this method as it will be moot. | |
395 // 3. Provide a SetAlternativeServiceRecentlyBroken if necessary. | |
396 ignore_result(broken_alternative_services_.erase(alternative_service)); | |
373 } | 397 } |
374 | 398 |
375 const AlternateProtocolMap& | 399 const AlternateProtocolMap& |
376 HttpServerPropertiesImpl::alternate_protocol_map() const { | 400 HttpServerPropertiesImpl::alternate_protocol_map() const { |
377 return alternate_protocol_map_; | 401 return alternate_protocol_map_; |
378 } | 402 } |
379 | 403 |
380 const SettingsMap& HttpServerPropertiesImpl::GetSpdySettings( | 404 const SettingsMap& HttpServerPropertiesImpl::GetSpdySettings( |
381 const HostPortPair& host_port_pair) { | 405 const HostPortPair& host_port_pair) { |
382 SpdySettingsMap::iterator it = spdy_settings_map_.Get(host_port_pair); | 406 SpdySettingsMap::iterator it = spdy_settings_map_.Get(host_port_pair); |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
534 base::TimeDelta delay = when > now ? when - now : base::TimeDelta(); | 558 base::TimeDelta delay = when > now ? when - now : base::TimeDelta(); |
535 base::MessageLoop::current()->PostDelayedTask( | 559 base::MessageLoop::current()->PostDelayedTask( |
536 FROM_HERE, | 560 FROM_HERE, |
537 base::Bind( | 561 base::Bind( |
538 &HttpServerPropertiesImpl::ExpireBrokenAlternateProtocolMappings, | 562 &HttpServerPropertiesImpl::ExpireBrokenAlternateProtocolMappings, |
539 weak_ptr_factory_.GetWeakPtr()), | 563 weak_ptr_factory_.GetWeakPtr()), |
540 delay); | 564 delay); |
541 } | 565 } |
542 | 566 |
543 } // namespace net | 567 } // namespace net |
OLD | NEW |