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

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: Nits. Created 6 years, 1 month 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 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
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 for (AlternateProtocolMap::iterator alternate_protocols =
53 // get persisted. 53 alternate_protocol_map_.begin();
54 for (AlternateProtocolMap::iterator it = alternate_protocol_map_.begin(); 54 alternate_protocols != alternate_protocol_map_.end();) {
55 it != alternate_protocol_map_.end();) { 55 // Keep all the ALTERNATE_PROTOCOL_BROKEN ones since those don't get
56 AlternateProtocolMap::iterator old_it = it; 56 // persisted.
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 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
131 // static 140 // static
132 std::string HttpServerPropertiesImpl::GetFlattenedSpdyServer( 141 std::string HttpServerPropertiesImpl::GetFlattenedSpdyServer(
133 const net::HostPortPair& host_port_pair) { 142 const net::HostPortPair& host_port_pair) {
134 std::string spdy_server; 143 std::string spdy_server;
135 spdy_server.append(host_port_pair.host()); 144 spdy_server.append(host_port_pair.host());
136 spdy_server.append(":"); 145 spdy_server.append(":");
137 base::StringAppendF(&spdy_server, "%d", host_port_pair.port()); 146 base::StringAppendF(&spdy_server, "%d", host_port_pair.port());
138 return spdy_server; 147 return spdy_server;
139 } 148 }
140 149
141 static const AlternateProtocolInfo* g_forced_alternate_protocol = NULL; 150 static AlternateProtocols* g_forced_alternate_protocol =
151 new AlternateProtocols();
142 152
143 // static 153 // static
144 void HttpServerPropertiesImpl::ForceAlternateProtocol( 154 void HttpServerPropertiesImpl::ForceAlternateProtocol(
145 const AlternateProtocolInfo& info) { 155 const AlternateProtocolInfo& info) {
156 DisableForcedAlternateProtocol();
146 // Note: we're going to leak this. 157 // Note: we're going to leak this.
147 if (g_forced_alternate_protocol) 158 g_forced_alternate_protocol->push_back(info);
148 delete g_forced_alternate_protocol;
149 g_forced_alternate_protocol = new AlternateProtocolInfo(info);
150 } 159 }
151 160
152 // static 161 // static
153 void HttpServerPropertiesImpl::DisableForcedAlternateProtocol() { 162 void HttpServerPropertiesImpl::DisableForcedAlternateProtocol() {
154 delete g_forced_alternate_protocol; 163 g_forced_alternate_protocol->clear();
155 g_forced_alternate_protocol = NULL;
156 } 164 }
157 165
158 base::WeakPtr<HttpServerProperties> HttpServerPropertiesImpl::GetWeakPtr() { 166 base::WeakPtr<HttpServerProperties> HttpServerPropertiesImpl::GetWeakPtr() {
159 return weak_ptr_factory_.GetWeakPtr(); 167 return weak_ptr_factory_.GetWeakPtr();
160 } 168 }
161 169
162 void HttpServerPropertiesImpl::Clear() { 170 void HttpServerPropertiesImpl::Clear() {
163 DCHECK(CalledOnValidThread()); 171 DCHECK(CalledOnValidThread());
164 spdy_servers_map_.Clear(); 172 spdy_servers_map_.Clear();
165 alternate_protocol_map_.Clear(); 173 alternate_protocol_map_.Clear();
(...skipping 29 matching lines...) Expand all
195 if ((spdy_host_port != spdy_servers_map_.end()) && 203 if ((spdy_host_port != spdy_servers_map_.end()) &&
196 (spdy_host_port->second == support_spdy)) { 204 (spdy_host_port->second == support_spdy)) {
197 return; 205 return;
198 } 206 }
199 // Cache the data. 207 // Cache the data.
200 spdy_servers_map_.Put(spdy_server, support_spdy); 208 spdy_servers_map_.Put(spdy_server, support_spdy);
201 } 209 }
202 210
203 bool HttpServerPropertiesImpl::HasAlternateProtocol( 211 bool HttpServerPropertiesImpl::HasAlternateProtocol(
204 const HostPortPair& server) { 212 const HostPortPair& server) {
205 if (g_forced_alternate_protocol) 213 if (!g_forced_alternate_protocol->empty())
206 return true; 214 return true;
207 AlternateProtocolMap::const_iterator it = alternate_protocol_map_.Get(server); 215 AlternateProtocolMap::const_iterator alternate_protocols =
208 if (it != alternate_protocol_map_.end() && 216 alternate_protocol_map_.Get(server);
209 it->second.probability >= alternate_protocol_probability_threshold_) { 217 if (alternate_protocols != alternate_protocol_map_.end()) {
210 return true; 218 for (AlternateProtocols::const_iterator alternate_protocol =
219 alternate_protocols->second.begin();
220 alternate_protocol != alternate_protocols->second.end();
221 alternate_protocol++) {
222 if (alternate_protocol->probability >=
223 alternate_protocol_probability_threshold_) {
224 return true;
225 }
226 }
211 } 227 }
212 228
213 return GetCanonicalHost(server) != canonical_host_to_origin_map_.end(); 229 return GetCanonicalHost(server) != canonical_host_to_origin_map_.end();
214 } 230 }
215 231
216 std::string HttpServerPropertiesImpl::GetCanonicalSuffix( 232 std::string HttpServerPropertiesImpl::GetCanonicalSuffix(
217 const HostPortPair& server) { 233 const HostPortPair& server) {
218 // If this host ends with a canonical suffix, then return the canonical 234 // If this host ends with a canonical suffix, then return the canonical
219 // suffix. 235 // suffix.
220 for (size_t i = 0; i < canonical_suffixes_.size(); ++i) { 236 for (size_t i = 0; i < canonical_suffixes_.size(); ++i) {
221 std::string canonical_suffix = canonical_suffixes_[i]; 237 std::string canonical_suffix = canonical_suffixes_[i];
222 if (EndsWith(server.host(), canonical_suffixes_[i], false)) { 238 if (EndsWith(server.host(), canonical_suffixes_[i], false)) {
223 return canonical_suffix; 239 return canonical_suffix;
224 } 240 }
225 } 241 }
226 return std::string(); 242 return std::string();
227 } 243 }
228 244
229 AlternateProtocolInfo 245 const AlternateProtocols& HttpServerPropertiesImpl::GetAlternateProtocols(
230 HttpServerPropertiesImpl::GetAlternateProtocol(
231 const HostPortPair& server) { 246 const HostPortPair& server) {
232 DCHECK(HasAlternateProtocol(server)); 247 DCHECK(HasAlternateProtocol(server));
233 248
234 // First check the map. 249 // First check the map.
235 AlternateProtocolMap::iterator it = alternate_protocol_map_.Get(server); 250 AlternateProtocolMap::iterator it = alternate_protocol_map_.Get(server);
236 if (it != alternate_protocol_map_.end()) 251 if (it != alternate_protocol_map_.end())
237 return it->second; 252 return it->second;
238 253
239 // Next check the canonical host. 254 // Next check the canonical host.
240 CanonicalHostMap::const_iterator canonical_host = GetCanonicalHost(server); 255 CanonicalHostMap::const_iterator canonical_host = GetCanonicalHost(server);
241 if (canonical_host != canonical_host_to_origin_map_.end()) 256 if (canonical_host != canonical_host_to_origin_map_.end())
242 return alternate_protocol_map_.Get(canonical_host->second)->second; 257 return alternate_protocol_map_.Get(canonical_host->second)->second;
243 258
244 // We must be forcing an alternate. 259 // We must be forcing an alternate.
245 DCHECK(g_forced_alternate_protocol); 260 DCHECK(!g_forced_alternate_protocol->empty());
246 return *g_forced_alternate_protocol; 261 return *g_forced_alternate_protocol;
247 } 262 }
248 263
249 void HttpServerPropertiesImpl::SetAlternateProtocol( 264 void HttpServerPropertiesImpl::AddAlternateProtocol(
250 const HostPortPair& server, 265 const HostPortPair& server,
251 uint16 alternate_port, 266 uint16 alternate_port,
252 AlternateProtocol alternate_protocol, 267 AlternateProtocol alternate_protocol,
253 double alternate_probability) { 268 double alternate_probability) {
254 if (alternate_protocol == ALTERNATE_PROTOCOL_BROKEN) { 269 if (alternate_protocol == ALTERNATE_PROTOCOL_BROKEN) {
255 LOG(DFATAL) << "Call SetBrokenAlternateProtocol() instead."; 270 LOG(DFATAL) << "Call SetBrokenAlternateProtocol() instead.";
256 return; 271 return;
257 } 272 }
258 273
259 AlternateProtocolInfo alternate(alternate_port, 274 AlternateProtocolInfo alternate(alternate_port,
260 alternate_protocol, 275 alternate_protocol,
261 alternate_probability); 276 alternate_probability);
262 if (HasAlternateProtocol(server)) { 277 // Do not call HasAlternateProtocol(), because we don't care about
263 const AlternateProtocolInfo existing_alternate = 278 // |g_forced_alternate_protocol|, or whether the alternate protocol
264 GetAlternateProtocol(server); 279 // probability is higher than the threshold.
265 280 AlternateProtocolMap::iterator map_it = alternate_protocol_map_.Get(server);
266 if (existing_alternate.protocol == ALTERNATE_PROTOCOL_BROKEN) { 281 if (map_it != alternate_protocol_map_.end()) {
267 DVLOG(1) << "Ignore alternate protocol since it's known to be broken."; 282 AlternateProtocols existing_alternates = map_it->second;
268 return; 283 AlternateProtocols::iterator it;
284 for (it = existing_alternates.begin(); it != existing_alternates.end();
285 ++it) {
286 if (it->EqualsModuloProbabilityAndProtocol(alternate)) {
287 break;
288 }
269 } 289 }
270 290
271 if (alternate_protocol != ALTERNATE_PROTOCOL_BROKEN && 291 if (it != existing_alternates.end()) {
272 !existing_alternate.Equals(alternate)) { 292 if (it->protocol == ALTERNATE_PROTOCOL_BROKEN) {
273 LOG(WARNING) << "Changing the alternate protocol for: " 293 DVLOG(1) << "Ignore alternate protocol since it's known to be broken.";
274 << server.ToString() 294 return;
275 << " from [Port: " << existing_alternate.port 295 }
276 << ", Protocol: " << existing_alternate.protocol 296 if (it->probability != alternate_probability) {
277 << ", Probability: " << existing_alternate.probability 297 LOG(WARNING) << "Changing the probability of alternate protocol for: "
278 << "] to [Port: " << alternate_port 298 << server.ToString()
279 << ", Protocol: " << alternate_protocol 299 << " Port: " << it->port
280 << ", Probability: " << alternate_probability 300 << ", Protocol: " << it->protocol
281 << "]."; 301 << ", Probability from: " << it->probability
302 << " to: " << alternate_probability << ".";
303 it->probability = alternate_probability;
304 }
305 } else {
306 existing_alternates.push_back(alternate);
282 } 307 }
308
309 alternate_protocol_map_.Put(server, existing_alternates);
283 } else { 310 } else {
284 if (alternate_probability >= alternate_protocol_probability_threshold_) { 311 if (alternate_probability >= alternate_protocol_probability_threshold_) {
285 // TODO(rch): Consider the case where multiple requests are started 312 // TODO(rch): Consider the case where multiple requests are started
286 // before the first completes. In this case, only one of the jobs 313 // before the first completes. In this case, only one of the jobs
287 // would reach this code, whereas all of them should should have. 314 // would reach this code, whereas all of them should should have.
288 HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_MAPPING_MISSING); 315 HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_MAPPING_MISSING);
289 } 316 }
317 alternate_protocol_map_.Put(server,
318 AlternateProtocols(/*size=*/1, alternate));
290 } 319 }
291 320
292 alternate_protocol_map_.Put(server, alternate);
293
294 // If this host ends with a canonical suffix, then set it as the 321 // If this host ends with a canonical suffix, then set it as the
295 // canonical host. 322 // canonical host.
296 for (size_t i = 0; i < canonical_suffixes_.size(); ++i) { 323 for (size_t i = 0; i < canonical_suffixes_.size(); ++i) {
297 std::string canonical_suffix = canonical_suffixes_[i]; 324 std::string canonical_suffix = canonical_suffixes_[i];
298 if (EndsWith(server.host(), canonical_suffixes_[i], false)) { 325 if (EndsWith(server.host(), canonical_suffixes_[i], false)) {
299 HostPortPair canonical_host(canonical_suffix, server.port()); 326 HostPortPair canonical_host(canonical_suffix, server.port());
300 canonical_host_to_origin_map_[canonical_host] = server; 327 canonical_host_to_origin_map_[canonical_host] = server;
301 break; 328 break;
302 } 329 }
303 } 330 }
304 } 331 }
305 332
306 void HttpServerPropertiesImpl::SetBrokenAlternateProtocol( 333 void HttpServerPropertiesImpl::SetBrokenAlternateProtocol(
307 const HostPortPair& server) { 334 const HostPortPair& server,
308 AlternateProtocolMap::iterator it = alternate_protocol_map_.Get(server); 335 const AlternateProtocolInfo& broken_alternate_protocol) {
309 if (it != alternate_protocol_map_.end()) { 336 AddAlternateProtocol(server,
310 it->second.protocol = ALTERNATE_PROTOCOL_BROKEN; 337 broken_alternate_protocol.port,
311 } else { 338 broken_alternate_protocol.protocol,
312 AlternateProtocolInfo alternate(server.port(), 339 broken_alternate_protocol.probability);
313 ALTERNATE_PROTOCOL_BROKEN, 340 AlternateProtocolMap::iterator alternate_protocols =
314 1); 341 alternate_protocol_map_.Get(server);
315 alternate_protocol_map_.Put(server, alternate); 342 DCHECK(alternate_protocols != alternate_protocol_map_.end());
343 AlternateProtocols::iterator it;
344 for (it = alternate_protocols->second.begin();
345 it != alternate_protocols->second.end();
346 ++it) {
347 if (it->Equals(broken_alternate_protocol)) {
348 it->protocol = ALTERNATE_PROTOCOL_BROKEN;
349 break;
350 }
316 } 351 }
352 DCHECK(it != alternate_protocols->second.end());
353
317 int count = ++broken_alternate_protocol_map_[server]; 354 int count = ++broken_alternate_protocol_map_[server];
318 base::TimeDelta delay = 355 base::TimeDelta delay =
319 base::TimeDelta::FromSeconds(kBrokenAlternateProtocolDelaySecs); 356 base::TimeDelta::FromSeconds(kBrokenAlternateProtocolDelaySecs);
320 BrokenAlternateProtocolEntry entry; 357 BrokenAlternateProtocolEntry entry;
321 entry.server = server; 358 entry.server = server;
322 entry.when = base::TimeTicks::Now() + delay * (1 << (count - 1)); 359 entry.when = base::TimeTicks::Now() + delay * (1 << (count - 1));
323 broken_alternate_protocol_list_.push_back(entry); 360 broken_alternate_protocol_list_.push_back(entry);
324 361
325 // Do not leave this host as canonical so that we don't infer the other 362 // 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. 363 // are also broken without testing them first.
327 RemoveCanonicalHost(server); 364 RemoveCanonicalHost(server);
328 365
329 // If this is the only entry in the list, schedule an expiration task. 366 // If this is the only entry in the list, schedule an expiration task.
330 // Otherwse it will be rescheduled automatically when the pending 367 // Otherwise it will be rescheduled automatically when the pending task runs.
331 // task runs.
332 if (broken_alternate_protocol_list_.size() == 1) { 368 if (broken_alternate_protocol_list_.size() == 1) {
333 ScheduleBrokenAlternateProtocolMappingsExpiration(); 369 ScheduleBrokenAlternateProtocolMappingsExpiration();
334 } 370 }
335 } 371 }
336 372
337 bool HttpServerPropertiesImpl::WasAlternateProtocolRecentlyBroken( 373 bool HttpServerPropertiesImpl::WasAlternateProtocolRecentlyBroken(
338 const HostPortPair& server) { 374 const HostPortPair& server,
375 const AlternateProtocolInfo& alternate_protocol) {
339 return ContainsKey(broken_alternate_protocol_map_, server); 376 return ContainsKey(broken_alternate_protocol_map_, server);
340 } 377 }
341 378
342 void HttpServerPropertiesImpl::ConfirmAlternateProtocol( 379 void HttpServerPropertiesImpl::ConfirmAlternateProtocol(
343 const HostPortPair& server) { 380 const HostPortPair& server,
381 const AlternateProtocolInfo& alternate_protocol) {
344 broken_alternate_protocol_map_.erase(server); 382 broken_alternate_protocol_map_.erase(server);
345 } 383 }
346 384
347 void HttpServerPropertiesImpl::ClearAlternateProtocol( 385 void HttpServerPropertiesImpl::ClearAlternateProtocol(
348 const HostPortPair& server) { 386 const HostPortPair& server) {
349 AlternateProtocolMap::iterator it = alternate_protocol_map_.Peek(server); 387 AlternateProtocolMap::iterator it = alternate_protocol_map_.Peek(server);
350 if (it != alternate_protocol_map_.end()) 388 if (it != alternate_protocol_map_.end()) {
351 alternate_protocol_map_.Erase(it); 389 alternate_protocol_map_.Erase(it);
390 }
352 391
353 RemoveCanonicalHost(server); 392 RemoveCanonicalHost(server);
354 } 393 }
355 394
395 void HttpServerPropertiesImpl::RemoveAlternateProtocol(
396 const HostPortPair& server,
397 const AlternateProtocolInfo& alternate_protocol) {
398 AlternateProtocolMap::iterator alternate_protocols =
399 alternate_protocol_map_.Peek(server);
400 if (alternate_protocols == alternate_protocol_map_.end()) {
401 return;
402 }
403 for (AlternateProtocols::iterator it = alternate_protocols->second.begin();
404 it != alternate_protocols->second.end();) {
405 if (it->Equals(alternate_protocol)) {
406 it = alternate_protocols->second.erase(it);
407 break;
408 } else {
409 ++it;
410 }
411 }
412 if (alternate_protocols->second.size() == 0) {
413 alternate_protocol_map_.Erase(alternate_protocols);
414 RemoveCanonicalHost(server);
415 }
416 }
417
356 const AlternateProtocolMap& 418 const AlternateProtocolMap&
357 HttpServerPropertiesImpl::alternate_protocol_map() const { 419 HttpServerPropertiesImpl::alternate_protocol_map() const {
358 return alternate_protocol_map_; 420 return alternate_protocol_map_;
359 } 421 }
360 422
361 const SettingsMap& HttpServerPropertiesImpl::GetSpdySettings( 423 const SettingsMap& HttpServerPropertiesImpl::GetSpdySettings(
362 const HostPortPair& host_port_pair) { 424 const HostPortPair& host_port_pair) {
363 SpdySettingsMap::iterator it = spdy_settings_map_.Get(host_port_pair); 425 SpdySettingsMap::iterator it = spdy_settings_map_.Get(host_port_pair);
364 if (it == spdy_settings_map_.end()) { 426 if (it == spdy_settings_map_.end()) {
365 CR_DEFINE_STATIC_LOCAL(SettingsMap, kEmptySettingsMap, ()); 427 CR_DEFINE_STATIC_LOCAL(SettingsMap, kEmptySettingsMap, ());
(...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after
500 base::TimeDelta delay = when > now ? when - now : base::TimeDelta(); 562 base::TimeDelta delay = when > now ? when - now : base::TimeDelta();
501 base::MessageLoop::current()->PostDelayedTask( 563 base::MessageLoop::current()->PostDelayedTask(
502 FROM_HERE, 564 FROM_HERE,
503 base::Bind( 565 base::Bind(
504 &HttpServerPropertiesImpl::ExpireBrokenAlternateProtocolMappings, 566 &HttpServerPropertiesImpl::ExpireBrokenAlternateProtocolMappings,
505 weak_ptr_factory_.GetWeakPtr()), 567 weak_ptr_factory_.GetWeakPtr()),
506 delay); 568 delay);
507 } 569 }
508 570
509 } // namespace net 571 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698