http_network_session.cc revision a3f6a49ab37290eeeb8db0f41ec0f1cb74a68be7
15c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)// found in the LICENSE file.
45c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
55c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "net/http/http_network_session.h"
65c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
75c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include <utility>
85c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
95c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "base/compiler_specific.h"
105c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "base/debug/stack_trace.h"
115c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "base/logging.h"
125c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "base/stl_util.h"
135c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "base/strings/string_util.h"
145c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "base/values.h"
155c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "net/http/http_auth_handler_factory.h"
165c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "net/http/http_response_body_drainer.h"
175c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "net/http/http_stream_factory_impl.h"
185c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "net/http/url_security_manager.h"
195c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "net/proxy/proxy_service.h"
205c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "net/quic/crypto/quic_random.h"
215c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "net/quic/quic_clock.h"
225c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "net/quic/quic_crypto_client_stream_factory.h"
235c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "net/quic/quic_stream_factory.h"
245c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "net/socket/client_socket_factory.h"
255c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "net/socket/client_socket_pool_manager_impl.h"
265c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "net/socket/next_proto.h"
275c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)#include "net/spdy/spdy_session_pool.h"
285c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
295c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace {
305c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
315c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)net::ClientSocketPoolManager* CreateSocketPoolManager(
325c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    net::HttpNetworkSession::SocketPoolType pool_type,
335c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)    const net::HttpNetworkSession::Params& params) {
3453e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)  // TODO(yutak): Differentiate WebSocket pool manager and allow more
3553e740f4a82e17f3ae59772501622dc354e42336Torne (Richard Coles)  // simultaneous connections for WebSockets.
365c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)  return new net::ClientSocketPoolManagerImpl(
375c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)      params.net_log,
385c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)      params.client_socket_factory ?
39591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch      params.client_socket_factory :
405c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)      net::ClientSocketFactory::GetDefaultFactory(),
415c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)      params.host_resolver,
4209380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)      params.cert_verifier,
435c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)      params.server_bound_cert_service,
445c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)      params.transport_security_state,
455c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)      params.cert_transparency_verifier,
4609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)      params.ssl_session_cache_shard,
475c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)      params.proxy_service,
485c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)      params.ssl_config_service,
49f79f16f17ddc4f842d7b7a38603e280e94be826aTorne (Richard Coles)      pool_type);
505c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}
515c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)
525c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)}  // unnamed namespace
5309380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
545c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)namespace net {
5509380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)
5609380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)HttpNetworkSession::Params::Params()
5709380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)    : client_socket_factory(NULL),
5809380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)      host_resolver(NULL),
5909380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)      cert_verifier(NULL),
6009380295ba73501a205346becac22c6978e4671dTorne (Richard Coles)      server_bound_cert_service(NULL),
615c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)      transport_security_state(NULL),
62521d96ec04ace82590870fb04353ec4f82bb150fTorne (Richard Coles)      cert_transparency_verifier(NULL),
63591b958dee2cf159d33a0b931e6231072eaf38d5Ben Murdoch      proxy_service(NULL),
645c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)      ssl_config_service(NULL),
655c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)      http_auth_handler_factory(NULL),
665c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)      network_delegate(NULL),
675c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)      net_log(NULL),
685c87bf8b86a7c82ef50fb7a89697d8e02e2553beTorne (Richard Coles)      host_mapping_rules(NULL),
69      force_http_pipelining(false),
70      ignore_certificate_errors(false),
71      http_pipelining_enabled(false),
72      testing_fixed_http_port(0),
73      testing_fixed_https_port(0),
74      force_spdy_single_domain(false),
75      enable_spdy_ip_pooling(true),
76      enable_spdy_compression(true),
77      enable_spdy_ping_based_connection_checking(true),
78      spdy_default_protocol(kProtoUnknown),
79      spdy_stream_initial_recv_window_size(0),
80      spdy_initial_max_concurrent_streams(0),
81      spdy_max_concurrent_streams_limit(0),
82      time_func(&base::TimeTicks::Now),
83      enable_quic(false),
84      enable_quic_https(false),
85      quic_clock(NULL),
86      quic_random(NULL),
87      quic_max_packet_length(kDefaultMaxPacketSize),
88      enable_user_alternate_protocol_ports(false),
89      quic_crypto_client_stream_factory(NULL) {
90}
91
92HttpNetworkSession::Params::~Params() {}
93
94// TODO(mbelshe): Move the socket factories into HttpStreamFactory.
95HttpNetworkSession::HttpNetworkSession(const Params& params)
96    : net_log_(params.net_log),
97      network_delegate_(params.network_delegate),
98      http_server_properties_(params.http_server_properties),
99      cert_verifier_(params.cert_verifier),
100      http_auth_handler_factory_(params.http_auth_handler_factory),
101      force_http_pipelining_(params.force_http_pipelining),
102      proxy_service_(params.proxy_service),
103      ssl_config_service_(params.ssl_config_service),
104      normal_socket_pool_manager_(
105          CreateSocketPoolManager(NORMAL_SOCKET_POOL, params)),
106      websocket_socket_pool_manager_(
107          CreateSocketPoolManager(WEBSOCKET_SOCKET_POOL, params)),
108      quic_stream_factory_(params.host_resolver,
109                           params.client_socket_factory ?
110                               params.client_socket_factory :
111                               net::ClientSocketFactory::GetDefaultFactory(),
112                           params.http_server_properties,
113                           params.quic_crypto_client_stream_factory,
114                           params.quic_random ? params.quic_random :
115                               QuicRandom::GetInstance(),
116                           params.quic_clock ? params. quic_clock :
117                               new QuicClock(),
118                           params.quic_max_packet_length),
119      spdy_session_pool_(params.host_resolver,
120                         params.ssl_config_service,
121                         params.http_server_properties,
122                         params.force_spdy_single_domain,
123                         params.enable_spdy_ip_pooling,
124                         params.enable_spdy_compression,
125                         params.enable_spdy_ping_based_connection_checking,
126                         params.spdy_default_protocol,
127                         params.spdy_stream_initial_recv_window_size,
128                         params.spdy_initial_max_concurrent_streams,
129                         params.spdy_max_concurrent_streams_limit,
130                         params.time_func,
131                         params.trusted_spdy_proxy),
132      http_stream_factory_(new HttpStreamFactoryImpl(this, false)),
133      http_stream_factory_for_websocket_(
134          new HttpStreamFactoryImpl(this, true)),
135      params_(params) {
136  DCHECK(proxy_service_);
137  DCHECK(ssl_config_service_.get());
138  CHECK(http_server_properties_);
139}
140
141HttpNetworkSession::~HttpNetworkSession() {
142  STLDeleteElements(&response_drainers_);
143  spdy_session_pool_.CloseAllSessions();
144}
145
146void HttpNetworkSession::AddResponseDrainer(HttpResponseBodyDrainer* drainer) {
147  DCHECK(!ContainsKey(response_drainers_, drainer));
148  response_drainers_.insert(drainer);
149}
150
151void HttpNetworkSession::RemoveResponseDrainer(
152    HttpResponseBodyDrainer* drainer) {
153  DCHECK(ContainsKey(response_drainers_, drainer));
154  response_drainers_.erase(drainer);
155}
156
157TransportClientSocketPool* HttpNetworkSession::GetTransportSocketPool(
158    SocketPoolType pool_type) {
159  return GetSocketPoolManager(pool_type)->GetTransportSocketPool();
160}
161
162SSLClientSocketPool* HttpNetworkSession::GetSSLSocketPool(
163    SocketPoolType pool_type) {
164  return GetSocketPoolManager(pool_type)->GetSSLSocketPool();
165}
166
167SOCKSClientSocketPool* HttpNetworkSession::GetSocketPoolForSOCKSProxy(
168    SocketPoolType pool_type,
169    const HostPortPair& socks_proxy) {
170  return GetSocketPoolManager(pool_type)->GetSocketPoolForSOCKSProxy(
171      socks_proxy);
172}
173
174HttpProxyClientSocketPool* HttpNetworkSession::GetSocketPoolForHTTPProxy(
175    SocketPoolType pool_type,
176    const HostPortPair& http_proxy) {
177  return GetSocketPoolManager(pool_type)->GetSocketPoolForHTTPProxy(http_proxy);
178}
179
180SSLClientSocketPool* HttpNetworkSession::GetSocketPoolForSSLWithProxy(
181    SocketPoolType pool_type,
182    const HostPortPair& proxy_server) {
183  return GetSocketPoolManager(pool_type)->GetSocketPoolForSSLWithProxy(
184      proxy_server);
185}
186
187base::Value* HttpNetworkSession::SocketPoolInfoToValue() const {
188  // TODO(yutak): Should merge values from normal pools and WebSocket pools.
189  return normal_socket_pool_manager_->SocketPoolInfoToValue();
190}
191
192base::Value* HttpNetworkSession::SpdySessionPoolInfoToValue() const {
193  return spdy_session_pool_.SpdySessionPoolInfoToValue();
194}
195
196base::Value* HttpNetworkSession::QuicInfoToValue() const {
197  base::DictionaryValue* dict = new base::DictionaryValue();
198  dict->Set("sessions", quic_stream_factory_.QuicStreamFactoryInfoToValue());
199  dict->SetBoolean("quic_enabled", params_.enable_quic);
200  dict->SetBoolean("quic_enabled_https", params_.enable_quic_https);
201  dict->SetString("origin_to_force_quic_on",
202                  params_.origin_to_force_quic_on.ToString());
203  return dict;
204}
205
206void HttpNetworkSession::CloseAllConnections() {
207  normal_socket_pool_manager_->FlushSocketPoolsWithError(ERR_ABORTED);
208  websocket_socket_pool_manager_->FlushSocketPoolsWithError(ERR_ABORTED);
209  spdy_session_pool_.CloseCurrentSessions(ERR_ABORTED);
210  quic_stream_factory_.CloseAllSessions(ERR_ABORTED);
211}
212
213void HttpNetworkSession::CloseIdleConnections() {
214  normal_socket_pool_manager_->CloseIdleSockets();
215  websocket_socket_pool_manager_->CloseIdleSockets();
216  spdy_session_pool_.CloseCurrentIdleSessions();
217}
218
219ClientSocketPoolManager* HttpNetworkSession::GetSocketPoolManager(
220    SocketPoolType pool_type) {
221  switch (pool_type) {
222    case NORMAL_SOCKET_POOL:
223      return normal_socket_pool_manager_.get();
224    case WEBSOCKET_SOCKET_POOL:
225      return websocket_socket_pool_manager_.get();
226    default:
227      NOTREACHED();
228      break;
229  }
230  return NULL;
231}
232
233}  //  namespace net
234