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 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
42 return; | 42 return; |
43 // Add the entries from persisted data. | 43 // Add the entries from persisted data. |
44 for (std::vector<std::string>::reverse_iterator it = spdy_servers->rbegin(); | 44 for (std::vector<std::string>::reverse_iterator it = spdy_servers->rbegin(); |
45 it != spdy_servers->rend(); ++it) { | 45 it != spdy_servers->rend(); ++it) { |
46 spdy_servers_map_.Put(*it, support_spdy); | 46 spdy_servers_map_.Put(*it, support_spdy); |
47 } | 47 } |
48 } | 48 } |
49 | 49 |
50 void HttpServerPropertiesImpl::InitializeAlternateProtocolServers( | 50 void HttpServerPropertiesImpl::InitializeAlternateProtocolServers( |
51 AlternateProtocolMap* alternate_protocol_map) { | 51 AlternateProtocolMap* alternate_protocol_map) { |
52 // Keep all the ALTERNATE_PROTOCOL_BROKEN ones since those don't | 52 // Keep all the ALTERNATE_PROTOCOL_BROKEN ones since those don't get |
53 // get persisted. | 53 // persisted. |
Ryan Hamilton
2014/11/03 19:00:30
I think you might want to move this to the second
Bence
2014/11/03 22:32:26
Done.
| |
54 for (AlternateProtocolMap::iterator it = alternate_protocol_map_.begin(); | 54 for (AlternateProtocolMap::iterator alternate_protocols = |
55 it != alternate_protocol_map_.end();) { | 55 alternate_protocol_map_.begin(); |
56 AlternateProtocolMap::iterator old_it = it; | 56 alternate_protocols != alternate_protocol_map_.end();) { |
57 ++it; | 57 for (AlternateProtocols::iterator it = alternate_protocols->second.begin(); |
58 if (old_it->second.protocol != ALTERNATE_PROTOCOL_BROKEN) { | 58 it != alternate_protocols->second.end();) { |
59 alternate_protocol_map_.Erase(old_it); | 59 if (it->protocol != ALTERNATE_PROTOCOL_BROKEN) { |
60 it = alternate_protocols->second.erase(it); | |
61 } else { | |
62 ++it; | |
63 } | |
64 } | |
65 if (alternate_protocols->second.size() == 0) { | |
66 alternate_protocols = alternate_protocol_map_.Erase(alternate_protocols); | |
67 } else { | |
68 ++alternate_protocols; | |
60 } | 69 } |
61 } | 70 } |
62 | 71 |
63 // Add the entries from persisted data. | 72 // Add the entries from persisted data. |
64 for (AlternateProtocolMap::reverse_iterator it = | 73 for (AlternateProtocolMap::reverse_iterator it = |
65 alternate_protocol_map->rbegin(); | 74 alternate_protocol_map->rbegin(); |
66 it != alternate_protocol_map->rend(); ++it) { | 75 it != alternate_protocol_map->rend(); ++it) { |
67 alternate_protocol_map_.Put(it->first, it->second); | 76 alternate_protocol_map_.Put(it->first, it->second); |
68 } | 77 } |
69 | 78 |
(...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
197 return; | 206 return; |
198 } | 207 } |
199 // Cache the data. | 208 // Cache the data. |
200 spdy_servers_map_.Put(spdy_server, support_spdy); | 209 spdy_servers_map_.Put(spdy_server, support_spdy); |
201 } | 210 } |
202 | 211 |
203 bool HttpServerPropertiesImpl::HasAlternateProtocol( | 212 bool HttpServerPropertiesImpl::HasAlternateProtocol( |
204 const HostPortPair& server) { | 213 const HostPortPair& server) { |
205 if (g_forced_alternate_protocol) | 214 if (g_forced_alternate_protocol) |
206 return true; | 215 return true; |
207 AlternateProtocolMap::const_iterator it = alternate_protocol_map_.Get(server); | 216 AlternateProtocolMap::const_iterator alternate_protocols = |
208 if (it != alternate_protocol_map_.end() && | 217 alternate_protocol_map_.Get(server); |
209 it->second.probability >= alternate_protocol_probability_threshold_) { | 218 if (alternate_protocols != alternate_protocol_map_.end()) { |
210 return true; | 219 for (AlternateProtocols::const_iterator alternate_protocol = |
220 alternate_protocols->second.begin(); | |
221 alternate_protocol != alternate_protocols->second.end(); | |
222 alternate_protocol++) { | |
223 if (alternate_protocol->probability >= | |
224 alternate_protocol_probability_threshold_) { | |
225 return true; | |
226 } | |
227 } | |
211 } | 228 } |
212 | 229 |
213 return GetCanonicalHost(server) != canonical_host_to_origin_map_.end(); | 230 return GetCanonicalHost(server) != canonical_host_to_origin_map_.end(); |
214 } | 231 } |
215 | 232 |
216 std::string HttpServerPropertiesImpl::GetCanonicalSuffix( | 233 std::string HttpServerPropertiesImpl::GetCanonicalSuffix( |
217 const HostPortPair& server) { | 234 const HostPortPair& server) { |
218 // If this host ends with a canonical suffix, then return the canonical | 235 // If this host ends with a canonical suffix, then return the canonical |
219 // suffix. | 236 // suffix. |
220 for (size_t i = 0; i < canonical_suffixes_.size(); ++i) { | 237 for (size_t i = 0; i < canonical_suffixes_.size(); ++i) { |
221 std::string canonical_suffix = canonical_suffixes_[i]; | 238 std::string canonical_suffix = canonical_suffixes_[i]; |
222 if (EndsWith(server.host(), canonical_suffixes_[i], false)) { | 239 if (EndsWith(server.host(), canonical_suffixes_[i], false)) { |
223 return canonical_suffix; | 240 return canonical_suffix; |
224 } | 241 } |
225 } | 242 } |
226 return std::string(); | 243 return std::string(); |
227 } | 244 } |
228 | 245 |
229 AlternateProtocolInfo | 246 AlternateProtocols HttpServerPropertiesImpl::GetAlternateProtocol( |
230 HttpServerPropertiesImpl::GetAlternateProtocol( | |
231 const HostPortPair& server) { | 247 const HostPortPair& server) { |
232 DCHECK(HasAlternateProtocol(server)); | 248 DCHECK(HasAlternateProtocol(server)); |
233 | 249 |
234 // First check the map. | 250 // First check the map. |
235 AlternateProtocolMap::iterator it = alternate_protocol_map_.Get(server); | 251 AlternateProtocolMap::iterator it = alternate_protocol_map_.Get(server); |
236 if (it != alternate_protocol_map_.end()) | 252 if (it != alternate_protocol_map_.end()) |
237 return it->second; | 253 return it->second; |
238 | 254 |
239 // Next check the canonical host. | 255 // Next check the canonical host. |
240 CanonicalHostMap::const_iterator canonical_host = GetCanonicalHost(server); | 256 CanonicalHostMap::const_iterator canonical_host = GetCanonicalHost(server); |
241 if (canonical_host != canonical_host_to_origin_map_.end()) | 257 if (canonical_host != canonical_host_to_origin_map_.end()) |
242 return alternate_protocol_map_.Get(canonical_host->second)->second; | 258 return alternate_protocol_map_.Get(canonical_host->second)->second; |
243 | 259 |
244 // We must be forcing an alternate. | 260 // We must be forcing an alternate. |
245 DCHECK(g_forced_alternate_protocol); | 261 DCHECK(g_forced_alternate_protocol); |
246 return *g_forced_alternate_protocol; | 262 return AlternateProtocols(/* size = */ 1, |
Ryan Hamilton
2014/11/03 19:00:30
I'm familiar wit this convention of "naming" liter
Bence
2014/11/03 22:32:26
Done.
| |
263 /* val = */ *g_forced_alternate_protocol); | |
Ryan Hamilton
2014/11/03 19:00:30
Since the variable already has a readable name, I
Bence
2014/11/03 22:32:26
Done.
| |
247 } | 264 } |
248 | 265 |
249 void HttpServerPropertiesImpl::SetAlternateProtocol( | 266 void HttpServerPropertiesImpl::AddAlternateProtocol( |
250 const HostPortPair& server, | 267 const HostPortPair& server, |
251 uint16 alternate_port, | 268 uint16 alternate_port, |
252 AlternateProtocol alternate_protocol, | 269 AlternateProtocol alternate_protocol, |
253 double alternate_probability) { | 270 double alternate_probability) { |
254 if (alternate_protocol == ALTERNATE_PROTOCOL_BROKEN) { | 271 if (alternate_protocol == ALTERNATE_PROTOCOL_BROKEN) { |
255 LOG(DFATAL) << "Call SetBrokenAlternateProtocol() instead."; | 272 LOG(DFATAL) << "Call SetBrokenAlternateProtocol() instead."; |
256 return; | 273 return; |
257 } | 274 } |
258 | 275 |
259 AlternateProtocolInfo alternate(alternate_port, | 276 AlternateProtocolInfo alternate(alternate_port, |
260 alternate_protocol, | 277 alternate_protocol, |
261 alternate_probability); | 278 alternate_probability); |
262 if (HasAlternateProtocol(server)) { | 279 // Do not call HasAlternateProtocol(), because we don't care about |
263 const AlternateProtocolInfo existing_alternate = | 280 // |g_forced_alternate_protocol|, or whether the alternate protocol |
264 GetAlternateProtocol(server); | 281 // probability is higher than the threshold. |
265 | 282 AlternateProtocolMap::iterator map_it = alternate_protocol_map_.Get(server); |
266 if (existing_alternate.protocol == ALTERNATE_PROTOCOL_BROKEN) { | 283 if (map_it != alternate_protocol_map_.end()) { |
267 DVLOG(1) << "Ignore alternate protocol since it's known to be broken."; | 284 AlternateProtocols existing_alternates = map_it->second; |
268 return; | 285 AlternateProtocols::iterator it; |
286 for (it = existing_alternates.begin(); it != existing_alternates.end(); | |
287 ++it) { | |
288 if (it->EqualsModuloProbabilityAndProtocol(alternate)) { | |
Ryan Hamilton
2014/11/04 18:56:22
I don't think I understand why this is the right t
Bence
2014/11/04 21:55:50
Darn, you are right. The problem with the current
Ryan Hamilton
2014/11/04 22:13:17
s/broken_/is_broken_/ but yeah, this sounds great.
| |
289 break; | |
290 } | |
269 } | 291 } |
270 | 292 |
271 if (alternate_protocol != ALTERNATE_PROTOCOL_BROKEN && | 293 if (it != existing_alternates.end()) { |
272 !existing_alternate.Equals(alternate)) { | 294 if (it->protocol == ALTERNATE_PROTOCOL_BROKEN) { |
273 LOG(WARNING) << "Changing the alternate protocol for: " | 295 DVLOG(1) << "Ignore alternate protocol since it's known to be broken."; |
274 << server.ToString() | 296 return; |
275 << " from [Port: " << existing_alternate.port | 297 } |
276 << ", Protocol: " << existing_alternate.protocol | 298 if (it->probability != alternate_probability) { |
277 << ", Probability: " << existing_alternate.probability | 299 LOG(WARNING) << "Changing the probability of alternate protocol for: " |
278 << "] to [Port: " << alternate_port | 300 << server.ToString() |
279 << ", Protocol: " << alternate_protocol | 301 << " Port: " << it->port |
280 << ", Probability: " << alternate_probability | 302 << ", Protocol: " << it->protocol |
281 << "]."; | 303 << ", Probability from: " << it->probability |
304 << " to: " << alternate_probability << "."; | |
305 it->probability = alternate_probability; | |
306 } | |
307 } else { | |
308 existing_alternates.push_back(alternate); | |
282 } | 309 } |
310 | |
311 alternate_protocol_map_.Put(server, existing_alternates); | |
283 } else { | 312 } else { |
284 if (alternate_probability >= alternate_protocol_probability_threshold_) { | 313 if (alternate_probability >= alternate_protocol_probability_threshold_) { |
285 // TODO(rch): Consider the case where multiple requests are started | 314 // TODO(rch): Consider the case where multiple requests are started |
286 // before the first completes. In this case, only one of the jobs | 315 // before the first completes. In this case, only one of the jobs |
287 // would reach this code, whereas all of them should should have. | 316 // would reach this code, whereas all of them should should have. |
288 HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_MAPPING_MISSING); | 317 HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_MAPPING_MISSING); |
289 } | 318 } |
319 alternate_protocol_map_.Put( | |
320 server, AlternateProtocols(/* size = */ 1, /* val = */ alternate)); | |
290 } | 321 } |
291 | 322 |
292 alternate_protocol_map_.Put(server, alternate); | |
293 | |
294 // If this host ends with a canonical suffix, then set it as the | 323 // If this host ends with a canonical suffix, then set it as the |
295 // canonical host. | 324 // canonical host. |
296 for (size_t i = 0; i < canonical_suffixes_.size(); ++i) { | 325 for (size_t i = 0; i < canonical_suffixes_.size(); ++i) { |
297 std::string canonical_suffix = canonical_suffixes_[i]; | 326 std::string canonical_suffix = canonical_suffixes_[i]; |
298 if (EndsWith(server.host(), canonical_suffixes_[i], false)) { | 327 if (EndsWith(server.host(), canonical_suffixes_[i], false)) { |
299 HostPortPair canonical_host(canonical_suffix, server.port()); | 328 HostPortPair canonical_host(canonical_suffix, server.port()); |
300 canonical_host_to_origin_map_[canonical_host] = server; | 329 canonical_host_to_origin_map_[canonical_host] = server; |
301 break; | 330 break; |
302 } | 331 } |
303 } | 332 } |
304 } | 333 } |
305 | 334 |
306 void HttpServerPropertiesImpl::SetBrokenAlternateProtocol( | 335 void HttpServerPropertiesImpl::SetBrokenAlternateProtocol( |
307 const HostPortPair& server) { | 336 const HostPortPair& server, |
308 AlternateProtocolMap::iterator it = alternate_protocol_map_.Get(server); | 337 const AlternateProtocolInfo& broken_alternate_protocol) { |
309 if (it != alternate_protocol_map_.end()) { | 338 AddAlternateProtocol(server, |
310 it->second.protocol = ALTERNATE_PROTOCOL_BROKEN; | 339 broken_alternate_protocol.port, |
311 } else { | 340 broken_alternate_protocol.protocol, |
312 AlternateProtocolInfo alternate(server.port(), | 341 broken_alternate_protocol.probability); |
313 ALTERNATE_PROTOCOL_BROKEN, | 342 AlternateProtocolMap::iterator alternate_protocols = |
314 1); | 343 alternate_protocol_map_.Get(server); |
315 alternate_protocol_map_.Put(server, alternate); | 344 DCHECK(alternate_protocols != alternate_protocol_map_.end()); |
345 AlternateProtocols::iterator it; | |
346 for (it = alternate_protocols->second.begin(); | |
347 it != alternate_protocols->second.end(); | |
348 ++it) { | |
349 if (it->Equals(broken_alternate_protocol)) { | |
350 it->protocol = ALTERNATE_PROTOCOL_BROKEN; | |
351 break; | |
352 } | |
316 } | 353 } |
354 DCHECK(it != alternate_protocols->second.end()); | |
355 | |
317 int count = ++broken_alternate_protocol_map_[server]; | 356 int count = ++broken_alternate_protocol_map_[server]; |
318 base::TimeDelta delay = | 357 base::TimeDelta delay = |
319 base::TimeDelta::FromSeconds(kBrokenAlternateProtocolDelaySecs); | 358 base::TimeDelta::FromSeconds(kBrokenAlternateProtocolDelaySecs); |
320 BrokenAlternateProtocolEntry entry; | 359 BrokenAlternateProtocolEntry entry; |
321 entry.server = server; | 360 entry.server = server; |
322 entry.when = base::TimeTicks::Now() + delay * (1 << (count - 1)); | 361 entry.when = base::TimeTicks::Now() + delay * (1 << (count - 1)); |
323 broken_alternate_protocol_list_.push_back(entry); | 362 broken_alternate_protocol_list_.push_back(entry); |
324 | 363 |
325 // Do not leave this host as canonical so that we don't infer the other | 364 // Do not leave this host as canonical so that we don't infer the other hosts |
326 // hosts are also broken without testing them first. | 365 // are also broken without testing them first. |
327 RemoveCanonicalHost(server); | 366 RemoveCanonicalHost(server); |
328 | 367 |
329 // If this is the only entry in the list, schedule an expiration task. | 368 // If this is the only entry in the list, schedule an expiration task. |
330 // Otherwse it will be rescheduled automatically when the pending | 369 // Otherwise it will be rescheduled automatically when the pending task runs. |
331 // task runs. | |
332 if (broken_alternate_protocol_list_.size() == 1) { | 370 if (broken_alternate_protocol_list_.size() == 1) { |
333 ScheduleBrokenAlternateProtocolMappingsExpiration(); | 371 ScheduleBrokenAlternateProtocolMappingsExpiration(); |
334 } | 372 } |
335 } | 373 } |
336 | 374 |
337 bool HttpServerPropertiesImpl::WasAlternateProtocolRecentlyBroken( | 375 bool HttpServerPropertiesImpl::WasAlternateProtocolRecentlyBroken( |
338 const HostPortPair& server) { | 376 const HostPortPair& server, |
377 const AlternateProtocolInfo& alternate_protocol) { | |
339 return ContainsKey(broken_alternate_protocol_map_, server); | 378 return ContainsKey(broken_alternate_protocol_map_, server); |
340 } | 379 } |
341 | 380 |
342 void HttpServerPropertiesImpl::ConfirmAlternateProtocol( | 381 void HttpServerPropertiesImpl::ConfirmAlternateProtocol( |
343 const HostPortPair& server) { | 382 const HostPortPair& server, |
383 const AlternateProtocolInfo& alternate_protocol) { | |
344 broken_alternate_protocol_map_.erase(server); | 384 broken_alternate_protocol_map_.erase(server); |
345 } | 385 } |
346 | 386 |
347 void HttpServerPropertiesImpl::ClearAlternateProtocol( | 387 void HttpServerPropertiesImpl::ClearAlternateProtocol( |
348 const HostPortPair& server) { | 388 const HostPortPair& server) { |
349 AlternateProtocolMap::iterator it = alternate_protocol_map_.Peek(server); | 389 AlternateProtocolMap::iterator it = alternate_protocol_map_.Peek(server); |
350 if (it != alternate_protocol_map_.end()) | 390 if (it != alternate_protocol_map_.end()) { |
351 alternate_protocol_map_.Erase(it); | 391 alternate_protocol_map_.Erase(it); |
392 } | |
352 | 393 |
353 RemoveCanonicalHost(server); | 394 RemoveCanonicalHost(server); |
354 } | 395 } |
355 | 396 |
397 void HttpServerPropertiesImpl::RemoveAlternateProtocol( | |
398 const HostPortPair& server, | |
399 const AlternateProtocolInfo& alternate_protocol) { | |
400 AlternateProtocolMap::iterator alternate_protocols = | |
401 alternate_protocol_map_.Peek(server); | |
402 if (alternate_protocols == alternate_protocol_map_.end()) { | |
403 return; | |
404 } | |
405 for (AlternateProtocols::iterator it = alternate_protocols->second.begin(); | |
406 it != alternate_protocols->second.end();) { | |
407 if (it->Equals(alternate_protocol)) { | |
408 it = alternate_protocols->second.erase(it); | |
409 break; | |
410 } else { | |
411 ++it; | |
412 } | |
413 } | |
414 if (alternate_protocols->second.size() == 0) { | |
415 alternate_protocol_map_.Erase(alternate_protocols); | |
416 RemoveCanonicalHost(server); | |
417 } | |
418 } | |
419 | |
356 const AlternateProtocolMap& | 420 const AlternateProtocolMap& |
357 HttpServerPropertiesImpl::alternate_protocol_map() const { | 421 HttpServerPropertiesImpl::alternate_protocol_map() const { |
358 return alternate_protocol_map_; | 422 return alternate_protocol_map_; |
359 } | 423 } |
360 | 424 |
361 const SettingsMap& HttpServerPropertiesImpl::GetSpdySettings( | 425 const SettingsMap& HttpServerPropertiesImpl::GetSpdySettings( |
362 const HostPortPair& host_port_pair) { | 426 const HostPortPair& host_port_pair) { |
363 SpdySettingsMap::iterator it = spdy_settings_map_.Get(host_port_pair); | 427 SpdySettingsMap::iterator it = spdy_settings_map_.Get(host_port_pair); |
364 if (it == spdy_settings_map_.end()) { | 428 if (it == spdy_settings_map_.end()) { |
365 CR_DEFINE_STATIC_LOCAL(SettingsMap, kEmptySettingsMap, ()); | 429 CR_DEFINE_STATIC_LOCAL(SettingsMap, kEmptySettingsMap, ()); |
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
500 base::TimeDelta delay = when > now ? when - now : base::TimeDelta(); | 564 base::TimeDelta delay = when > now ? when - now : base::TimeDelta(); |
501 base::MessageLoop::current()->PostDelayedTask( | 565 base::MessageLoop::current()->PostDelayedTask( |
502 FROM_HERE, | 566 FROM_HERE, |
503 base::Bind( | 567 base::Bind( |
504 &HttpServerPropertiesImpl::ExpireBrokenAlternateProtocolMappings, | 568 &HttpServerPropertiesImpl::ExpireBrokenAlternateProtocolMappings, |
505 weak_ptr_factory_.GetWeakPtr()), | 569 weak_ptr_factory_.GetWeakPtr()), |
506 delay); | 570 delay); |
507 } | 571 } |
508 | 572 |
509 } // namespace net | 573 } // namespace net |
OLD | NEW |