summaryrefslogtreecommitdiffstats
path: root/net/http
diff options
context:
space:
mode:
authorwillchan@chromium.org <willchan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-19 22:45:53 +0000
committerwillchan@chromium.org <willchan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-04-19 22:45:53 +0000
commit61a86c4d5644817d291e7f22ffd0b0b5cef56295 (patch)
treedfd15e590bbbf44af479f702875d24aa19d1f491 /net/http
parent74d7e1d0cb8040ba0bfe15619ccb240e5c7d5c19 (diff)
downloadchromium_src-61a86c4d5644817d291e7f22ffd0b0b5cef56295.zip
chromium_src-61a86c4d5644817d291e7f22ffd0b0b5cef56295.tar.gz
chromium_src-61a86c4d5644817d291e7f22ffd0b0b5cef56295.tar.bz2
Fix crash on IP address change.
Revert r43908: "Flush socket pools and SPDY session pool properly on explicit requests and network changes." This change was reverted on the 375 branch, but not on trunk. BUG=41190 Review URL: http://codereview.chromium.org/1604045 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@44973 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/http')
-rw-r--r--net/http/http_cache.cc8
-rw-r--r--net/http/http_network_layer.cc8
-rw-r--r--net/http/http_network_layer.h2
-rw-r--r--net/http/http_network_session.cc65
-rw-r--r--net/http/http_network_session.h21
-rw-r--r--net/http/http_network_session_unittest.cc82
-rw-r--r--net/http/http_network_transaction_unittest.cc11
7 files changed, 52 insertions, 145 deletions
diff --git a/net/http/http_cache.cc b/net/http/http_cache.cc
index f1ddaf9..3a816f7 100644
--- a/net/http/http_cache.cc
+++ b/net/http/http_cache.cc
@@ -371,8 +371,12 @@ void HttpCache::CloseCurrentConnections() {
net::HttpNetworkLayer* network =
static_cast<net::HttpNetworkLayer*>(network_layer_.get());
HttpNetworkSession* session = network->GetSession();
- if (session)
- session->Flush();
+ if (session) {
+ session->tcp_socket_pool()->CloseIdleSockets();
+ if (session->spdy_session_pool())
+ session->spdy_session_pool()->CloseAllSessions();
+ session->ReplaceTCPSocketPool();
+ }
}
//-----------------------------------------------------------------------------
diff --git a/net/http/http_network_layer.cc b/net/http/http_network_layer.cc
index 4915cd1..4e53abe 100644
--- a/net/http/http_network_layer.cc
+++ b/net/http/http_network_layer.cc
@@ -12,6 +12,7 @@
#include "net/spdy/spdy_framer.h"
#include "net/spdy/spdy_network_transaction.h"
#include "net/spdy/spdy_session.h"
+#include "net/spdy/spdy_session_pool.h"
namespace net {
@@ -56,6 +57,7 @@ HttpNetworkLayer::HttpNetworkLayer(
proxy_service_(proxy_service),
ssl_config_service_(ssl_config_service),
session_(NULL),
+ spdy_session_pool_(NULL),
http_auth_handler_factory_(http_auth_handler_factory),
suspended_(false) {
DCHECK(proxy_service_);
@@ -67,6 +69,7 @@ HttpNetworkLayer::HttpNetworkLayer(HttpNetworkSession* session)
network_change_notifier_(NULL),
ssl_config_service_(NULL),
session_(session),
+ spdy_session_pool_(session->spdy_session_pool()),
http_auth_handler_factory_(NULL),
suspended_(false) {
DCHECK(session_.get());
@@ -94,15 +97,16 @@ void HttpNetworkLayer::Suspend(bool suspend) {
suspended_ = suspend;
if (suspend && session_)
- session_->Flush();
+ session_->tcp_socket_pool()->CloseIdleSockets();
}
HttpNetworkSession* HttpNetworkLayer::GetSession() {
if (!session_) {
DCHECK(proxy_service_);
+ SpdySessionPool* spdy_pool = new SpdySessionPool;
session_ = new HttpNetworkSession(
network_change_notifier_, host_resolver_, proxy_service_,
- socket_factory_, ssl_config_service_,
+ socket_factory_, ssl_config_service_, spdy_pool,
http_auth_handler_factory_);
// These were just temps for lazy-initializing HttpNetworkSession.
network_change_notifier_ = NULL;
diff --git a/net/http/http_network_layer.h b/net/http/http_network_layer.h
index 63df00b..2d4130d 100644
--- a/net/http/http_network_layer.h
+++ b/net/http/http_network_layer.h
@@ -20,6 +20,7 @@ class HttpNetworkSession;
class NetworkChangeNotifier;
class ProxyInfo;
class ProxyService;
+class SpdySessionPool;
class SSLConfigService;
class HttpNetworkLayer : public HttpTransactionFactory {
@@ -81,6 +82,7 @@ class HttpNetworkLayer : public HttpTransactionFactory {
scoped_refptr<SSLConfigService> ssl_config_service_;
scoped_refptr<HttpNetworkSession> session_;
+ scoped_refptr<SpdySessionPool> spdy_session_pool_;
HttpAuthHandlerFactory* http_auth_handler_factory_;
diff --git a/net/http/http_network_session.cc b/net/http/http_network_session.cc
index ea8d1d7..146223b6 100644
--- a/net/http/http_network_session.cc
+++ b/net/http/http_network_session.cc
@@ -29,68 +29,49 @@ HttpNetworkSession::HttpNetworkSession(
ProxyService* proxy_service,
ClientSocketFactory* client_socket_factory,
SSLConfigService* ssl_config_service,
+ SpdySessionPool* spdy_session_pool,
HttpAuthHandlerFactory* http_auth_handler_factory)
: network_change_notifier_(network_change_notifier),
+ tcp_socket_pool_(new TCPClientSocketPool(
+ max_sockets_, max_sockets_per_group_, "Transport",
+ host_resolver, client_socket_factory, network_change_notifier_)),
+ socks_socket_pool_(new SOCKSClientSocketPool(
+ max_sockets_, max_sockets_per_group_, "SOCKS", host_resolver,
+ new TCPClientSocketPool(max_sockets_, max_sockets_per_group_,
+ "TCPForSOCKS", host_resolver,
+ client_socket_factory,
+ network_change_notifier_),
+ network_change_notifier_)),
socket_factory_(client_socket_factory),
host_resolver_(host_resolver),
- tcp_socket_pool_(CreateNewTCPSocketPool()),
- socks_socket_pool_(CreateNewSOCKSSocketPool()),
proxy_service_(proxy_service),
ssl_config_service_(ssl_config_service),
- spdy_session_pool_(new SpdySessionPool()),
+ spdy_session_pool_(spdy_session_pool),
http_auth_handler_factory_(http_auth_handler_factory) {
DCHECK(proxy_service);
DCHECK(ssl_config_service);
-
- if (network_change_notifier)
- network_change_notifier_->AddObserver(this);
}
HttpNetworkSession::~HttpNetworkSession() {
- if (network_change_notifier_)
- network_change_notifier_->RemoveObserver(this);
}
// static
void HttpNetworkSession::set_max_sockets_per_group(int socket_count) {
- DCHECK_LT(0, socket_count);
+ DCHECK(0 < socket_count);
// The following is a sanity check... but we should NEVER be near this value.
- DCHECK_GT(100, socket_count);
+ DCHECK(100 > socket_count);
max_sockets_per_group_ = socket_count;
}
-void HttpNetworkSession::Flush() {
- host_resolver()->Flush();
- tcp_socket_pool()->CloseIdleSockets();
- tcp_socket_pool_ = CreateNewTCPSocketPool();
- socks_socket_pool()->CloseIdleSockets();
- socks_socket_pool_ = CreateNewSOCKSSocketPool();
- spdy_session_pool_->CloseAllSessions();
- spdy_session_pool_ = new SpdySessionPool;
-}
-
-void HttpNetworkSession::OnIPAddressChanged() {
- Flush();
-}
-
-scoped_refptr<TCPClientSocketPool>
-HttpNetworkSession::CreateNewTCPSocketPool() {
- // TODO(vandebo) when we've completely converted to pools, the base TCP
- // pool name should get changed to TCP instead of Transport.
- return new TCPClientSocketPool(max_sockets_,
- max_sockets_per_group_,
- "Transport",
- host_resolver_,
- socket_factory_);
-}
-
-scoped_refptr<SOCKSClientSocketPool>
-HttpNetworkSession::CreateNewSOCKSSocketPool() {
- return new SOCKSClientSocketPool(
- max_sockets_, max_sockets_per_group_, "SOCKS", host_resolver_,
- new TCPClientSocketPool(max_sockets_, max_sockets_per_group_,
- "TCPForSOCKS", host_resolver_,
- socket_factory_));
+// TODO(vandebo) when we've completely converted to pools, the base TCP
+// pool name should get changed to TCP instead of Transport.
+void HttpNetworkSession::ReplaceTCPSocketPool() {
+ tcp_socket_pool_ = new TCPClientSocketPool(max_sockets_,
+ max_sockets_per_group_,
+ "Transport",
+ host_resolver_,
+ socket_factory_,
+ network_change_notifier_);
}
} // namespace net
diff --git a/net/http/http_network_session.h b/net/http/http_network_session.h
index 23ba526..8f85ce7 100644
--- a/net/http/http_network_session.h
+++ b/net/http/http_network_session.h
@@ -8,7 +8,6 @@
#include "base/ref_counted.h"
#include "base/scoped_ptr.h"
#include "net/base/host_resolver.h"
-#include "net/base/network_change_notifier.h"
#include "net/base/ssl_client_auth_cache.h"
#include "net/base/ssl_config_service.h"
#include "net/http/http_alternate_protocols.h"
@@ -26,9 +25,7 @@ class SpdySessionPool;
class NetworkChangeNotifier;
// This class holds session objects used by HttpNetworkTransaction objects.
-class HttpNetworkSession
- : public base::RefCounted<HttpNetworkSession>,
- public NetworkChangeNotifier::Observer {
+class HttpNetworkSession : public base::RefCounted<HttpNetworkSession> {
public:
HttpNetworkSession(
NetworkChangeNotifier* network_change_notifier,
@@ -36,6 +33,7 @@ class HttpNetworkSession
ProxyService* proxy_service,
ClientSocketFactory* client_socket_factory,
SSLConfigService* ssl_config_service,
+ SpdySessionPool* spdy_session_pool,
HttpAuthHandlerFactory* http_auth_handler_factory);
HttpAuthCache* auth_cache() { return &auth_cache_; }
@@ -77,11 +75,9 @@ class HttpNetworkSession
return http_auth_handler_factory_;
}
- // Flushes cached data in the HttpNetworkSession.
- void Flush();
-
- // NetworkChangeNotifier::Observer methods:
- virtual void OnIPAddressChanged();
+ // Replace the current socket pool with a new one. This effectively
+ // abandons the current pool. This is only used for debugging.
+ void ReplaceTCPSocketPool();
static void set_max_sockets_per_group(int socket_count);
@@ -97,9 +93,6 @@ class HttpNetworkSession
~HttpNetworkSession();
- scoped_refptr<TCPClientSocketPool> CreateNewTCPSocketPool();
- scoped_refptr<SOCKSClientSocketPool> CreateNewSOCKSSocketPool();
-
// Total limit of sockets. Not a constant to allow experiments.
static int max_sockets_;
@@ -115,10 +108,10 @@ class HttpNetworkSession
SSLClientAuthCache ssl_client_auth_cache_;
HttpAlternateProtocols alternate_protocols_;
NetworkChangeNotifier* const network_change_notifier_;
- ClientSocketFactory* socket_factory_;
- scoped_refptr<HostResolver> host_resolver_;
scoped_refptr<TCPClientSocketPool> tcp_socket_pool_;
scoped_refptr<SOCKSClientSocketPool> socks_socket_pool_;
+ ClientSocketFactory* socket_factory_;
+ scoped_refptr<HostResolver> host_resolver_;
scoped_refptr<ProxyService> proxy_service_;
scoped_refptr<SSLConfigService> ssl_config_service_;
scoped_refptr<SpdySessionPool> spdy_session_pool_;
diff --git a/net/http/http_network_session_unittest.cc b/net/http/http_network_session_unittest.cc
deleted file mode 100644
index 329f394c..0000000
--- a/net/http/http_network_session_unittest.cc
+++ /dev/null
@@ -1,82 +0,0 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "net/http/http_network_session.h"
-
-#include "base/ref_counted.h"
-#include "net/base/mock_host_resolver.h"
-#include "net/base/mock_network_change_notifier.h"
-#include "net/base/ssl_config_service_defaults.h"
-#include "net/base/test_completion_callback.h"
-#include "net/http/http_auth_handler_factory.h"
-#include "net/proxy/proxy_service.h"
-#include "net/socket/client_socket_handle.h"
-#include "net/socket/socket_test_util.h"
-#include "net/socket/tcp_client_socket_pool.h"
-#include "net/spdy/spdy_session.h"
-#include "net/spdy/spdy_session_pool.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace net {
-namespace {
-
-TEST(HttpNetworkSessionTest, FlushOnNetworkChange) {
- MockNetworkChangeNotifier mock_notifier;
- scoped_refptr<MockCachingHostResolver> mock_resolver(
- new MockCachingHostResolver);
- MockClientSocketFactory mock_factory;
- scoped_ptr<HttpAuthHandlerFactory> auth_handler_factory(
- HttpAuthHandlerFactory::CreateDefault());
- scoped_refptr<HttpNetworkSession> session(
- new HttpNetworkSession(&mock_notifier,
- mock_resolver,
- ProxyService::CreateNull(),
- &mock_factory,
- new SSLConfigServiceDefaults,
- auth_handler_factory.get()));
-
- scoped_refptr<TCPClientSocketPool> tcp_socket_pool(
- session->tcp_socket_pool());
-
- StaticSocketDataProvider data;
- mock_factory.AddSocketDataProvider(&data);
-
- TestCompletionCallback callback;
- ClientSocketHandle handle;
- TCPSocketParams dest("www.google.com", 80, LOW, GURL(), false);
- int rv = handle.Init("a", dest, LOW, &callback, tcp_socket_pool, NULL);
- EXPECT_EQ(ERR_IO_PENDING, rv);
- EXPECT_FALSE(handle.is_initialized());
- EXPECT_FALSE(handle.socket());
-
- EXPECT_EQ(OK, callback.WaitForResult());
- EXPECT_TRUE(handle.is_initialized());
- EXPECT_TRUE(handle.socket());
-
- handle.Reset();
-
- // Need to run all pending to release the socket back to the pool.
- MessageLoop::current()->RunAllPending();
-
- // Now we should have 1 idle socket.
- EXPECT_EQ(1, tcp_socket_pool->IdleSocketCount());
-
- HostPortPair host_port_pair("www.google.com", 80);
-
- scoped_refptr<SpdySession> spdy_session(session->spdy_session_pool()->Get(
- host_port_pair, session));
-
- EXPECT_TRUE(session->spdy_session_pool()->HasSession(host_port_pair));
-
- EXPECT_EQ(1u, mock_resolver->cache()->size());
-
- // After an IP address change, we should have 0 idle sockets.
- mock_notifier.NotifyIPAddressChange();
- EXPECT_EQ(0, tcp_socket_pool->IdleSocketCount());
- EXPECT_FALSE(session->spdy_session_pool()->HasSession(host_port_pair));
- EXPECT_EQ(0u, mock_resolver->cache()->size());
-}
-
-} // namespace
-} // namespace net
diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc
index df1604e..41408bd 100644
--- a/net/http/http_network_transaction_unittest.cc
+++ b/net/http/http_network_transaction_unittest.cc
@@ -43,20 +43,23 @@ class SessionDependencies {
: host_resolver(new MockHostResolver),
proxy_service(ProxyService::CreateNull()),
ssl_config_service(new SSLConfigServiceDefaults),
- http_auth_handler_factory(HttpAuthHandlerFactory::CreateDefault()) {}
+ http_auth_handler_factory(HttpAuthHandlerFactory::CreateDefault()),
+ spdy_session_pool(new SpdySessionPool) {}
// Custom proxy service dependency.
explicit SessionDependencies(ProxyService* proxy_service)
: host_resolver(new MockHostResolver),
proxy_service(proxy_service),
ssl_config_service(new SSLConfigServiceDefaults),
- http_auth_handler_factory(HttpAuthHandlerFactory::CreateDefault()) {}
+ http_auth_handler_factory(HttpAuthHandlerFactory::CreateDefault()),
+ spdy_session_pool(new SpdySessionPool) {}
scoped_refptr<MockHostResolverBase> host_resolver;
scoped_refptr<ProxyService> proxy_service;
scoped_refptr<SSLConfigService> ssl_config_service;
MockClientSocketFactory socket_factory;
scoped_ptr<HttpAuthHandlerFactory> http_auth_handler_factory;
+ scoped_refptr<SpdySessionPool> spdy_session_pool;
};
ProxyService* CreateFixedProxyService(const std::string& proxy) {
@@ -71,6 +74,7 @@ HttpNetworkSession* CreateSession(SessionDependencies* session_deps) {
session_deps->proxy_service,
&session_deps->socket_factory,
session_deps->ssl_config_service,
+ session_deps->spdy_session_pool,
session_deps->http_auth_handler_factory.get());
}
@@ -184,7 +188,8 @@ class CaptureGroupNameSocketPool : public EmulatedClientSocketPool {
CaptureGroupNameSocketPool(HttpNetworkSession* session,
SocketSourceType* socket_source)
: EmulatedClientSocketPool(0, 0, "CaptureGroupNameTestPool",
- session->host_resolver(), socket_source) {}
+ session->host_resolver(), socket_source,
+ NULL) {}
const std::string last_group_name_received() const {
return last_group_name_;
}