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 ContainsKey(broken_alternative_services_, alternative_service); |
| 349 } |
| 350 |
345 bool HttpServerPropertiesImpl::WasAlternateProtocolRecentlyBroken( | 351 bool HttpServerPropertiesImpl::WasAlternateProtocolRecentlyBroken( |
346 const HostPortPair& server) { | 352 const HostPortPair& server) { |
347 const AlternateProtocolInfo alternate_protocol = GetAlternateProtocol(server); | 353 const AlternateProtocolInfo alternate_protocol = GetAlternateProtocol(server); |
348 if (alternate_protocol.protocol == UNINITIALIZED_ALTERNATE_PROTOCOL) | 354 if (alternate_protocol.protocol == UNINITIALIZED_ALTERNATE_PROTOCOL) |
349 return false; | 355 return false; |
350 const AlternativeService alternative_service( | 356 const AlternativeService alternative_service( |
351 alternate_protocol.protocol, server.host(), alternate_protocol.port); | 357 alternate_protocol.protocol, server.host(), alternate_protocol.port); |
352 return ContainsKey(recently_broken_alternative_services_, | 358 return ContainsKey(recently_broken_alternative_services_, |
353 alternative_service); | 359 alternative_service); |
354 } | 360 } |
355 | 361 |
356 void HttpServerPropertiesImpl::ConfirmAlternateProtocol( | 362 void HttpServerPropertiesImpl::ConfirmAlternateProtocol( |
357 const HostPortPair& server) { | 363 const HostPortPair& server) { |
358 const AlternateProtocolInfo alternate_protocol = GetAlternateProtocol(server); | 364 const AlternateProtocolInfo alternate_protocol = GetAlternateProtocol(server); |
359 if (alternate_protocol.protocol == UNINITIALIZED_ALTERNATE_PROTOCOL) | 365 if (alternate_protocol.protocol == UNINITIALIZED_ALTERNATE_PROTOCOL) |
360 return; | 366 return; |
361 const AlternativeService alternative_service( | 367 const AlternativeService alternative_service( |
362 alternate_protocol.protocol, server.host(), alternate_protocol.port); | 368 alternate_protocol.protocol, server.host(), alternate_protocol.port); |
| 369 broken_alternative_services_.erase(alternative_service); |
363 recently_broken_alternative_services_.erase(alternative_service); | 370 recently_broken_alternative_services_.erase(alternative_service); |
364 } | 371 } |
365 | 372 |
366 void HttpServerPropertiesImpl::ClearAlternateProtocol( | 373 void HttpServerPropertiesImpl::ClearAlternateProtocol( |
367 const HostPortPair& server) { | 374 const HostPortPair& server) { |
| 375 RemoveCanonicalHost(server); |
| 376 |
368 AlternateProtocolMap::iterator it = alternate_protocol_map_.Peek(server); | 377 AlternateProtocolMap::iterator it = alternate_protocol_map_.Peek(server); |
369 if (it != alternate_protocol_map_.end()) | 378 if (it == alternate_protocol_map_.end()) { |
370 alternate_protocol_map_.Erase(it); | 379 return; |
| 380 } |
| 381 const AlternativeService alternative_service( |
| 382 it->second.protocol, it->first.host(), it->second.port); |
| 383 alternate_protocol_map_.Erase(it); |
371 | 384 |
372 RemoveCanonicalHost(server); | 385 // The following is temporary to keep the existing semantics, which is that if |
| 386 // there is a broken alternative service in the mapping, then this method |
| 387 // leaves it in a non-broken, but recently broken state. |
| 388 // |
| 389 // TODO(bnc): |
| 390 // 1. Verify and document the class invariant that no broken alternative |
| 391 // service can be in the mapping. |
| 392 // 2. Remove the rest of this method as it will be moot. |
| 393 // 3. Provide a SetAlternativeServiceRecentlyBroken if necessary. |
| 394 ignore_result(broken_alternative_services_.erase(alternative_service)); |
373 } | 395 } |
374 | 396 |
375 const AlternateProtocolMap& | 397 const AlternateProtocolMap& |
376 HttpServerPropertiesImpl::alternate_protocol_map() const { | 398 HttpServerPropertiesImpl::alternate_protocol_map() const { |
377 return alternate_protocol_map_; | 399 return alternate_protocol_map_; |
378 } | 400 } |
379 | 401 |
380 const SettingsMap& HttpServerPropertiesImpl::GetSpdySettings( | 402 const SettingsMap& HttpServerPropertiesImpl::GetSpdySettings( |
381 const HostPortPair& host_port_pair) { | 403 const HostPortPair& host_port_pair) { |
382 SpdySettingsMap::iterator it = spdy_settings_map_.Get(host_port_pair); | 404 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(); | 556 base::TimeDelta delay = when > now ? when - now : base::TimeDelta(); |
535 base::MessageLoop::current()->PostDelayedTask( | 557 base::MessageLoop::current()->PostDelayedTask( |
536 FROM_HERE, | 558 FROM_HERE, |
537 base::Bind( | 559 base::Bind( |
538 &HttpServerPropertiesImpl::ExpireBrokenAlternateProtocolMappings, | 560 &HttpServerPropertiesImpl::ExpireBrokenAlternateProtocolMappings, |
539 weak_ptr_factory_.GetWeakPtr()), | 561 weak_ptr_factory_.GetWeakPtr()), |
540 delay); | 562 delay); |
541 } | 563 } |
542 | 564 |
543 } // namespace net | 565 } // namespace net |
OLD | NEW |