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" |
11 #include "base/stl_util.h" | 11 #include "base/stl_util.h" |
12 #include "base/strings/string_util.h" | 12 #include "base/strings/string_util.h" |
13 #include "base/strings/stringprintf.h" | 13 #include "base/strings/stringprintf.h" |
14 | 14 |
15 namespace net { | 15 namespace net { |
16 | 16 |
17 namespace { | 17 namespace { |
18 | 18 |
19 const uint64 kBrokenAlternateProtocolDelaySecs = 300; | 19 const uint64 kBrokenAlternateProtocolDelaySecs = 300; |
20 | 20 |
21 } // namespace | 21 } // namespace |
22 | 22 |
23 HttpServerPropertiesImpl::HttpServerPropertiesImpl() | 23 HttpServerPropertiesImpl::HttpServerPropertiesImpl() |
24 : spdy_servers_map_(SpdyServerHostPortMap::NO_AUTO_EVICT), | 24 : spdy_servers_map_(SpdyServerHostPortMap::NO_AUTO_EVICT), |
25 alternate_protocol_map_(AlternateProtocolMap::NO_AUTO_EVICT), | 25 alternate_protocol_map_(AlternateProtocolMap::NO_AUTO_EVICT), |
26 alternate_protocol_experiment_( | 26 alternate_protocol_experiment_( |
27 ALTERNATE_PROTOCOL_NOT_PART_OF_EXPERIMENT), | 27 ALTERNATE_PROTOCOL_NOT_PART_OF_EXPERIMENT), |
28 spdy_settings_map_(SpdySettingsMap::NO_AUTO_EVICT), | 28 spdy_settings_map_(SpdySettingsMap::NO_AUTO_EVICT), |
29 alternate_protocol_probability_threshold_(0), | |
30 weak_ptr_factory_(this) { | 29 weak_ptr_factory_(this) { |
31 canoncial_suffixes_.push_back(".c.youtube.com"); | 30 canoncial_suffixes_.push_back(".c.youtube.com"); |
32 canoncial_suffixes_.push_back(".googlevideo.com"); | 31 canoncial_suffixes_.push_back(".googlevideo.com"); |
33 canoncial_suffixes_.push_back(".googleusercontent.com"); | 32 canoncial_suffixes_.push_back(".googleusercontent.com"); |
34 } | 33 } |
35 | 34 |
36 HttpServerPropertiesImpl::~HttpServerPropertiesImpl() { | 35 HttpServerPropertiesImpl::~HttpServerPropertiesImpl() { |
37 } | 36 } |
38 | 37 |
39 void HttpServerPropertiesImpl::InitializeSpdyServers( | 38 void HttpServerPropertiesImpl::InitializeSpdyServers( |
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
124 // static | 123 // static |
125 std::string HttpServerPropertiesImpl::GetFlattenedSpdyServer( | 124 std::string HttpServerPropertiesImpl::GetFlattenedSpdyServer( |
126 const net::HostPortPair& host_port_pair) { | 125 const net::HostPortPair& host_port_pair) { |
127 std::string spdy_server; | 126 std::string spdy_server; |
128 spdy_server.append(host_port_pair.host()); | 127 spdy_server.append(host_port_pair.host()); |
129 spdy_server.append(":"); | 128 spdy_server.append(":"); |
130 base::StringAppendF(&spdy_server, "%d", host_port_pair.port()); | 129 base::StringAppendF(&spdy_server, "%d", host_port_pair.port()); |
131 return spdy_server; | 130 return spdy_server; |
132 } | 131 } |
133 | 132 |
134 static const AlternateProtocolInfo* g_forced_alternate_protocol = NULL; | 133 static const PortAlternateProtocolPair* g_forced_alternate_protocol = NULL; |
135 | 134 |
136 // static | 135 // static |
137 void HttpServerPropertiesImpl::ForceAlternateProtocol( | 136 void HttpServerPropertiesImpl::ForceAlternateProtocol( |
138 const AlternateProtocolInfo& info) { | 137 const PortAlternateProtocolPair& pair) { |
139 // Note: we're going to leak this. | 138 // Note: we're going to leak this. |
140 if (g_forced_alternate_protocol) | 139 if (g_forced_alternate_protocol) |
141 delete g_forced_alternate_protocol; | 140 delete g_forced_alternate_protocol; |
142 g_forced_alternate_protocol = new AlternateProtocolInfo(info); | 141 g_forced_alternate_protocol = new PortAlternateProtocolPair(pair); |
143 } | 142 } |
144 | 143 |
145 // static | 144 // static |
146 void HttpServerPropertiesImpl::DisableForcedAlternateProtocol() { | 145 void HttpServerPropertiesImpl::DisableForcedAlternateProtocol() { |
147 delete g_forced_alternate_protocol; | 146 delete g_forced_alternate_protocol; |
148 g_forced_alternate_protocol = NULL; | 147 g_forced_alternate_protocol = NULL; |
149 } | 148 } |
150 | 149 |
151 base::WeakPtr<HttpServerProperties> HttpServerPropertiesImpl::GetWeakPtr() { | 150 base::WeakPtr<HttpServerProperties> HttpServerPropertiesImpl::GetWeakPtr() { |
152 return weak_ptr_factory_.GetWeakPtr(); | 151 return weak_ptr_factory_.GetWeakPtr(); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
187 if ((spdy_host_port != spdy_servers_map_.end()) && | 186 if ((spdy_host_port != spdy_servers_map_.end()) && |
188 (spdy_host_port->second == support_spdy)) { | 187 (spdy_host_port->second == support_spdy)) { |
189 return; | 188 return; |
190 } | 189 } |
191 // Cache the data. | 190 // Cache the data. |
192 spdy_servers_map_.Put(spdy_server, support_spdy); | 191 spdy_servers_map_.Put(spdy_server, support_spdy); |
193 } | 192 } |
194 | 193 |
195 bool HttpServerPropertiesImpl::HasAlternateProtocol( | 194 bool HttpServerPropertiesImpl::HasAlternateProtocol( |
196 const HostPortPair& server) { | 195 const HostPortPair& server) { |
197 if (g_forced_alternate_protocol) | 196 if (alternate_protocol_map_.Get(server) != alternate_protocol_map_.end() || |
| 197 g_forced_alternate_protocol) |
198 return true; | 198 return true; |
199 AlternateProtocolMap::const_iterator it = alternate_protocol_map_.Get(server); | |
200 if (it != alternate_protocol_map_.end() && | |
201 it->second.probability > alternate_protocol_probability_threshold_) { | |
202 return true; | |
203 } | |
204 | 199 |
205 return GetCanonicalHost(server) != canonical_host_to_origin_map_.end(); | 200 return GetCanonicalHost(server) != canonical_host_to_origin_map_.end(); |
206 } | 201 } |
207 | 202 |
208 std::string HttpServerPropertiesImpl::GetCanonicalSuffix( | 203 std::string HttpServerPropertiesImpl::GetCanonicalSuffix( |
209 const HostPortPair& server) { | 204 const HostPortPair& server) { |
210 // If this host ends with a canonical suffix, then return the canonical | 205 // If this host ends with a canonical suffix, then return the canonical |
211 // suffix. | 206 // suffix. |
212 for (size_t i = 0; i < canoncial_suffixes_.size(); ++i) { | 207 for (size_t i = 0; i < canoncial_suffixes_.size(); ++i) { |
213 std::string canonical_suffix = canoncial_suffixes_[i]; | 208 std::string canonical_suffix = canoncial_suffixes_[i]; |
214 if (EndsWith(server.host(), canoncial_suffixes_[i], false)) { | 209 if (EndsWith(server.host(), canoncial_suffixes_[i], false)) { |
215 return canonical_suffix; | 210 return canonical_suffix; |
216 } | 211 } |
217 } | 212 } |
218 return std::string(); | 213 return std::string(); |
219 } | 214 } |
220 | 215 |
221 AlternateProtocolInfo | 216 PortAlternateProtocolPair |
222 HttpServerPropertiesImpl::GetAlternateProtocol( | 217 HttpServerPropertiesImpl::GetAlternateProtocol( |
223 const HostPortPair& server) { | 218 const HostPortPair& server) { |
224 DCHECK(HasAlternateProtocol(server)); | 219 DCHECK(HasAlternateProtocol(server)); |
225 | 220 |
226 // First check the map. | 221 // First check the map. |
227 AlternateProtocolMap::iterator it = alternate_protocol_map_.Get(server); | 222 AlternateProtocolMap::iterator it = alternate_protocol_map_.Get(server); |
228 if (it != alternate_protocol_map_.end()) | 223 if (it != alternate_protocol_map_.end()) |
229 return it->second; | 224 return it->second; |
230 | 225 |
231 // Next check the canonical host. | 226 // Next check the canonical host. |
232 CanonicalHostMap::const_iterator canonical_host = GetCanonicalHost(server); | 227 CanonicalHostMap::const_iterator canonical_host = GetCanonicalHost(server); |
233 if (canonical_host != canonical_host_to_origin_map_.end()) | 228 if (canonical_host != canonical_host_to_origin_map_.end()) |
234 return alternate_protocol_map_.Get(canonical_host->second)->second; | 229 return alternate_protocol_map_.Get(canonical_host->second)->second; |
235 | 230 |
236 // We must be forcing an alternate. | 231 // We must be forcing an alternate. |
237 DCHECK(g_forced_alternate_protocol); | 232 DCHECK(g_forced_alternate_protocol); |
238 return *g_forced_alternate_protocol; | 233 return *g_forced_alternate_protocol; |
239 } | 234 } |
240 | 235 |
241 void HttpServerPropertiesImpl::SetAlternateProtocol( | 236 void HttpServerPropertiesImpl::SetAlternateProtocol( |
242 const HostPortPair& server, | 237 const HostPortPair& server, |
243 uint16 alternate_port, | 238 uint16 alternate_port, |
244 AlternateProtocol alternate_protocol, | 239 AlternateProtocol alternate_protocol) { |
245 double alternate_probability) { | |
246 if (alternate_protocol == ALTERNATE_PROTOCOL_BROKEN) { | 240 if (alternate_protocol == ALTERNATE_PROTOCOL_BROKEN) { |
247 LOG(DFATAL) << "Call SetBrokenAlternateProtocol() instead."; | 241 LOG(DFATAL) << "Call SetBrokenAlternateProtocol() instead."; |
248 return; | 242 return; |
249 } | 243 } |
250 | 244 |
251 AlternateProtocolInfo alternate(alternate_port, | 245 PortAlternateProtocolPair alternate; |
252 alternate_protocol, | 246 alternate.port = alternate_port; |
253 alternate_probability); | 247 alternate.protocol = alternate_protocol; |
254 if (HasAlternateProtocol(server)) { | 248 if (HasAlternateProtocol(server)) { |
255 const AlternateProtocolInfo existing_alternate = | 249 const PortAlternateProtocolPair existing_alternate = |
256 GetAlternateProtocol(server); | 250 GetAlternateProtocol(server); |
257 | 251 |
258 if (existing_alternate.protocol == ALTERNATE_PROTOCOL_BROKEN) { | 252 if (existing_alternate.protocol == ALTERNATE_PROTOCOL_BROKEN) { |
259 DVLOG(1) << "Ignore alternate protocol since it's known to be broken."; | 253 DVLOG(1) << "Ignore alternate protocol since it's known to be broken."; |
260 return; | 254 return; |
261 } | 255 } |
262 | 256 |
263 if (alternate_protocol != ALTERNATE_PROTOCOL_BROKEN && | 257 if (alternate_protocol != ALTERNATE_PROTOCOL_BROKEN && |
264 !existing_alternate.Equals(alternate)) { | 258 !existing_alternate.Equals(alternate)) { |
265 LOG(WARNING) << "Changing the alternate protocol for: " | 259 LOG(WARNING) << "Changing the alternate protocol for: " |
266 << server.ToString() | 260 << server.ToString() |
267 << " from [Port: " << existing_alternate.port | 261 << " from [Port: " << existing_alternate.port |
268 << ", Protocol: " << existing_alternate.protocol | 262 << ", Protocol: " << existing_alternate.protocol |
269 << ", Probability: " << existing_alternate.probability | |
270 << "] to [Port: " << alternate_port | 263 << "] to [Port: " << alternate_port |
271 << ", Protocol: " << alternate_protocol | 264 << ", Protocol: " << alternate_protocol |
272 << ", Probability: " << alternate_probability | |
273 << "]."; | 265 << "]."; |
274 } | 266 } |
275 } else { | 267 } else { |
276 // TODO(rch): Consider the case where multiple requests are started | 268 // TODO(rch): Consider the case where multiple requests are started |
277 // before the first completes. In this case, only one of the jobs | 269 // before the first completes. In this case, only one of the jobs |
278 // would reach this code, whereas all of them should should have. | 270 // would reach this code, whereas all of them should should have. |
279 HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_MAPPING_MISSING, | 271 HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_MAPPING_MISSING, |
280 alternate_protocol_experiment_); | 272 alternate_protocol_experiment_); |
281 } | 273 } |
282 | 274 |
(...skipping 10 matching lines...) Expand all Loading... |
293 } | 285 } |
294 } | 286 } |
295 } | 287 } |
296 | 288 |
297 void HttpServerPropertiesImpl::SetBrokenAlternateProtocol( | 289 void HttpServerPropertiesImpl::SetBrokenAlternateProtocol( |
298 const HostPortPair& server) { | 290 const HostPortPair& server) { |
299 AlternateProtocolMap::iterator it = alternate_protocol_map_.Get(server); | 291 AlternateProtocolMap::iterator it = alternate_protocol_map_.Get(server); |
300 if (it != alternate_protocol_map_.end()) { | 292 if (it != alternate_protocol_map_.end()) { |
301 it->second.protocol = ALTERNATE_PROTOCOL_BROKEN; | 293 it->second.protocol = ALTERNATE_PROTOCOL_BROKEN; |
302 } else { | 294 } else { |
303 AlternateProtocolInfo alternate(server.port(), | 295 PortAlternateProtocolPair alternate; |
304 ALTERNATE_PROTOCOL_BROKEN, | 296 alternate.protocol = ALTERNATE_PROTOCOL_BROKEN; |
305 1); | |
306 alternate_protocol_map_.Put(server, alternate); | 297 alternate_protocol_map_.Put(server, alternate); |
307 } | 298 } |
308 int count = ++broken_alternate_protocol_map_[server]; | 299 int count = ++broken_alternate_protocol_map_[server]; |
309 base::TimeDelta delay = | 300 base::TimeDelta delay = |
310 base::TimeDelta::FromSeconds(kBrokenAlternateProtocolDelaySecs); | 301 base::TimeDelta::FromSeconds(kBrokenAlternateProtocolDelaySecs); |
311 BrokenAlternateProtocolEntry entry; | 302 BrokenAlternateProtocolEntry entry; |
312 entry.server = server; | 303 entry.server = server; |
313 entry.when = base::TimeTicks::Now() + delay * (1 << (count - 1)); | 304 entry.when = base::TimeTicks::Now() + delay * (1 << (count - 1)); |
314 broken_alternate_protocol_list_.push_back(entry); | 305 broken_alternate_protocol_list_.push_back(entry); |
315 | 306 |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
416 HttpServerPropertiesImpl::GetServerNetworkStats( | 407 HttpServerPropertiesImpl::GetServerNetworkStats( |
417 const HostPortPair& host_port_pair) const { | 408 const HostPortPair& host_port_pair) const { |
418 ServerNetworkStatsMap::const_iterator it = | 409 ServerNetworkStatsMap::const_iterator it = |
419 server_network_stats_map_.find(host_port_pair); | 410 server_network_stats_map_.find(host_port_pair); |
420 if (it == server_network_stats_map_.end()) { | 411 if (it == server_network_stats_map_.end()) { |
421 return NULL; | 412 return NULL; |
422 } | 413 } |
423 return &it->second; | 414 return &it->second; |
424 } | 415 } |
425 | 416 |
426 void HttpServerPropertiesImpl::SetAlternateProtocolProbabilityThreshold( | |
427 double threshold) { | |
428 alternate_protocol_probability_threshold_ = threshold; | |
429 } | |
430 | |
431 HttpServerPropertiesImpl::CanonicalHostMap::const_iterator | 417 HttpServerPropertiesImpl::CanonicalHostMap::const_iterator |
432 HttpServerPropertiesImpl::GetCanonicalHost(HostPortPair server) const { | 418 HttpServerPropertiesImpl::GetCanonicalHost(HostPortPair server) const { |
433 for (size_t i = 0; i < canoncial_suffixes_.size(); ++i) { | 419 for (size_t i = 0; i < canoncial_suffixes_.size(); ++i) { |
434 std::string canonical_suffix = canoncial_suffixes_[i]; | 420 std::string canonical_suffix = canoncial_suffixes_[i]; |
435 if (EndsWith(server.host(), canoncial_suffixes_[i], false)) { | 421 if (EndsWith(server.host(), canoncial_suffixes_[i], false)) { |
436 HostPortPair canonical_host(canonical_suffix, server.port()); | 422 HostPortPair canonical_host(canonical_suffix, server.port()); |
437 return canonical_host_to_origin_map_.find(canonical_host); | 423 return canonical_host_to_origin_map_.find(canonical_host); |
438 } | 424 } |
439 } | 425 } |
440 | 426 |
(...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
478 base::TimeDelta delay = when > now ? when - now : base::TimeDelta(); | 464 base::TimeDelta delay = when > now ? when - now : base::TimeDelta(); |
479 base::MessageLoop::current()->PostDelayedTask( | 465 base::MessageLoop::current()->PostDelayedTask( |
480 FROM_HERE, | 466 FROM_HERE, |
481 base::Bind( | 467 base::Bind( |
482 &HttpServerPropertiesImpl::ExpireBrokenAlternateProtocolMappings, | 468 &HttpServerPropertiesImpl::ExpireBrokenAlternateProtocolMappings, |
483 weak_ptr_factory_.GetWeakPtr()), | 469 weak_ptr_factory_.GetWeakPtr()), |
484 delay); | 470 delay); |
485 } | 471 } |
486 | 472 |
487 } // namespace net | 473 } // namespace net |
OLD | NEW |