| 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 160 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 171 const HostPortPair& host_port_pair) { | 171 const HostPortPair& host_port_pair) { |
| 172 DCHECK(CalledOnValidThread()); | 172 DCHECK(CalledOnValidThread()); |
| 173 if (host_port_pair.host().empty()) | 173 if (host_port_pair.host().empty()) |
| 174 return false; | 174 return false; |
| 175 | 175 |
| 176 SpdyServerHostPortMap::iterator spdy_host_port = | 176 SpdyServerHostPortMap::iterator spdy_host_port = |
| 177 spdy_servers_map_.Get(host_port_pair.ToString()); | 177 spdy_servers_map_.Get(host_port_pair.ToString()); |
| 178 if (spdy_host_port != spdy_servers_map_.end() && spdy_host_port->second) | 178 if (spdy_host_port != spdy_servers_map_.end() && spdy_host_port->second) |
| 179 return true; | 179 return true; |
| 180 | 180 |
| 181 const AlternateProtocolInfo info = GetAlternateProtocol(host_port_pair); | 181 const AlternativeService alternative_service = |
| 182 return info.protocol == QUIC; | 182 GetAlternativeService(host_port_pair); |
| 183 return alternative_service.protocol == QUIC; |
| 183 } | 184 } |
| 184 | 185 |
| 185 void HttpServerPropertiesImpl::SetSupportsSpdy( | 186 void HttpServerPropertiesImpl::SetSupportsSpdy( |
| 186 const HostPortPair& host_port_pair, | 187 const HostPortPair& host_port_pair, |
| 187 bool support_spdy) { | 188 bool support_spdy) { |
| 188 DCHECK(CalledOnValidThread()); | 189 DCHECK(CalledOnValidThread()); |
| 189 if (host_port_pair.host().empty()) | 190 if (host_port_pair.host().empty()) |
| 190 return; | 191 return; |
| 191 | 192 |
| 192 SpdyServerHostPortMap::iterator spdy_host_port = | 193 SpdyServerHostPortMap::iterator spdy_host_port = |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 230 // suffix. | 231 // suffix. |
| 231 for (size_t i = 0; i < canonical_suffixes_.size(); ++i) { | 232 for (size_t i = 0; i < canonical_suffixes_.size(); ++i) { |
| 232 std::string canonical_suffix = canonical_suffixes_[i]; | 233 std::string canonical_suffix = canonical_suffixes_[i]; |
| 233 if (EndsWith(host, canonical_suffixes_[i], false)) { | 234 if (EndsWith(host, canonical_suffixes_[i], false)) { |
| 234 return canonical_suffix; | 235 return canonical_suffix; |
| 235 } | 236 } |
| 236 } | 237 } |
| 237 return std::string(); | 238 return std::string(); |
| 238 } | 239 } |
| 239 | 240 |
| 240 AlternateProtocolInfo HttpServerPropertiesImpl::GetAlternateProtocol( | 241 AlternativeService HttpServerPropertiesImpl::GetAlternativeService( |
| 241 const HostPortPair& server) { | 242 const HostPortPair& origin) { |
| 242 AlternateProtocolMap::const_iterator it = | 243 AlternateProtocolMap::const_iterator it = |
| 243 GetAlternateProtocolIterator(server); | 244 GetAlternateProtocolIterator(origin); |
| 244 if (it != alternate_protocol_map_.end() && | 245 if (it != alternate_protocol_map_.end() && |
| 245 it->second.probability >= alternate_protocol_probability_threshold_) | 246 it->second.probability >= alternate_protocol_probability_threshold_) |
| 246 return it->second; | 247 return AlternativeService(it->second.protocol, origin.host(), |
| 248 it->second.port); |
| 247 | 249 |
| 248 if (g_forced_alternate_protocol) | 250 if (g_forced_alternate_protocol) |
| 249 return *g_forced_alternate_protocol; | 251 return AlternativeService(g_forced_alternate_protocol->protocol, |
| 252 origin.host(), g_forced_alternate_protocol->port); |
| 250 | 253 |
| 251 AlternateProtocolInfo uninitialized_alternate_protocol; | 254 AlternativeService uninitialize_alternative_service; |
| 252 return uninitialized_alternate_protocol; | 255 return uninitialize_alternative_service; |
| 253 } | 256 } |
| 254 | 257 |
| 255 void HttpServerPropertiesImpl::SetAlternateProtocol( | 258 void HttpServerPropertiesImpl::SetAlternateProtocol( |
| 256 const HostPortPair& server, | 259 const HostPortPair& origin, |
| 257 uint16 alternate_port, | 260 uint16 alternate_port, |
| 258 AlternateProtocol alternate_protocol, | 261 AlternateProtocol alternate_protocol, |
| 259 double alternate_probability) { | 262 double alternate_probability) { |
| 260 const AlternativeService alternative_service(alternate_protocol, | 263 const AlternativeService alternative_service(alternate_protocol, |
| 261 server.host(), alternate_port); | 264 origin.host(), alternate_port); |
| 262 if (IsAlternativeServiceBroken(alternative_service)) { | 265 if (IsAlternativeServiceBroken(alternative_service)) { |
| 263 DVLOG(1) << "Ignore alternative service since it is known to be broken."; | 266 DVLOG(1) << "Ignore alternative service since it is known to be broken."; |
| 264 return; | 267 return; |
| 265 } | 268 } |
| 266 | 269 |
| 267 const AlternateProtocolInfo alternate(alternate_port, alternate_protocol, | 270 const AlternateProtocolInfo alternate(alternate_port, alternate_protocol, |
| 268 alternate_probability); | 271 alternate_probability); |
| 269 AlternateProtocolMap::const_iterator it = | 272 AlternateProtocolMap::const_iterator it = |
| 270 GetAlternateProtocolIterator(server); | 273 GetAlternateProtocolIterator(origin); |
| 271 if (it != alternate_protocol_map_.end()) { | 274 if (it != alternate_protocol_map_.end()) { |
| 272 const AlternateProtocolInfo existing_alternate = it->second; | 275 const AlternateProtocolInfo existing_alternate = it->second; |
| 273 | 276 |
| 274 if (!existing_alternate.Equals(alternate)) { | 277 if (!existing_alternate.Equals(alternate)) { |
| 275 LOG(WARNING) << "Changing the alternate protocol for: " | 278 LOG(WARNING) << "Changing the alternate protocol for: " |
| 276 << server.ToString() | 279 << origin.ToString() |
| 277 << " from [Port: " << existing_alternate.port | 280 << " from [Port: " << existing_alternate.port |
| 278 << ", Protocol: " << existing_alternate.protocol | 281 << ", Protocol: " << existing_alternate.protocol |
| 279 << ", Probability: " << existing_alternate.probability | 282 << ", Probability: " << existing_alternate.probability |
| 280 << "] to [Port: " << alternate_port | 283 << "] to [Port: " << alternate_port |
| 281 << ", Protocol: " << alternate_protocol | 284 << ", Protocol: " << alternate_protocol |
| 282 << ", Probability: " << alternate_probability | 285 << ", Probability: " << alternate_probability << "]."; |
| 283 << "]."; | |
| 284 } | 286 } |
| 285 } else { | 287 } else { |
| 286 if (alternate_probability >= alternate_protocol_probability_threshold_) { | 288 if (alternate_probability >= alternate_protocol_probability_threshold_) { |
| 287 // TODO(rch): Consider the case where multiple requests are started | 289 // TODO(rch): Consider the case where multiple requests are started |
| 288 // before the first completes. In this case, only one of the jobs | 290 // before the first completes. In this case, only one of the jobs |
| 289 // would reach this code, whereas all of them should should have. | 291 // would reach this code, whereas all of them should should have. |
| 290 HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_MAPPING_MISSING); | 292 HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_MAPPING_MISSING); |
| 291 } | 293 } |
| 292 } | 294 } |
| 293 | 295 |
| 294 alternate_protocol_map_.Put(server, alternate); | 296 alternate_protocol_map_.Put(origin, alternate); |
| 295 | 297 |
| 296 // If this host ends with a canonical suffix, then set it as the | 298 // If this host ends with a canonical suffix, then set it as the |
| 297 // canonical host. | 299 // canonical host. |
| 298 for (size_t i = 0; i < canonical_suffixes_.size(); ++i) { | 300 for (size_t i = 0; i < canonical_suffixes_.size(); ++i) { |
| 299 std::string canonical_suffix = canonical_suffixes_[i]; | 301 std::string canonical_suffix = canonical_suffixes_[i]; |
| 300 if (EndsWith(server.host(), canonical_suffixes_[i], false)) { | 302 if (EndsWith(origin.host(), canonical_suffixes_[i], false)) { |
| 301 HostPortPair canonical_host(canonical_suffix, server.port()); | 303 HostPortPair canonical_host(canonical_suffix, origin.port()); |
| 302 canonical_host_to_origin_map_[canonical_host] = server; | 304 canonical_host_to_origin_map_[canonical_host] = origin; |
| 303 break; | 305 break; |
| 304 } | 306 } |
| 305 } | 307 } |
| 306 } | 308 } |
| 307 | 309 |
| 308 void HttpServerPropertiesImpl::SetBrokenAlternateProtocol( | 310 void HttpServerPropertiesImpl::SetBrokenAlternateProtocol( |
| 309 const HostPortPair& server) { | 311 const HostPortPair& origin) { |
| 310 const AlternateProtocolInfo alternate = GetAlternateProtocol(server); | 312 const AlternativeService alternative_service = GetAlternativeService(origin); |
| 311 if (alternate.protocol == UNINITIALIZED_ALTERNATE_PROTOCOL) { | 313 if (alternative_service.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 const AlternativeService alternative_service(alternate.protocol, | |
| 316 server.host(), alternate.port); | |
| 317 int count = ++recently_broken_alternative_services_[alternative_service]; | 317 int count = ++recently_broken_alternative_services_[alternative_service]; |
| 318 base::TimeDelta delay = | 318 base::TimeDelta delay = |
| 319 base::TimeDelta::FromSeconds(kBrokenAlternateProtocolDelaySecs); | 319 base::TimeDelta::FromSeconds(kBrokenAlternateProtocolDelaySecs); |
| 320 base::TimeTicks when = base::TimeTicks::Now() + delay * (1 << (count - 1)); | 320 base::TimeTicks when = base::TimeTicks::Now() + delay * (1 << (count - 1)); |
| 321 auto result = broken_alternative_services_.insert( | 321 auto result = broken_alternative_services_.insert( |
| 322 std::make_pair(alternative_service, when)); | 322 std::make_pair(alternative_service, when)); |
| 323 // Return if alternative service is already in expiration queue. | 323 // Return if alternative service is already in expiration queue. |
| 324 if (!result.second) { | 324 if (!result.second) { |
| 325 return; | 325 return; |
| 326 } | 326 } |
| 327 | 327 |
| 328 // Do not leave this host as canonical so that we don't infer the other | 328 // Do not leave this host as canonical so that we don't infer the other |
| 329 // hosts are also broken without testing them first. | 329 // hosts are also broken without testing them first. |
| 330 RemoveCanonicalHost(server); | 330 RemoveCanonicalHost(origin); |
| 331 | 331 |
| 332 // If this is the only entry in the list, schedule an expiration task. | 332 // If this is the only entry in the list, schedule an expiration task. |
| 333 // Otherwise it will be rescheduled automatically when the pending task runs. | 333 // Otherwise it will be rescheduled automatically when the pending task runs. |
| 334 if (broken_alternative_services_.size() == 1) { | 334 if (broken_alternative_services_.size() == 1) { |
| 335 ScheduleBrokenAlternateProtocolMappingsExpiration(); | 335 ScheduleBrokenAlternateProtocolMappingsExpiration(); |
| 336 } | 336 } |
| 337 } | 337 } |
| 338 | 338 |
| 339 void HttpServerPropertiesImpl::MarkAlternativeServiceRecentlyBroken( | 339 void HttpServerPropertiesImpl::MarkAlternativeServiceRecentlyBroken( |
| 340 const AlternativeService& alternative_service) { | 340 const AlternativeService& alternative_service) { |
| 341 if (!ContainsKey(recently_broken_alternative_services_, alternative_service)) | 341 if (!ContainsKey(recently_broken_alternative_services_, alternative_service)) |
| 342 recently_broken_alternative_services_[alternative_service] = 1; | 342 recently_broken_alternative_services_[alternative_service] = 1; |
| 343 } | 343 } |
| 344 | 344 |
| 345 bool HttpServerPropertiesImpl::IsAlternativeServiceBroken( | 345 bool HttpServerPropertiesImpl::IsAlternativeServiceBroken( |
| 346 const AlternativeService& alternative_service) { | 346 const AlternativeService& alternative_service) { |
| 347 return ContainsKey(broken_alternative_services_, alternative_service); | 347 return ContainsKey(broken_alternative_services_, alternative_service); |
| 348 } | 348 } |
| 349 | 349 |
| 350 bool HttpServerPropertiesImpl::WasAlternateProtocolRecentlyBroken( | 350 bool HttpServerPropertiesImpl::WasAlternateProtocolRecentlyBroken( |
| 351 const HostPortPair& server) { | 351 const HostPortPair& origin) { |
| 352 const AlternateProtocolInfo alternate_protocol = GetAlternateProtocol(server); | 352 const AlternativeService alternative_service = GetAlternativeService(origin); |
| 353 if (alternate_protocol.protocol == UNINITIALIZED_ALTERNATE_PROTOCOL) | 353 if (alternative_service.protocol == UNINITIALIZED_ALTERNATE_PROTOCOL) |
| 354 return false; | 354 return false; |
| 355 const AlternativeService alternative_service( | |
| 356 alternate_protocol.protocol, server.host(), alternate_protocol.port); | |
| 357 return ContainsKey(recently_broken_alternative_services_, | 355 return ContainsKey(recently_broken_alternative_services_, |
| 358 alternative_service); | 356 alternative_service); |
| 359 } | 357 } |
| 360 | 358 |
| 361 void HttpServerPropertiesImpl::ConfirmAlternateProtocol( | 359 void HttpServerPropertiesImpl::ConfirmAlternateProtocol( |
| 362 const HostPortPair& server) { | 360 const HostPortPair& origin) { |
| 363 const AlternateProtocolInfo alternate_protocol = GetAlternateProtocol(server); | 361 const AlternativeService alternative_service = GetAlternativeService(origin); |
| 364 if (alternate_protocol.protocol == UNINITIALIZED_ALTERNATE_PROTOCOL) | 362 if (alternative_service.protocol == UNINITIALIZED_ALTERNATE_PROTOCOL) |
| 365 return; | 363 return; |
| 366 const AlternativeService alternative_service( | |
| 367 alternate_protocol.protocol, server.host(), alternate_protocol.port); | |
| 368 broken_alternative_services_.erase(alternative_service); | 364 broken_alternative_services_.erase(alternative_service); |
| 369 recently_broken_alternative_services_.erase(alternative_service); | 365 recently_broken_alternative_services_.erase(alternative_service); |
| 370 } | 366 } |
| 371 | 367 |
| 372 void HttpServerPropertiesImpl::ClearAlternateProtocol( | 368 void HttpServerPropertiesImpl::ClearAlternateProtocol( |
| 373 const HostPortPair& server) { | 369 const HostPortPair& origin) { |
| 374 RemoveCanonicalHost(server); | 370 RemoveCanonicalHost(origin); |
| 375 | 371 |
| 376 AlternateProtocolMap::iterator it = alternate_protocol_map_.Peek(server); | 372 AlternateProtocolMap::iterator it = alternate_protocol_map_.Peek(origin); |
| 377 if (it == alternate_protocol_map_.end()) { | 373 if (it == alternate_protocol_map_.end()) { |
| 378 return; | 374 return; |
| 379 } | 375 } |
| 380 const AlternativeService alternative_service( | 376 const AlternativeService alternative_service( |
| 381 it->second.protocol, it->first.host(), it->second.port); | 377 it->second.protocol, it->first.host(), it->second.port); |
| 382 alternate_protocol_map_.Erase(it); | 378 alternate_protocol_map_.Erase(it); |
| 383 | 379 |
| 384 // The following is temporary to keep the existing semantics, which is that if | 380 // The following is temporary to keep the existing semantics, which is that if |
| 385 // there is a broken alternative service in the mapping, then this method | 381 // there is a broken alternative service in the mapping, then this method |
| 386 // leaves it in a non-broken, but recently broken state. | 382 // leaves it in a non-broken, but recently broken state. |
| (...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 555 base::TimeDelta delay = when > now ? when - now : base::TimeDelta(); | 551 base::TimeDelta delay = when > now ? when - now : base::TimeDelta(); |
| 556 base::MessageLoop::current()->PostDelayedTask( | 552 base::MessageLoop::current()->PostDelayedTask( |
| 557 FROM_HERE, | 553 FROM_HERE, |
| 558 base::Bind( | 554 base::Bind( |
| 559 &HttpServerPropertiesImpl::ExpireBrokenAlternateProtocolMappings, | 555 &HttpServerPropertiesImpl::ExpireBrokenAlternateProtocolMappings, |
| 560 weak_ptr_factory_.GetWeakPtr()), | 556 weak_ptr_factory_.GetWeakPtr()), |
| 561 delay); | 557 delay); |
| 562 } | 558 } |
| 563 | 559 |
| 564 } // namespace net | 560 } // namespace net |
| OLD | NEW |