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