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 |