Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(14)

Side by Side Diff: net/http/http_server_properties_impl.cc

Issue 665083009: ABANDONED Handle multiple AlternateProtocols for each HostPortPair. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Rebase. Created 5 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
43 return; 43 return;
44 // Add the entries from persisted data. 44 // Add the entries from persisted data.
45 for (std::vector<std::string>::reverse_iterator it = spdy_servers->rbegin(); 45 for (std::vector<std::string>::reverse_iterator it = spdy_servers->rbegin();
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 for (AlternateProtocolMap::iterator alternate_protocols =
54 for (AlternateProtocolMap::iterator it = alternate_protocol_map_.begin(); 54 alternate_protocol_map_.begin();
55 it != alternate_protocol_map_.end();) { 55 alternate_protocols != alternate_protocol_map_.end();) {
56 AlternateProtocolMap::iterator old_it = it; 56 // Keep all the broken ones since those don't get persisted.
57 ++it; 57 for (AlternateProtocols::iterator it = alternate_protocols->second.begin();
58 if (!old_it->second.is_broken) { 58 it != alternate_protocols->second.end();) {
59 alternate_protocol_map_.Erase(old_it); 59 if (!it->is_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 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
130 for (SpdyServerHostPortMap::const_iterator it = spdy_servers_map_.begin(); 139 for (SpdyServerHostPortMap::const_iterator it = spdy_servers_map_.begin();
131 it != spdy_servers_map_.end() && count < max_size; ++it) { 140 it != spdy_servers_map_.end() && count < max_size; ++it) {
132 const std::string spdy_server_host_port = it->first; 141 const std::string spdy_server_host_port = it->first;
133 if (it->second) { 142 if (it->second) {
134 spdy_server_list->Append(new base::StringValue(spdy_server_host_port)); 143 spdy_server_list->Append(new base::StringValue(spdy_server_host_port));
135 ++count; 144 ++count;
136 } 145 }
137 } 146 }
138 } 147 }
139 148
140 static const AlternateProtocolInfo* g_forced_alternate_protocol = NULL; 149 // static
150 std::string HttpServerPropertiesImpl::GetFlattenedSpdyServer(
151 const net::HostPortPair& host_port_pair) {
152 std::string spdy_server;
153 spdy_server.append(host_port_pair.host());
154 spdy_server.append(":");
155 base::StringAppendF(&spdy_server, "%d", host_port_pair.port());
156 return spdy_server;
157 }
158
159 static AlternateProtocols* g_forced_alternate_protocol =
160 new AlternateProtocols();
141 161
142 // static 162 // static
143 void HttpServerPropertiesImpl::ForceAlternateProtocol( 163 void HttpServerPropertiesImpl::ForceAlternateProtocol(
144 const AlternateProtocolInfo& info) { 164 const AlternateProtocolInfo& info) {
165 DisableForcedAlternateProtocol();
145 // Note: we're going to leak this. 166 // Note: we're going to leak this.
146 if (g_forced_alternate_protocol) 167 g_forced_alternate_protocol->push_back(info);
147 delete g_forced_alternate_protocol;
148 g_forced_alternate_protocol = new AlternateProtocolInfo(info);
149 } 168 }
150 169
151 // static 170 // static
152 void HttpServerPropertiesImpl::DisableForcedAlternateProtocol() { 171 void HttpServerPropertiesImpl::DisableForcedAlternateProtocol() {
153 delete g_forced_alternate_protocol; 172 g_forced_alternate_protocol->clear();
154 g_forced_alternate_protocol = NULL;
155 } 173 }
156 174
157 base::WeakPtr<HttpServerProperties> HttpServerPropertiesImpl::GetWeakPtr() { 175 base::WeakPtr<HttpServerProperties> HttpServerPropertiesImpl::GetWeakPtr() {
158 return weak_ptr_factory_.GetWeakPtr(); 176 return weak_ptr_factory_.GetWeakPtr();
159 } 177 }
160 178
161 void HttpServerPropertiesImpl::Clear() { 179 void HttpServerPropertiesImpl::Clear() {
162 DCHECK(CalledOnValidThread()); 180 DCHECK(CalledOnValidThread());
163 spdy_servers_map_.Clear(); 181 spdy_servers_map_.Clear();
164 alternate_protocol_map_.Clear(); 182 alternate_protocol_map_.Clear();
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
218 236
219 void HttpServerPropertiesImpl::MaybeForceHTTP11(const HostPortPair& server, 237 void HttpServerPropertiesImpl::MaybeForceHTTP11(const HostPortPair& server,
220 SSLConfig* ssl_config) { 238 SSLConfig* ssl_config) {
221 if (RequiresHTTP11(server)) { 239 if (RequiresHTTP11(server)) {
222 ForceHTTP11(ssl_config); 240 ForceHTTP11(ssl_config);
223 } 241 }
224 } 242 }
225 243
226 bool HttpServerPropertiesImpl::HasAlternateProtocol( 244 bool HttpServerPropertiesImpl::HasAlternateProtocol(
227 const HostPortPair& server) { 245 const HostPortPair& server) {
228 if (g_forced_alternate_protocol) 246 if (!g_forced_alternate_protocol->empty())
229 return true; 247 return true;
230 AlternateProtocolMap::const_iterator it = alternate_protocol_map_.Get(server); 248 AlternateProtocolMap::const_iterator alternate_protocols =
231 if (it != alternate_protocol_map_.end()) 249 alternate_protocol_map_.Get(server);
232 return it->second.probability >= alternate_protocol_probability_threshold_; 250 if (alternate_protocols != alternate_protocol_map_.end()) {
251 for (AlternateProtocols::const_iterator alternate_protocol =
252 alternate_protocols->second.begin();
253 alternate_protocol != alternate_protocols->second.end();
254 alternate_protocol++) {
255 if (alternate_protocol->probability >=
256 alternate_protocol_probability_threshold_) {
257 return true;
258 }
259 }
260 }
233 261
234 auto canonical = GetCanonicalHost(server); 262 auto canonical = GetCanonicalHost(server);
235 if (canonical == canonical_host_to_origin_map_.end() || 263 if (canonical == canonical_host_to_origin_map_.end() ||
236 canonical->second.Equals(server)) { 264 canonical->second.Equals(server)) {
237 return false; 265 return false;
238 } 266 }
239 267
240 return HasAlternateProtocol(canonical->second); 268 return HasAlternateProtocol(canonical->second);
241 } 269 }
242 270
243 std::string HttpServerPropertiesImpl::GetCanonicalSuffix( 271 std::string HttpServerPropertiesImpl::GetCanonicalSuffix(
244 const HostPortPair& server) { 272 const HostPortPair& server) {
245 // If this host ends with a canonical suffix, then return the canonical 273 // If this host ends with a canonical suffix, then return the canonical
246 // suffix. 274 // suffix.
247 for (size_t i = 0; i < canonical_suffixes_.size(); ++i) { 275 for (size_t i = 0; i < canonical_suffixes_.size(); ++i) {
248 std::string canonical_suffix = canonical_suffixes_[i]; 276 std::string canonical_suffix = canonical_suffixes_[i];
249 if (EndsWith(server.host(), canonical_suffixes_[i], false)) { 277 if (EndsWith(server.host(), canonical_suffixes_[i], false)) {
250 return canonical_suffix; 278 return canonical_suffix;
251 } 279 }
252 } 280 }
253 return std::string(); 281 return std::string();
254 } 282 }
255 283
256 AlternateProtocolInfo 284 const AlternateProtocols& HttpServerPropertiesImpl::GetAlternateProtocols(
257 HttpServerPropertiesImpl::GetAlternateProtocol(
258 const HostPortPair& server) { 285 const HostPortPair& server) {
259 DCHECK(HasAlternateProtocol(server)); 286 DCHECK(HasAlternateProtocol(server));
260 287
261 // First check the map. 288 // First check the map.
262 AlternateProtocolMap::iterator it = alternate_protocol_map_.Get(server); 289 AlternateProtocolMap::iterator it = alternate_protocol_map_.Get(server);
263 if (it != alternate_protocol_map_.end()) 290 if (it != alternate_protocol_map_.end())
264 return it->second; 291 return it->second;
265 292
266 // Next check the canonical host. 293 // Next check the canonical host.
267 CanonicalHostMap::const_iterator canonical_host = GetCanonicalHost(server); 294 CanonicalHostMap::const_iterator canonical_host = GetCanonicalHost(server);
268 if (canonical_host != canonical_host_to_origin_map_.end()) 295 if (canonical_host != canonical_host_to_origin_map_.end())
269 return alternate_protocol_map_.Get(canonical_host->second)->second; 296 return alternate_protocol_map_.Get(canonical_host->second)->second;
270 297
271 // We must be forcing an alternate. 298 // We must be forcing an alternate.
272 DCHECK(g_forced_alternate_protocol); 299 DCHECK(!g_forced_alternate_protocol->empty());
273 return *g_forced_alternate_protocol; 300 return *g_forced_alternate_protocol;
274 } 301 }
275 302
276 void HttpServerPropertiesImpl::SetAlternateProtocol( 303 void HttpServerPropertiesImpl::AddAlternateProtocol(
277 const HostPortPair& server, 304 const HostPortPair& server,
278 uint16 alternate_port, 305 uint16 alternate_port,
279 AlternateProtocol alternate_protocol, 306 AlternateProtocol alternate_protocol,
280 double alternate_probability) { 307 double alternate_probability) {
281
282 AlternateProtocolInfo alternate(alternate_port, 308 AlternateProtocolInfo alternate(alternate_port,
283 alternate_protocol, 309 alternate_protocol,
284 alternate_probability); 310 alternate_probability);
285 if (HasAlternateProtocol(server)) { 311 // Do not call HasAlternateProtocol(), because we don't care about
286 const AlternateProtocolInfo existing_alternate = 312 // |g_forced_alternate_protocol|, or whether the alternate protocol
287 GetAlternateProtocol(server); 313 // probability is higher than the threshold.
288 314 AlternateProtocolMap::iterator map_it = alternate_protocol_map_.Get(server);
289 if (existing_alternate.is_broken) { 315 if (map_it != alternate_protocol_map_.end()) {
290 DVLOG(1) << "Ignore alternate protocol since it's known to be broken."; 316 AlternateProtocols existing_alternates = map_it->second;
291 return; 317 AlternateProtocols::iterator it;
318 for (it = existing_alternates.begin(); it != existing_alternates.end();
319 ++it) {
320 if (it->EqualsModuloProbabilityAndProtocol(alternate)) {
321 break;
322 }
292 } 323 }
293 324
294 if (!existing_alternate.Equals(alternate)) { 325 if (it != existing_alternates.end()) {
295 LOG(WARNING) << "Changing the alternate protocol for: " 326 if (it->is_broken) {
296 << server.ToString() 327 DVLOG(1) << "Ignore alternate protocol since it's known to be broken.";
297 << " from [Port: " << existing_alternate.port 328 return;
298 << ", Protocol: " << existing_alternate.protocol 329 }
299 << ", Probability: " << existing_alternate.probability 330 if (it->probability != alternate_probability) {
300 << "] to [Port: " << alternate_port 331 LOG(WARNING) << "Changing the probability of alternate protocol for: "
301 << ", Protocol: " << alternate_protocol 332 << server.ToString() << " Port: " << it->port
302 << ", Probability: " << alternate_probability 333 << ", Protocol: " << it->protocol
303 << "]."; 334 << ", Probability from: " << it->probability
335 << " to: " << alternate_probability << ".";
336 it->probability = alternate_probability;
337 }
338 } else {
339 existing_alternates.push_back(alternate);
304 } 340 }
341
342 alternate_protocol_map_.Put(server, existing_alternates);
305 } else { 343 } else {
306 if (alternate_probability >= alternate_protocol_probability_threshold_) { 344 if (alternate_probability >= alternate_protocol_probability_threshold_) {
307 // TODO(rch): Consider the case where multiple requests are started 345 // TODO(rch): Consider the case where multiple requests are started
308 // before the first completes. In this case, only one of the jobs 346 // before the first completes. In this case, only one of the jobs
309 // would reach this code, whereas all of them should should have. 347 // would reach this code, whereas all of them should should have.
310 HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_MAPPING_MISSING); 348 HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_MAPPING_MISSING);
311 } 349 }
350 alternate_protocol_map_.Put(server,
351 AlternateProtocols(/*size=*/1, alternate));
312 } 352 }
313 353
314 alternate_protocol_map_.Put(server, alternate);
315
316 // If this host ends with a canonical suffix, then set it as the 354 // If this host ends with a canonical suffix, then set it as the
317 // canonical host. 355 // canonical host.
318 for (size_t i = 0; i < canonical_suffixes_.size(); ++i) { 356 for (size_t i = 0; i < canonical_suffixes_.size(); ++i) {
319 std::string canonical_suffix = canonical_suffixes_[i]; 357 std::string canonical_suffix = canonical_suffixes_[i];
320 if (EndsWith(server.host(), canonical_suffixes_[i], false)) { 358 if (EndsWith(server.host(), canonical_suffixes_[i], false)) {
321 HostPortPair canonical_host(canonical_suffix, server.port()); 359 HostPortPair canonical_host(canonical_suffix, server.port());
322 canonical_host_to_origin_map_[canonical_host] = server; 360 canonical_host_to_origin_map_[canonical_host] = server;
323 break; 361 break;
324 } 362 }
325 } 363 }
326 } 364 }
327 365
328 void HttpServerPropertiesImpl::SetBrokenAlternateProtocol( 366 void HttpServerPropertiesImpl::SetBrokenAlternateProtocol(
329 const HostPortPair& server) { 367 const HostPortPair& server,
330 AlternateProtocolMap::iterator it = alternate_protocol_map_.Get(server); 368 const AlternateProtocolInfo& broken_alternate_protocol) {
331 if (it == alternate_protocol_map_.end()) { 369 AddAlternateProtocol(server, broken_alternate_protocol.port,
332 if (!HasAlternateProtocol(server)) { 370 broken_alternate_protocol.protocol,
333 LOG(DFATAL) << "Trying to mark unknown alternate protocol broken."; 371 broken_alternate_protocol.probability);
334 return; 372 AlternateProtocolMap::iterator alternate_protocols =
373 alternate_protocol_map_.Get(server);
374 DCHECK(alternate_protocols != alternate_protocol_map_.end());
375 AlternateProtocols::iterator it;
376 for (it = alternate_protocols->second.begin();
377 it != alternate_protocols->second.end(); ++it) {
378 if (it->Equals(broken_alternate_protocol)) {
379 it->is_broken = true;
380 break;
335 } 381 }
336 // This server's alternate protocol information is coming from a canonical
337 // server. Add an entry in the map for this server explicitly so that
338 // it can be marked as broken.
339 it = alternate_protocol_map_.Put(server, GetAlternateProtocol(server));
340 } 382 }
341 it->second.is_broken = true; 383 DCHECK(it != alternate_protocols->second.end());
384
342 int count = ++broken_alternate_protocol_map_[server]; 385 int count = ++broken_alternate_protocol_map_[server];
343 base::TimeDelta delay = 386 base::TimeDelta delay =
344 base::TimeDelta::FromSeconds(kBrokenAlternateProtocolDelaySecs); 387 base::TimeDelta::FromSeconds(kBrokenAlternateProtocolDelaySecs);
345 BrokenAlternateProtocolEntry entry; 388 BrokenAlternateProtocolEntry entry;
346 entry.server = server; 389 entry.server = server;
347 entry.when = base::TimeTicks::Now() + delay * (1 << (count - 1)); 390 entry.when = base::TimeTicks::Now() + delay * (1 << (count - 1));
348 broken_alternate_protocol_list_.push_back(entry); 391 broken_alternate_protocol_list_.push_back(entry);
349 392
350 // Do not leave this host as canonical so that we don't infer the other 393 // Do not leave this host as canonical so that we don't infer the other hosts
351 // hosts are also broken without testing them first. 394 // are also broken without testing them first.
352 RemoveCanonicalHost(server); 395 RemoveCanonicalHost(server);
353 396
354 // If this is the only entry in the list, schedule an expiration task. 397 // If this is the only entry in the list, schedule an expiration task.
355 // Otherwse it will be rescheduled automatically when the pending 398 // Otherwise it will be rescheduled automatically when the pending task runs.
356 // task runs.
357 if (broken_alternate_protocol_list_.size() == 1) { 399 if (broken_alternate_protocol_list_.size() == 1) {
358 ScheduleBrokenAlternateProtocolMappingsExpiration(); 400 ScheduleBrokenAlternateProtocolMappingsExpiration();
359 } 401 }
360 } 402 }
361 403
362 bool HttpServerPropertiesImpl::WasAlternateProtocolRecentlyBroken( 404 bool HttpServerPropertiesImpl::WasAlternateProtocolRecentlyBroken(
363 const HostPortPair& server) { 405 const HostPortPair& server,
406 const AlternateProtocolInfo& alternate_protocol) {
364 return ContainsKey(broken_alternate_protocol_map_, server); 407 return ContainsKey(broken_alternate_protocol_map_, server);
365 } 408 }
366 409
367 void HttpServerPropertiesImpl::ConfirmAlternateProtocol( 410 void HttpServerPropertiesImpl::ConfirmAlternateProtocol(
368 const HostPortPair& server) { 411 const HostPortPair& server,
412 const AlternateProtocolInfo& alternate_protocol) {
369 broken_alternate_protocol_map_.erase(server); 413 broken_alternate_protocol_map_.erase(server);
370 } 414 }
371 415
372 void HttpServerPropertiesImpl::ClearAlternateProtocol( 416 void HttpServerPropertiesImpl::ClearAlternateProtocol(
373 const HostPortPair& server) { 417 const HostPortPair& server) {
374 AlternateProtocolMap::iterator it = alternate_protocol_map_.Peek(server); 418 AlternateProtocolMap::iterator it = alternate_protocol_map_.Peek(server);
375 if (it != alternate_protocol_map_.end()) 419 if (it != alternate_protocol_map_.end()) {
376 alternate_protocol_map_.Erase(it); 420 alternate_protocol_map_.Erase(it);
421 }
377 422
378 RemoveCanonicalHost(server); 423 RemoveCanonicalHost(server);
379 } 424 }
380 425
426 void HttpServerPropertiesImpl::ClearNonBrokenAlternateProtocols(
427 const HostPortPair& server) {
428 AlternateProtocolMap::iterator alternate_protocols =
429 alternate_protocol_map_.Peek(server);
430 if (alternate_protocols != alternate_protocol_map_.end()) {
431 for (AlternateProtocols::iterator it = alternate_protocols->second.begin();
432 it != alternate_protocols->second.end();) {
433 if (!it->is_broken) {
434 it = alternate_protocols->second.erase(it);
435 } else {
436 ++it;
437 }
438 }
439 if (alternate_protocols->second.size() == 0) {
440 alternate_protocols = alternate_protocol_map_.Erase(alternate_protocols);
441 RemoveCanonicalHost(server);
442 }
443 }
444 }
445
446 void HttpServerPropertiesImpl::RemoveAlternateProtocol(
447 const HostPortPair& server,
448 const AlternateProtocolInfo& alternate_protocol) {
449 AlternateProtocolMap::iterator alternate_protocols =
450 alternate_protocol_map_.Peek(server);
451 if (alternate_protocols == alternate_protocol_map_.end()) {
452 return;
453 }
454 for (AlternateProtocols::iterator it = alternate_protocols->second.begin();
455 it != alternate_protocols->second.end();) {
456 if (it->Equals(alternate_protocol)) {
457 it = alternate_protocols->second.erase(it);
458 break;
459 } else {
460 ++it;
461 }
462 }
463 if (alternate_protocols->second.size() == 0) {
464 alternate_protocol_map_.Erase(alternate_protocols);
465 RemoveCanonicalHost(server);
466 }
467 }
468
381 const AlternateProtocolMap& 469 const AlternateProtocolMap&
382 HttpServerPropertiesImpl::alternate_protocol_map() const { 470 HttpServerPropertiesImpl::alternate_protocol_map() const {
383 return alternate_protocol_map_; 471 return alternate_protocol_map_;
384 } 472 }
385 473
386 const SettingsMap& HttpServerPropertiesImpl::GetSpdySettings( 474 const SettingsMap& HttpServerPropertiesImpl::GetSpdySettings(
387 const HostPortPair& host_port_pair) { 475 const HostPortPair& host_port_pair) {
388 SpdySettingsMap::iterator it = spdy_settings_map_.Get(host_port_pair); 476 SpdySettingsMap::iterator it = spdy_settings_map_.Get(host_port_pair);
389 if (it == spdy_settings_map_.end()) { 477 if (it == spdy_settings_map_.end()) {
390 CR_DEFINE_STATIC_LOCAL(SettingsMap, kEmptySettingsMap, ()); 478 CR_DEFINE_STATIC_LOCAL(SettingsMap, kEmptySettingsMap, ());
(...skipping 137 matching lines...) Expand 10 before | Expand all | Expand 10 after
528 base::TimeDelta delay = when > now ? when - now : base::TimeDelta(); 616 base::TimeDelta delay = when > now ? when - now : base::TimeDelta();
529 base::MessageLoop::current()->PostDelayedTask( 617 base::MessageLoop::current()->PostDelayedTask(
530 FROM_HERE, 618 FROM_HERE,
531 base::Bind( 619 base::Bind(
532 &HttpServerPropertiesImpl::ExpireBrokenAlternateProtocolMappings, 620 &HttpServerPropertiesImpl::ExpireBrokenAlternateProtocolMappings,
533 weak_ptr_factory_.GetWeakPtr()), 621 weak_ptr_factory_.GetWeakPtr()),
534 delay); 622 delay);
535 } 623 }
536 624
537 } // namespace net 625 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698