http_network_session.cc 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418
  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
  3. // found in the LICENSE file.
  4. #include "net/http/http_network_session.h"
  5. #include <inttypes.h>
  6. #include <utility>
  7. #include "base/atomic_sequence_num.h"
  8. #include "base/check_op.h"
  9. #include "base/compiler_specific.h"
  10. #include "base/containers/contains.h"
  11. #include "base/notreached.h"
  12. #include "base/strings/string_number_conversions.h"
  13. #include "base/strings/string_util.h"
  14. #include "base/strings/stringprintf.h"
  15. #include "base/values.h"
  16. #include "build/build_config.h"
  17. #include "net/base/features.h"
  18. #include "net/dns/host_resolver.h"
  19. #include "net/http/http_auth_handler_factory.h"
  20. #include "net/http/http_response_body_drainer.h"
  21. #include "net/http/http_stream_factory.h"
  22. #include "net/http/url_security_manager.h"
  23. #include "net/proxy_resolution/proxy_resolution_service.h"
  24. #include "net/quic/platform/impl/quic_chromium_clock.h"
  25. #include "net/quic/quic_crypto_client_stream_factory.h"
  26. #include "net/quic/quic_stream_factory.h"
  27. #include "net/socket/client_socket_factory.h"
  28. #include "net/socket/client_socket_pool_manager_impl.h"
  29. #include "net/socket/next_proto.h"
  30. #include "net/socket/ssl_client_socket.h"
  31. #include "net/spdy/spdy_session.h"
  32. #include "net/spdy/spdy_session_pool.h"
  33. #include "net/third_party/quiche/src/quiche/quic/core/crypto/quic_random.h"
  34. #include "net/third_party/quiche/src/quiche/quic/core/quic_packets.h"
  35. #include "net/third_party/quiche/src/quiche/quic/core/quic_tag.h"
  36. #include "net/third_party/quiche/src/quiche/quic/core/quic_utils.h"
  37. namespace net {
  38. // The maximum receive window sizes for HTTP/2 sessions and streams.
  39. const int32_t kSpdySessionMaxRecvWindowSize = 15 * 1024 * 1024; // 15 MB
  40. const int32_t kSpdyStreamMaxRecvWindowSize = 6 * 1024 * 1024; // 6 MB
  41. namespace {
  42. // Keep all HTTP2 parameters in |http2_settings|, even the ones that are not
  43. // implemented, to be sent to the server.
  44. // Set default values for settings that |http2_settings| does not specify.
  45. spdy::SettingsMap AddDefaultHttp2Settings(spdy::SettingsMap http2_settings) {
  46. // Set default values only if |http2_settings| does not have
  47. // a value set for given setting.
  48. auto it = http2_settings.find(spdy::SETTINGS_HEADER_TABLE_SIZE);
  49. if (it == http2_settings.end())
  50. http2_settings[spdy::SETTINGS_HEADER_TABLE_SIZE] = kSpdyMaxHeaderTableSize;
  51. it = http2_settings.find(spdy::SETTINGS_MAX_CONCURRENT_STREAMS);
  52. if (it == http2_settings.end())
  53. http2_settings[spdy::SETTINGS_MAX_CONCURRENT_STREAMS] =
  54. kSpdyMaxConcurrentPushedStreams;
  55. it = http2_settings.find(spdy::SETTINGS_INITIAL_WINDOW_SIZE);
  56. if (it == http2_settings.end())
  57. http2_settings[spdy::SETTINGS_INITIAL_WINDOW_SIZE] =
  58. kSpdyStreamMaxRecvWindowSize;
  59. it = http2_settings.find(spdy::SETTINGS_MAX_HEADER_LIST_SIZE);
  60. if (it == http2_settings.end())
  61. http2_settings[spdy::SETTINGS_MAX_HEADER_LIST_SIZE] =
  62. kSpdyMaxHeaderListSize;
  63. return http2_settings;
  64. }
  65. } // unnamed namespace
  66. HttpNetworkSessionParams::HttpNetworkSessionParams()
  67. : spdy_session_max_recv_window_size(kSpdySessionMaxRecvWindowSize),
  68. spdy_session_max_queued_capped_frames(kSpdySessionMaxQueuedCappedFrames),
  69. time_func(&base::TimeTicks::Now) {
  70. enable_early_data =
  71. base::FeatureList::IsEnabled(features::kEnableTLS13EarlyData);
  72. use_dns_https_svcb_alpn =
  73. base::FeatureList::IsEnabled(features::kUseDnsHttpsSvcbAlpn);
  74. }
  75. HttpNetworkSessionParams::HttpNetworkSessionParams(
  76. const HttpNetworkSessionParams& other) = default;
  77. HttpNetworkSessionParams::~HttpNetworkSessionParams() = default;
  78. HttpNetworkSessionContext::HttpNetworkSessionContext()
  79. : client_socket_factory(nullptr),
  80. host_resolver(nullptr),
  81. cert_verifier(nullptr),
  82. transport_security_state(nullptr),
  83. ct_policy_enforcer(nullptr),
  84. sct_auditing_delegate(nullptr),
  85. proxy_resolution_service(nullptr),
  86. proxy_delegate(nullptr),
  87. http_user_agent_settings(nullptr),
  88. ssl_config_service(nullptr),
  89. http_auth_handler_factory(nullptr),
  90. net_log(nullptr),
  91. socket_performance_watcher_factory(nullptr),
  92. network_quality_estimator(nullptr),
  93. quic_context(nullptr),
  94. #if BUILDFLAG(ENABLE_REPORTING)
  95. reporting_service(nullptr),
  96. network_error_logging_service(nullptr),
  97. #endif
  98. quic_crypto_client_stream_factory(
  99. QuicCryptoClientStreamFactory::GetDefaultFactory()) {
  100. }
  101. HttpNetworkSessionContext::HttpNetworkSessionContext(
  102. const HttpNetworkSessionContext& other) = default;
  103. HttpNetworkSessionContext::~HttpNetworkSessionContext() = default;
  104. // TODO(mbelshe): Move the socket factories into HttpStreamFactory.
  105. HttpNetworkSession::HttpNetworkSession(const HttpNetworkSessionParams& params,
  106. const HttpNetworkSessionContext& context)
  107. : net_log_(context.net_log),
  108. http_server_properties_(context.http_server_properties),
  109. cert_verifier_(context.cert_verifier),
  110. http_auth_handler_factory_(context.http_auth_handler_factory),
  111. host_resolver_(context.host_resolver),
  112. #if BUILDFLAG(ENABLE_REPORTING)
  113. reporting_service_(context.reporting_service),
  114. network_error_logging_service_(context.network_error_logging_service),
  115. #endif
  116. proxy_resolution_service_(context.proxy_resolution_service),
  117. ssl_config_service_(context.ssl_config_service),
  118. http_auth_cache_(
  119. params.key_auth_cache_server_entries_by_network_isolation_key),
  120. ssl_client_session_cache_(SSLClientSessionCache::Config()),
  121. ssl_client_context_(context.ssl_config_service,
  122. context.cert_verifier,
  123. context.transport_security_state,
  124. context.ct_policy_enforcer,
  125. &ssl_client_session_cache_,
  126. context.sct_auditing_delegate),
  127. quic_stream_factory_(context.net_log,
  128. context.host_resolver,
  129. context.ssl_config_service,
  130. context.client_socket_factory,
  131. context.http_server_properties,
  132. context.cert_verifier,
  133. context.ct_policy_enforcer,
  134. context.transport_security_state,
  135. context.sct_auditing_delegate,
  136. context.socket_performance_watcher_factory,
  137. context.quic_crypto_client_stream_factory,
  138. context.quic_context),
  139. spdy_session_pool_(context.host_resolver,
  140. &ssl_client_context_,
  141. context.http_server_properties,
  142. context.transport_security_state,
  143. context.quic_context->params()->supported_versions,
  144. params.enable_spdy_ping_based_connection_checking,
  145. params.enable_http2,
  146. params.enable_quic,
  147. params.spdy_session_max_recv_window_size,
  148. params.spdy_session_max_queued_capped_frames,
  149. AddDefaultHttp2Settings(params.http2_settings),
  150. params.enable_http2_settings_grease,
  151. params.greased_http2_frame,
  152. params.http2_end_stream_with_data_frame,
  153. params.enable_priority_update,
  154. params.spdy_go_away_on_ip_change,
  155. params.time_func,
  156. context.network_quality_estimator,
  157. // cleanup_sessions_on_ip_address_changed
  158. !params.ignore_ip_address_changes),
  159. http_stream_factory_(std::make_unique<HttpStreamFactory>(this)),
  160. params_(params),
  161. context_(context) {
  162. DCHECK(proxy_resolution_service_);
  163. DCHECK(ssl_config_service_);
  164. CHECK(http_server_properties_);
  165. DCHECK(context_.client_socket_factory);
  166. normal_socket_pool_manager_ = std::make_unique<ClientSocketPoolManagerImpl>(
  167. CreateCommonConnectJobParams(false /* for_websockets */),
  168. CreateCommonConnectJobParams(true /* for_websockets */),
  169. NORMAL_SOCKET_POOL,
  170. // cleanup_on_ip_address_change
  171. !params.ignore_ip_address_changes);
  172. websocket_socket_pool_manager_ =
  173. std::make_unique<ClientSocketPoolManagerImpl>(
  174. CreateCommonConnectJobParams(false /* for_websockets */),
  175. CreateCommonConnectJobParams(true /* for_websockets */),
  176. WEBSOCKET_SOCKET_POOL,
  177. // cleanup_on_ip_address_change
  178. !params.ignore_ip_address_changes);
  179. if (params_.enable_http2) {
  180. next_protos_.push_back(kProtoHTTP2);
  181. if (base::FeatureList::IsEnabled(features::kAlpsForHttp2)) {
  182. // Enable ALPS for HTTP/2 with empty data.
  183. application_settings_[kProtoHTTP2] = {};
  184. }
  185. }
  186. next_protos_.push_back(kProtoHTTP11);
  187. http_server_properties_->SetMaxServerConfigsStoredInProperties(
  188. context.quic_context->params()->max_server_configs_stored_in_properties);
  189. http_server_properties_->SetBrokenAlternativeServicesDelayParams(
  190. context.quic_context->params()
  191. ->initial_delay_for_broken_alternative_service,
  192. context.quic_context->params()->exponential_backoff_on_initial_delay);
  193. if (!params_.disable_idle_sockets_close_on_memory_pressure) {
  194. memory_pressure_listener_ = std::make_unique<base::MemoryPressureListener>(
  195. FROM_HERE, base::BindRepeating(&HttpNetworkSession::OnMemoryPressure,
  196. base::Unretained(this)));
  197. }
  198. }
  199. HttpNetworkSession::~HttpNetworkSession() {
  200. DCHECK_CALLED_ON_VALID_THREAD(thread_checker_);
  201. response_drainers_.clear();
  202. // TODO(bnc): CloseAllSessions() is also called in SpdySessionPool destructor,
  203. // one of the two calls should be removed.
  204. spdy_session_pool_.CloseAllSessions();
  205. }
  206. void HttpNetworkSession::StartResponseDrainer(
  207. std::unique_ptr<HttpResponseBodyDrainer> drainer) {
  208. DCHECK(!base::Contains(response_drainers_, drainer.get()));
  209. HttpResponseBodyDrainer* drainer_ptr = drainer.get();
  210. response_drainers_.insert(std::move(drainer));
  211. drainer_ptr->Start(this);
  212. }
  213. void HttpNetworkSession::RemoveResponseDrainer(
  214. HttpResponseBodyDrainer* drainer) {
  215. DCHECK(base::Contains(response_drainers_, drainer));
  216. response_drainers_.erase(response_drainers_.find(drainer));
  217. }
  218. ClientSocketPool* HttpNetworkSession::GetSocketPool(
  219. SocketPoolType pool_type,
  220. const ProxyServer& proxy_server) {
  221. return GetSocketPoolManager(pool_type)->GetSocketPool(proxy_server);
  222. }
  223. base::Value HttpNetworkSession::SocketPoolInfoToValue() const {
  224. // TODO(yutak): Should merge values from normal pools and WebSocket pools.
  225. return normal_socket_pool_manager_->SocketPoolInfoToValue();
  226. }
  227. std::unique_ptr<base::Value> HttpNetworkSession::SpdySessionPoolInfoToValue()
  228. const {
  229. return spdy_session_pool_.SpdySessionPoolInfoToValue();
  230. }
  231. base::Value HttpNetworkSession::QuicInfoToValue() const {
  232. base::Value::Dict dict;
  233. dict.Set("sessions", quic_stream_factory_.QuicStreamFactoryInfoToValue());
  234. dict.Set("quic_enabled", IsQuicEnabled());
  235. const QuicParams* quic_params = context_.quic_context->params();
  236. base::Value::List connection_options;
  237. for (const auto& option : quic_params->connection_options)
  238. connection_options.Append(quic::QuicTagToString(option));
  239. dict.Set("connection_options", std::move(connection_options));
  240. base::Value::List supported_versions;
  241. for (const auto& version : quic_params->supported_versions)
  242. supported_versions.Append(ParsedQuicVersionToString(version));
  243. dict.Set("supported_versions", std::move(supported_versions));
  244. base::Value::List origins_to_force_quic_on;
  245. for (const auto& origin : quic_params->origins_to_force_quic_on)
  246. origins_to_force_quic_on.Append(origin.ToString());
  247. dict.Set("origins_to_force_quic_on", std::move(origins_to_force_quic_on));
  248. dict.Set("max_packet_length",
  249. static_cast<int>(quic_params->max_packet_length));
  250. dict.Set(
  251. "max_server_configs_stored_in_properties",
  252. static_cast<int>(quic_params->max_server_configs_stored_in_properties));
  253. dict.Set("idle_connection_timeout_seconds",
  254. static_cast<int>(quic_params->idle_connection_timeout.InSeconds()));
  255. dict.Set("reduced_ping_timeout_seconds",
  256. static_cast<int>(quic_params->reduced_ping_timeout.InSeconds()));
  257. dict.Set("retry_without_alt_svc_on_quic_errors",
  258. quic_params->retry_without_alt_svc_on_quic_errors);
  259. dict.Set("disable_bidirectional_streams",
  260. quic_params->disable_bidirectional_streams);
  261. dict.Set("close_sessions_on_ip_change",
  262. quic_params->close_sessions_on_ip_change);
  263. dict.Set("goaway_sessions_on_ip_change",
  264. quic_params->goaway_sessions_on_ip_change);
  265. dict.Set("migrate_sessions_on_network_change_v2",
  266. quic_params->migrate_sessions_on_network_change_v2);
  267. dict.Set("migrate_sessions_early_v2", quic_params->migrate_sessions_early_v2);
  268. dict.Set("retransmittable_on_wire_timeout_milliseconds",
  269. static_cast<int>(
  270. quic_params->retransmittable_on_wire_timeout.InMilliseconds()));
  271. dict.Set("retry_on_alternate_network_before_handshake",
  272. quic_params->retry_on_alternate_network_before_handshake);
  273. dict.Set("migrate_idle_sessions", quic_params->migrate_idle_sessions);
  274. dict.Set(
  275. "idle_session_migration_period_seconds",
  276. static_cast<int>(quic_params->idle_session_migration_period.InSeconds()));
  277. dict.Set("max_time_on_non_default_network_seconds",
  278. static_cast<int>(
  279. quic_params->max_time_on_non_default_network.InSeconds()));
  280. dict.Set("max_num_migrations_to_non_default_network_on_write_error",
  281. quic_params->max_migrations_to_non_default_network_on_write_error);
  282. dict.Set(
  283. "max_num_migrations_to_non_default_network_on_path_degrading",
  284. quic_params->max_migrations_to_non_default_network_on_path_degrading);
  285. dict.Set("allow_server_migration", quic_params->allow_server_migration);
  286. dict.Set("race_stale_dns_on_connection",
  287. quic_params->race_stale_dns_on_connection);
  288. dict.Set("estimate_initial_rtt", quic_params->estimate_initial_rtt);
  289. dict.Set("server_push_cancellation", params_.enable_server_push_cancellation);
  290. dict.Set("initial_rtt_for_handshake_milliseconds",
  291. static_cast<int>(
  292. quic_params->initial_rtt_for_handshake.InMilliseconds()));
  293. return base::Value(std::move(dict));
  294. }
  295. void HttpNetworkSession::CloseAllConnections(int net_error,
  296. const char* net_log_reason_utf8) {
  297. normal_socket_pool_manager_->FlushSocketPoolsWithError(net_error,
  298. net_log_reason_utf8);
  299. websocket_socket_pool_manager_->FlushSocketPoolsWithError(
  300. net_error, net_log_reason_utf8);
  301. spdy_session_pool_.CloseCurrentSessions(static_cast<net::Error>(net_error));
  302. quic_stream_factory_.CloseAllSessions(net_error, quic::QUIC_PEER_GOING_AWAY);
  303. }
  304. void HttpNetworkSession::CloseIdleConnections(const char* net_log_reason_utf8) {
  305. normal_socket_pool_manager_->CloseIdleSockets(net_log_reason_utf8);
  306. websocket_socket_pool_manager_->CloseIdleSockets(net_log_reason_utf8);
  307. spdy_session_pool_.CloseCurrentIdleSessions(net_log_reason_utf8);
  308. }
  309. void HttpNetworkSession::SetServerPushDelegate(
  310. std::unique_ptr<ServerPushDelegate> push_delegate) {
  311. DCHECK(push_delegate);
  312. if (!params_.enable_server_push_cancellation || push_delegate_)
  313. return;
  314. push_delegate_ = std::move(push_delegate);
  315. spdy_session_pool_.set_server_push_delegate(push_delegate_.get());
  316. quic_stream_factory_.set_server_push_delegate(push_delegate_.get());
  317. }
  318. bool HttpNetworkSession::IsQuicEnabled() const {
  319. return params_.enable_quic;
  320. }
  321. void HttpNetworkSession::DisableQuic() {
  322. params_.enable_quic = false;
  323. }
  324. void HttpNetworkSession::ClearSSLSessionCache() {
  325. ssl_client_session_cache_.Flush();
  326. }
  327. CommonConnectJobParams HttpNetworkSession::CreateCommonConnectJobParams(
  328. bool for_websockets) {
  329. // Use null websocket_endpoint_lock_manager, which is only set for WebSockets,
  330. // and only when not using a proxy.
  331. return CommonConnectJobParams(
  332. context_.client_socket_factory, context_.host_resolver, &http_auth_cache_,
  333. context_.http_auth_handler_factory, &spdy_session_pool_,
  334. &context_.quic_context->params()->supported_versions,
  335. &quic_stream_factory_, context_.proxy_delegate,
  336. context_.http_user_agent_settings, &ssl_client_context_,
  337. context_.socket_performance_watcher_factory,
  338. context_.network_quality_estimator, context_.net_log,
  339. for_websockets ? &websocket_endpoint_lock_manager_ : nullptr);
  340. }
  341. ClientSocketPoolManager* HttpNetworkSession::GetSocketPoolManager(
  342. SocketPoolType pool_type) {
  343. switch (pool_type) {
  344. case NORMAL_SOCKET_POOL:
  345. return normal_socket_pool_manager_.get();
  346. case WEBSOCKET_SOCKET_POOL:
  347. return websocket_socket_pool_manager_.get();
  348. default:
  349. NOTREACHED();
  350. break;
  351. }
  352. return nullptr;
  353. }
  354. void HttpNetworkSession::OnMemoryPressure(
  355. base::MemoryPressureListener::MemoryPressureLevel memory_pressure_level) {
  356. DCHECK(!params_.disable_idle_sockets_close_on_memory_pressure);
  357. switch (memory_pressure_level) {
  358. case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_NONE:
  359. break;
  360. case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_MODERATE:
  361. case base::MemoryPressureListener::MEMORY_PRESSURE_LEVEL_CRITICAL:
  362. CloseIdleConnections("Low memory");
  363. break;
  364. }
  365. }
  366. } // namespace net