| 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_stream_factory_impl.h" | 5 #include "net/http/http_stream_factory_impl.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 #include <tuple> |
| 8 | 9 |
| 9 #include "base/logging.h" | 10 #include "base/logging.h" |
| 10 #include "base/memory/ptr_util.h" | 11 #include "base/memory/ptr_util.h" |
| 11 #include "base/metrics/histogram_macros.h" | 12 #include "base/metrics/histogram_macros.h" |
| 12 #include "base/stl_util.h" | 13 #include "base/stl_util.h" |
| 13 #include "base/strings/string_util.h" | 14 #include "base/strings/string_util.h" |
| 14 #include "net/http/http_network_session.h" | 15 #include "net/http/http_network_session.h" |
| 15 #include "net/http/http_server_properties.h" | 16 #include "net/http/http_server_properties.h" |
| 16 #include "net/http/http_stream_factory_impl_job.h" | 17 #include "net/http/http_stream_factory_impl_job.h" |
| 17 #include "net/http/http_stream_factory_impl_job_controller.h" | 18 #include "net/http/http_stream_factory_impl_job_controller.h" |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 236 for (auto it = job_controller_set_.begin(); it != job_controller_set_.end(); | 237 for (auto it = job_controller_set_.begin(); it != job_controller_set_.end(); |
| 237 ++it) { | 238 ++it) { |
| 238 if (it->get() == controller) { | 239 if (it->get() == controller) { |
| 239 job_controller_set_.erase(it); | 240 job_controller_set_.erase(it); |
| 240 return; | 241 return; |
| 241 } | 242 } |
| 242 } | 243 } |
| 243 NOTREACHED(); | 244 NOTREACHED(); |
| 244 } | 245 } |
| 245 | 246 |
| 247 HttpStreamFactoryImpl::PreconnectingProxyServer::PreconnectingProxyServer( |
| 248 ProxyServer proxy_server, |
| 249 PrivacyMode privacy_mode) |
| 250 : proxy_server(proxy_server), privacy_mode(privacy_mode) {} |
| 251 |
| 252 bool HttpStreamFactoryImpl::PreconnectingProxyServer::operator<( |
| 253 const PreconnectingProxyServer& other) const { |
| 254 return std::tie(proxy_server, privacy_mode) < |
| 255 std::tie(other.proxy_server, other.privacy_mode); |
| 256 } |
| 257 |
| 258 bool HttpStreamFactoryImpl::PreconnectingProxyServer::operator==( |
| 259 const PreconnectingProxyServer& other) const { |
| 260 return proxy_server == other.proxy_server && |
| 261 privacy_mode == other.privacy_mode; |
| 262 } |
| 263 |
| 246 bool HttpStreamFactoryImpl::OnInitConnection(const JobController& controller, | 264 bool HttpStreamFactoryImpl::OnInitConnection(const JobController& controller, |
| 247 const ProxyInfo& proxy_info) { | 265 const ProxyInfo& proxy_info, |
| 266 PrivacyMode privacy_mode) { |
| 248 if (!controller.is_preconnect()) { | 267 if (!controller.is_preconnect()) { |
| 249 // Connection initialization can be skipped only for the preconnect jobs. | 268 // Connection initialization can be skipped only for the preconnect jobs. |
| 250 return false; | 269 return false; |
| 251 } | 270 } |
| 252 | 271 |
| 253 if (!session_->params().restrict_to_one_preconnect_for_proxies || | 272 if (!session_->params().restrict_to_one_preconnect_for_proxies || |
| 254 !ProxyServerSupportsPriorities(proxy_info)) { | 273 !ProxyServerSupportsPriorities(proxy_info)) { |
| 255 return false; | 274 return false; |
| 256 } | 275 } |
| 257 | 276 |
| 277 PreconnectingProxyServer preconnecting_proxy_server(proxy_info.proxy_server(), |
| 278 privacy_mode); |
| 279 |
| 258 if (base::ContainsKey(preconnecting_proxy_servers_, | 280 if (base::ContainsKey(preconnecting_proxy_servers_, |
| 259 proxy_info.proxy_server())) { | 281 preconnecting_proxy_server)) { |
| 260 UMA_HISTOGRAM_EXACT_LINEAR("Net.PreconnectSkippedToProxyServers", 1, 2); | 282 UMA_HISTOGRAM_EXACT_LINEAR("Net.PreconnectSkippedToProxyServers", 1, 2); |
| 261 // Skip preconnect to the proxy server since we are already preconnecting | 283 // Skip preconnect to the proxy server since we are already preconnecting |
| 262 // (probably via some other job). | 284 // (probably via some other job). |
| 263 return true; | 285 return true; |
| 264 } | 286 } |
| 265 | 287 |
| 266 // Add the proxy server to the set of preconnecting proxy servers. | 288 // Add the proxy server to the set of preconnecting proxy servers. |
| 267 // The maximum size of |preconnecting_proxy_servers_|. | 289 // The maximum size of |preconnecting_proxy_servers_|. |
| 268 static const size_t kMaxPreconnectingServerSize = 3; | 290 static const size_t kMaxPreconnectingServerSize = 3; |
| 269 if (preconnecting_proxy_servers_.size() >= kMaxPreconnectingServerSize) { | 291 if (preconnecting_proxy_servers_.size() >= kMaxPreconnectingServerSize) { |
| 270 // Erase the first entry. A better approach (at the cost of higher memory | 292 // Erase the first entry. A better approach (at the cost of higher memory |
| 271 // overhead) may be to erase the least recently used entry. | 293 // overhead) may be to erase the least recently used entry. |
| 272 preconnecting_proxy_servers_.erase(preconnecting_proxy_servers_.begin()); | 294 preconnecting_proxy_servers_.erase(preconnecting_proxy_servers_.begin()); |
| 273 } | 295 } |
| 274 | 296 |
| 275 preconnecting_proxy_servers_.insert(proxy_info.proxy_server()); | 297 preconnecting_proxy_servers_.insert(preconnecting_proxy_server); |
| 276 DCHECK_GE(kMaxPreconnectingServerSize, preconnecting_proxy_servers_.size()); | 298 DCHECK_GE(kMaxPreconnectingServerSize, preconnecting_proxy_servers_.size()); |
| 277 // The first preconnect should be allowed. | 299 // The first preconnect should be allowed. |
| 278 return false; | 300 return false; |
| 279 } | 301 } |
| 280 | 302 |
| 281 void HttpStreamFactoryImpl::OnStreamReady(const ProxyInfo& proxy_info) { | 303 void HttpStreamFactoryImpl::OnStreamReady(const ProxyInfo& proxy_info, |
| 304 PrivacyMode privacy_mode) { |
| 282 if (proxy_info.is_empty()) | 305 if (proxy_info.is_empty()) |
| 283 return; | 306 return; |
| 284 preconnecting_proxy_servers_.erase(proxy_info.proxy_server()); | 307 preconnecting_proxy_servers_.erase( |
| 308 PreconnectingProxyServer(proxy_info.proxy_server(), privacy_mode)); |
| 285 } | 309 } |
| 286 | 310 |
| 287 bool HttpStreamFactoryImpl::ProxyServerSupportsPriorities( | 311 bool HttpStreamFactoryImpl::ProxyServerSupportsPriorities( |
| 288 const ProxyInfo& proxy_info) const { | 312 const ProxyInfo& proxy_info) const { |
| 289 if (proxy_info.is_empty() || !proxy_info.proxy_server().is_valid()) | 313 if (proxy_info.is_empty() || !proxy_info.proxy_server().is_valid()) |
| 290 return false; | 314 return false; |
| 291 | 315 |
| 292 if (!proxy_info.proxy_server().is_https()) | 316 if (!proxy_info.proxy_server().is_https()) |
| 293 return false; | 317 return false; |
| 294 | 318 |
| 295 HostPortPair host_port_pair = proxy_info.proxy_server().host_port_pair(); | 319 HostPortPair host_port_pair = proxy_info.proxy_server().host_port_pair(); |
| 296 DCHECK(!host_port_pair.IsEmpty()); | 320 DCHECK(!host_port_pair.IsEmpty()); |
| 297 | 321 |
| 298 url::SchemeHostPort scheme_host_port("https", host_port_pair.host(), | 322 url::SchemeHostPort scheme_host_port("https", host_port_pair.host(), |
| 299 host_port_pair.port()); | 323 host_port_pair.port()); |
| 300 | 324 |
| 301 return session_->http_server_properties()->SupportsRequestPriority( | 325 return session_->http_server_properties()->SupportsRequestPriority( |
| 302 scheme_host_port); | 326 scheme_host_port); |
| 303 } | 327 } |
| 304 | 328 |
| 305 } // namespace net | 329 } // namespace net |
| OLD | NEW |