summaryrefslogtreecommitdiffstats
path: root/net/http
diff options
context:
space:
mode:
authordarin@google.com <darin@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-08-06 23:57:07 +0000
committerdarin@google.com <darin@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2008-08-06 23:57:07 +0000
commite1e0626250c6accd6e72168636630ce2aedf4953 (patch)
tree0b6206aac9e8140eba48f6bb1e261926d448f1eb /net/http
parent78b02d540d5d4ee753b319b4811842273be9d509 (diff)
downloadchromium_src-e1e0626250c6accd6e72168636630ce2aedf4953.zip
chromium_src-e1e0626250c6accd6e72168636630ce2aedf4953.tar.gz
chromium_src-e1e0626250c6accd6e72168636630ce2aedf4953.tar.bz2
Rename HttpConnection to ClientSocketHandle, and rename HttpConnectionManager to ClientSocketPool.
The max number of sockets per group is now a constructor argument to ClientSocketPool. I also changed the API on the pool to take ClientSocketHandle pointers. The former SocketHandle typedef is now a private ClientSocketPtr typedef for use within the implementation of ClientSocketPool. git-svn-id: svn://svn.chromium.org/chrome/trunk/src@471 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/http')
-rw-r--r--net/http/http_connection.cc64
-rw-r--r--net/http/http_connection.h97
-rw-r--r--net/http/http_connection_manager.cc208
-rw-r--r--net/http/http_connection_manager.h138
-rw-r--r--net/http/http_connection_manager_unittest.cc271
-rw-r--r--net/http/http_network_layer.cc2
-rw-r--r--net/http/http_network_session.h13
-rw-r--r--net/http/http_network_transaction.cc2
8 files changed, 11 insertions, 784 deletions
diff --git a/net/http/http_connection.cc b/net/http/http_connection.cc
deleted file mode 100644
index 0ca8a3d..0000000
--- a/net/http/http_connection.cc
+++ /dev/null
@@ -1,64 +0,0 @@
-// Copyright 2008, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#include "net/http/http_connection.h"
-
-#include "net/base/client_socket.h"
-#include "net/http/http_connection_manager.h"
-
-namespace net {
-
-HttpConnection::HttpConnection(HttpConnectionManager* mgr)
- : mgr_(mgr), socket_(NULL) {
-}
-
-HttpConnection::~HttpConnection() {
- Reset();
-}
-
-int HttpConnection::Init(const std::string& group_name,
- CompletionCallback* callback) {
- Reset();
- group_name_ = group_name;
- return mgr_->RequestSocket(group_name_, &socket_, callback);
-}
-
-void HttpConnection::Reset() {
- if (group_name_.empty()) // Was Init called?
- return;
- if (socket_) {
- mgr_->ReleaseSocket(group_name_, socket_);
- socket_ = NULL;
- } else {
- mgr_->CancelRequest(group_name_, &socket_);
- }
- group_name_.clear();
-}
-
-} // namespace net
diff --git a/net/http/http_connection.h b/net/http/http_connection.h
deleted file mode 100644
index e3a6496..0000000
--- a/net/http/http_connection.h
+++ /dev/null
@@ -1,97 +0,0 @@
-// Copyright 2008, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#ifndef NET_HTTP_HTTP_CONNECTION_H_
-#define NET_HTTP_HTTP_CONNECTION_H_
-
-#include <string>
-
-#include "base/ref_counted.h"
-#include "base/scoped_ptr.h"
-#include "net/base/client_socket.h"
-#include "net/base/completion_callback.h"
-
-namespace net {
-
-class HttpConnectionManager;
-
-// A container for a ClientSocket, representing a HTTP connection.
-//
-// The connection's |group_name| uniquely identifies the origin and type of the
-// connection. It is used by the HttpConnectionManager to group similar http
-// connection objects.
-//
-// A connection object is initialized with a null socket. It is the consumer's
-// job to initialize a ClientSocket object and set it on the connection.
-//
-class HttpConnection {
- public:
- explicit HttpConnection(HttpConnectionManager* mgr);
- ~HttpConnection();
-
- // Initializes a HttpConnection object, which involves talking to the
- // HttpConnectionManager to locate a socket to possibly reuse. This method
- // returns either OK or ERR_IO_PENDING.
- //
- // If this method succeeds, then the socket member will be set to an existing
- // socket if an existing socket was available to reuse. Otherwise, the
- // consumer should set the socket member of this connection object.
- //
- // This method returns ERR_IO_PENDING if it cannot complete synchronously, in
- // which case the consumer should wait for the completion callback to run.
- //
- // Init may be called multiple times.
- //
- int Init(const std::string& group_name, CompletionCallback* callback);
-
- // An initialized connection can be reset, which causes it to return to the
- // un-initialized state. This releases the underlying socket, which in the
- // case of a socket that is not disconnected, indicates that the socket may
- // be kept alive for use by a subsequent HttpConnection. NOTE: To prevent
- // the socket from being kept alive, be sure to call its Disconnect method.
- void Reset();
-
- // Returns true when Init has completed successfully.
- bool is_initialized() const { return socket_ != NULL; }
-
- // These may only be used if is_initialized() is true.
- ClientSocket* socket() { return socket_->get(); }
- void set_socket(ClientSocket* s) { socket_->reset(s); }
-
- private:
- scoped_refptr<HttpConnectionManager> mgr_;
- scoped_ptr<ClientSocket>* socket_;
- std::string group_name_;
-
- DISALLOW_EVIL_CONSTRUCTORS(HttpConnection);
-};
-
-} // namespace net
-
-#endif // NET_HTTP_HTTP_CONNECTION_H_
diff --git a/net/http/http_connection_manager.cc b/net/http/http_connection_manager.cc
deleted file mode 100644
index 7064c4f..0000000
--- a/net/http/http_connection_manager.cc
+++ /dev/null
@@ -1,208 +0,0 @@
-// Copyright 2008, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#include "net/http/http_connection_manager.h"
-
-#include "base/message_loop.h"
-#include "net/base/client_socket.h"
-#include "net/base/net_errors.h"
-
-namespace {
-
-// The timeout value, in seconds, used to clean up disconnected idle sockets.
-const int kCleanupInterval = 5;
-
-} // namespace
-
-namespace net {
-
-HttpConnectionManager::HttpConnectionManager()
- : timer_(TimeDelta::FromSeconds(kCleanupInterval)),
- idle_socket_count_(0) {
- timer_.set_task(this);
-}
-
-HttpConnectionManager::~HttpConnectionManager() {
- timer_.set_task(NULL);
-
- // Clean up any idle sockets. Assert that we have no remaining active sockets
- // or pending requests. They should have all been cleaned up prior to the
- // manager being destroyed.
-
- CloseIdleSockets();
- DCHECK(group_map_.empty());
-}
-
-int HttpConnectionManager::RequestSocket(const std::string& group_name,
- SocketHandle** handle,
- CompletionCallback* callback) {
- Group& group = group_map_[group_name];
-
- // Can we make another active socket now?
- if (group.active_socket_count == kMaxSocketsPerGroup) {
- Request r;
- r.result = handle;
- DCHECK(callback);
- r.callback = callback;
- group.pending_requests.push_back(r);
- return ERR_IO_PENDING;
- }
-
- // OK, we are going to activate one.
- group.active_socket_count++;
-
- // Use idle sockets in LIFO order because they're more likely to be
- // still connected.
- while (!group.idle_sockets.empty()) {
- SocketHandle* h = group.idle_sockets.back();
- group.idle_sockets.pop_back();
- DecrementIdleCount();
- if (h->get()->IsConnected()) {
- // We found one we can reuse!
- *handle = h;
- return OK;
- }
- delete h;
- }
-
- *handle = new SocketHandle();
- return OK;
-}
-
-void HttpConnectionManager::CancelRequest(const std::string& group_name,
- SocketHandle** handle) {
- Group& group = group_map_[group_name];
-
- // In order for us to be canceling a pending request, we must have active
- // sockets equaling the limit. NOTE: The correctness of the code doesn't
- // require this assertion.
- DCHECK(group.active_socket_count == kMaxSocketsPerGroup);
-
- // Search pending_requests for matching handle.
- std::deque<Request>::iterator it = group.pending_requests.begin();
- for (; it != group.pending_requests.end(); ++it) {
- if (it->result == handle) {
- group.pending_requests.erase(it);
- break;
- }
- }
-}
-
-void HttpConnectionManager::ReleaseSocket(const std::string& group_name,
- SocketHandle* handle) {
- // Run this asynchronously to allow the caller to finish before we let
- // another to begin doing work. This also avoids nasty recursion issues.
- MessageLoop::current()->PostTask(FROM_HERE, NewRunnableMethod(
- this, &HttpConnectionManager::DoReleaseSocket, group_name, handle));
-}
-
-void HttpConnectionManager::CloseIdleSockets() {
- MaybeCloseIdleSockets(false);
-}
-
-void HttpConnectionManager::MaybeCloseIdleSockets(
- bool only_if_disconnected) {
- if (idle_socket_count_ == 0)
- return;
-
- GroupMap::iterator i = group_map_.begin();
- while (i != group_map_.end()) {
- Group& group = i->second;
-
- std::deque<SocketHandle*>::iterator j = group.idle_sockets.begin();
- while (j != group.idle_sockets.end()) {
- if (!only_if_disconnected || !(*j)->get()->IsConnected()) {
- delete *j;
- j = group.idle_sockets.erase(j);
- DecrementIdleCount();
- } else {
- ++j;
- }
- }
-
- // Delete group if no longer needed.
- if (group.active_socket_count == 0 && group.idle_sockets.empty()) {
- DCHECK(group.pending_requests.empty());
- group_map_.erase(i++);
- } else {
- ++i;
- }
- }
-}
-
-void HttpConnectionManager::IncrementIdleCount() {
- if (++idle_socket_count_ == 1)
- timer_.Start();
-}
-
-void HttpConnectionManager::DecrementIdleCount() {
- if (--idle_socket_count_ == 0)
- timer_.Stop();
-}
-
-void HttpConnectionManager::DoReleaseSocket(const std::string& group_name,
- SocketHandle* handle) {
- GroupMap::iterator i = group_map_.find(group_name);
- DCHECK(i != group_map_.end());
-
- Group& group = i->second;
-
- DCHECK(group.active_socket_count > 0);
- group.active_socket_count--;
-
- bool can_reuse = handle->get() && handle->get()->IsConnected();
- if (can_reuse) {
- group.idle_sockets.push_back(handle);
- IncrementIdleCount();
- } else {
- delete handle;
- }
-
- // Process one pending request.
- if (!group.pending_requests.empty()) {
- Request r = group.pending_requests.front();
- group.pending_requests.pop_front();
- int rv = RequestSocket(i->first, r.result, NULL);
- DCHECK(rv == OK);
- r.callback->Run(rv);
- return;
- }
-
- // Delete group if no longer needed.
- if (group.active_socket_count == 0 && group.idle_sockets.empty()) {
- DCHECK(group.pending_requests.empty());
- group_map_.erase(i);
- }
-}
-
-void HttpConnectionManager::Run() {
- MaybeCloseIdleSockets(true);
-}
-
-} // namespace net
diff --git a/net/http/http_connection_manager.h b/net/http/http_connection_manager.h
deleted file mode 100644
index fc5402c..0000000
--- a/net/http/http_connection_manager.h
+++ /dev/null
@@ -1,138 +0,0 @@
-// Copyright 2008, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#ifndef NET_HTTP_HTTP_CONNECTION_MANAGER_H_
-#define NET_HTTP_HTTP_CONNECTION_MANAGER_H_
-
-#include <deque>
-#include <map>
-#include <string>
-
-#include "base/ref_counted.h"
-#include "base/timer.h"
-#include "net/base/completion_callback.h"
-
-namespace net {
-
-class ClientSocket;
-
-// A HttpConnectionManager is used to restrict the number of HTTP sockets
-// open at a time. It also maintains a list of idle persistent sockets.
-//
-// The HttpConnectionManager allocates SocketHandle objects, but it is not
-// responsible for allocating the associated ClientSocket objects. The
-// consumer must do so if it gets a SocketHandle with a null ClientSocket.
-//
-class HttpConnectionManager : public base::RefCounted<HttpConnectionManager>,
- public Task {
- public:
- HttpConnectionManager();
-
- // The maximum number of simultaneous sockets per group.
- enum { kMaxSocketsPerGroup = 6 };
-
- typedef scoped_ptr<ClientSocket> SocketHandle;
-
- // Called to get access to a SocketHandle object for the given group name.
- //
- // If this function returns OK, then |*handle| will reference a SocketHandle
- // object. If ERR_IO_PENDING is returned, then the completion callback will
- // be called when |*handle| has been populated.
- //
- // If the resultant SocketHandle object has a null member, then it is the
- // caller's job to create a ClientSocket and associate it with the handle.
- //
- int RequestSocket(const std::string& group_name, SocketHandle** handle,
- CompletionCallback* callback);
-
- // Called to cancel a RequestSocket call that returned ERR_IO_PENDING. The
- // same group_name and handle parameters must be passed to this method as
- // were passed to the RequestSocket call being cancelled. The associated
- // CompletionCallback is not run.
- void CancelRequest(const std::string& group_name, SocketHandle** handle);
-
- // Called to release a SocketHandle object that is no longer in use. If the
- // handle has a ClientSocket that is still connected, then this handle may be
- // added to the keep-alive set of sockets.
- void ReleaseSocket(const std::string& group_name, SocketHandle* handle);
-
- // Called to close any idle connections held by the connection manager.
- void CloseIdleSockets();
-
- private:
- friend class base::RefCounted<HttpConnectionManager>;
-
- ~HttpConnectionManager();
-
- // Closes all idle sockets if |only_if_disconnected| is false. Else, only
- // idle sockets that are disconnected get closed. "Maybe" refers to the
- // fact that it doesn't close all idle sockets if |only_if_disconnected| is
- // true.
- void MaybeCloseIdleSockets(bool only_if_disconnected);
-
- // Called when the number of idle sockets changes.
- void IncrementIdleCount();
- void DecrementIdleCount();
-
- // Called via PostTask by ReleaseSocket.
- void DoReleaseSocket(const std::string& group_name, SocketHandle* handle);
-
- // Task implementation. This method scans the idle sockets checking to see
- // if any have been disconnected.
- virtual void Run();
-
- // A Request is allocated per call to RequestSocket that results in
- // ERR_IO_PENDING.
- struct Request {
- SocketHandle** result;
- CompletionCallback* callback;
- };
-
- // A Group is allocated per group_name when there are idle sockets or pending
- // requests. Otherwise, the Group object is removed from the map.
- struct Group {
- Group() : active_socket_count(0) {}
- std::deque<SocketHandle*> idle_sockets;
- std::deque<Request> pending_requests;
- int active_socket_count;
- };
-
- typedef std::map<std::string, Group> GroupMap;
- GroupMap group_map_;
-
- // Timer used to periodically prune sockets that have been disconnected.
- RepeatingTimer timer_;
-
- // The total number of idle sockets in the system.
- int idle_socket_count_;
-};
-
-} // namespace net
-
-#endif // NET_HTTP_HTTP_CONNECTION_MANAGER_H_
diff --git a/net/http/http_connection_manager_unittest.cc b/net/http/http_connection_manager_unittest.cc
deleted file mode 100644
index 503097b..0000000
--- a/net/http/http_connection_manager_unittest.cc
+++ /dev/null
@@ -1,271 +0,0 @@
-// Copyright 2008, Google Inc.
-// All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following disclaimer
-// in the documentation and/or other materials provided with the
-// distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-#include "base/message_loop.h"
-#include "net/base/client_socket.h"
-#include "net/base/net_errors.h"
-#include "net/http/http_connection_manager.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace {
-
-typedef testing::Test HttpConnectionManagerTest;
-
-class MockClientSocket : public net::ClientSocket {
- public:
- MockClientSocket() : connected_(false) {
- allocation_count++;
- }
-
- // ClientSocket methods:
- virtual int Connect(net::CompletionCallback* callback) {
- connected_ = true;
- return net::OK;
- }
- virtual int ReconnectIgnoringLastError(net::CompletionCallback* callback) {
- return net::ERR_FAILED;
- }
- virtual void Disconnect() {
- connected_ = false;
- }
- virtual bool IsConnected() const {
- return connected_;
- }
-
- // Socket methods:
- virtual int Read(char* buf, int buf_len,
- net::CompletionCallback* callback) {
- return net::ERR_FAILED;
- }
- virtual int Write(const char* buf, int buf_len,
- net::CompletionCallback* callback) {
- return net::ERR_FAILED;
- }
-
- static int allocation_count;
-
- private:
- bool connected_;
-};
-
-int MockClientSocket::allocation_count = 0;
-
-class TestSocketRequest : public CallbackRunner< Tuple1<int> > {
- public:
- TestSocketRequest() : handle(NULL) {}
-
- net::HttpConnectionManager::SocketHandle* handle;
-
- void InitHandle() {
- DCHECK(handle);
- if (!handle->get()) {
- handle->reset(new MockClientSocket());
- handle->get()->Connect(NULL);
- }
- }
-
- virtual void RunWithParams(const Tuple1<int>& params) {
- DCHECK(params.a == net::OK);
- completion_count++;
- InitHandle();
- }
-
- static int completion_count;
-};
-
-int TestSocketRequest::completion_count = 0;
-
-// Call ReleaseSocket and wait for it to complete. It runs via PostTask, so we
-// can just empty the MessageLoop to ensure that ReleaseSocket finished.
-void CallReleaseSocket(net::HttpConnectionManager* connection_mgr,
- const std::string& group_name,
- net::HttpConnectionManager::SocketHandle* handle) {
- connection_mgr->ReleaseSocket(group_name, handle);
- MessageLoop::current()->Quit();
- MessageLoop::current()->Run();
-}
-
-} // namespace
-
-TEST(HttpConnectionManagerTest, Basic) {
- scoped_refptr<net::HttpConnectionManager> mgr =
- new net::HttpConnectionManager();
-
- TestSocketRequest r;
- int rv;
-
- rv = mgr->RequestSocket("a", &r.handle, &r);
- EXPECT_EQ(net::OK, rv);
- EXPECT_TRUE(r.handle != NULL);
-
- CallReleaseSocket(mgr, "a", r.handle);
-}
-
-TEST(HttpConnectionManagerTest, WithIdleConnection) {
- scoped_refptr<net::HttpConnectionManager> mgr =
- new net::HttpConnectionManager();
-
- TestSocketRequest r;
- int rv;
-
- rv = mgr->RequestSocket("a", &r.handle, &r);
- EXPECT_EQ(net::OK, rv);
- EXPECT_TRUE(r.handle != NULL);
-
- r.InitHandle();
-
- CallReleaseSocket(mgr, "a", r.handle);
-}
-
-TEST(HttpConnectionManagerTest, PendingRequests) {
- scoped_refptr<net::HttpConnectionManager> mgr =
- new net::HttpConnectionManager();
-
- int rv;
-
- TestSocketRequest reqs[
- net::HttpConnectionManager::kMaxSocketsPerGroup + 10];
-
- // Reset
- MockClientSocket::allocation_count = 0;
- TestSocketRequest::completion_count = 0;
-
- // Create connections or queue up requests.
- for (size_t i = 0; i < arraysize(reqs); ++i) {
- rv = mgr->RequestSocket("a", &reqs[i].handle, &reqs[i]);
- if (rv != net::ERR_IO_PENDING) {
- EXPECT_EQ(net::OK, rv);
- reqs[i].InitHandle();
- }
- }
-
- // Release any connections until we have no connections.
- bool released_one;
- do {
- released_one = false;
- for (size_t i = 0; i < arraysize(reqs); ++i) {
- if (reqs[i].handle) {
- CallReleaseSocket(mgr, "a", reqs[i].handle);
- reqs[i].handle = NULL;
- released_one = true;
- }
- }
- } while (released_one);
-
- EXPECT_EQ(net::HttpConnectionManager::kMaxSocketsPerGroup,
- MockClientSocket::allocation_count);
- EXPECT_EQ(10, TestSocketRequest::completion_count);
-}
-
-TEST(HttpConnectionManagerTest, PendingRequests_NoKeepAlive) {
- scoped_refptr<net::HttpConnectionManager> mgr =
- new net::HttpConnectionManager();
-
- int rv;
-
- TestSocketRequest reqs[
- net::HttpConnectionManager::kMaxSocketsPerGroup + 10];
-
- // Reset
- MockClientSocket::allocation_count = 0;
- TestSocketRequest::completion_count = 0;
-
- // Create connections or queue up requests.
- for (size_t i = 0; i < arraysize(reqs); ++i) {
- rv = mgr->RequestSocket("a", &reqs[i].handle, &reqs[i]);
- if (rv != net::ERR_IO_PENDING) {
- EXPECT_EQ(net::OK, rv);
- reqs[i].InitHandle();
- }
- }
-
- // Release any connections until we have no connections.
- bool released_one;
- do {
- released_one = false;
- for (size_t i = 0; i < arraysize(reqs); ++i) {
- if (reqs[i].handle) {
- reqs[i].handle->get()->Disconnect();
- CallReleaseSocket(mgr, "a", reqs[i].handle);
- reqs[i].handle = NULL;
- released_one = true;
- }
- }
- } while (released_one);
-
- EXPECT_EQ(net::HttpConnectionManager::kMaxSocketsPerGroup + 10,
- MockClientSocket::allocation_count);
- EXPECT_EQ(10, TestSocketRequest::completion_count);
-}
-
-TEST(HttpConnectionManagerTest, CancelRequest) {
- scoped_refptr<net::HttpConnectionManager> mgr =
- new net::HttpConnectionManager();
-
- int rv;
-
- TestSocketRequest reqs[
- net::HttpConnectionManager::kMaxSocketsPerGroup + 10];
-
- // Reset
- MockClientSocket::allocation_count = 0;
- TestSocketRequest::completion_count = 0;
-
- // Create connections or queue up requests.
- for (size_t i = 0; i < arraysize(reqs); ++i) {
- rv = mgr->RequestSocket("a", &reqs[i].handle, &reqs[i]);
- if (rv != net::ERR_IO_PENDING) {
- EXPECT_EQ(net::OK, rv);
- reqs[i].InitHandle();
- }
- }
-
- // Cancel a request.
- size_t index_to_cancel =
- net::HttpConnectionManager::kMaxSocketsPerGroup + 2;
- EXPECT_TRUE(reqs[index_to_cancel].handle == NULL);
- mgr->CancelRequest("a", &reqs[index_to_cancel].handle);
-
- // Release any connections until we have no connections.
- bool released_one;
- do {
- released_one = false;
- for (size_t i = 0; i < arraysize(reqs); ++i) {
- if (reqs[i].handle) {
- CallReleaseSocket(mgr, "a", reqs[i].handle);
- reqs[i].handle = NULL;
- released_one = true;
- }
- }
- } while (released_one);
-
- EXPECT_EQ(net::HttpConnectionManager::kMaxSocketsPerGroup,
- MockClientSocket::allocation_count);
- EXPECT_EQ(9, TestSocketRequest::completion_count);
-}
diff --git a/net/http/http_network_layer.cc b/net/http/http_network_layer.cc
index 2fd846c..426b987 100644
--- a/net/http/http_network_layer.cc
+++ b/net/http/http_network_layer.cc
@@ -93,7 +93,7 @@ void HttpNetworkLayer::Suspend(bool suspend) {
suspended_ = suspend;
if (suspend)
- session_->connection_manager()->CloseIdleSockets();
+ session_->connection_pool()->CloseIdleSockets();
}
} // namespace net
diff --git a/net/http/http_network_session.h b/net/http/http_network_session.h
index dc31ed1..58cbb2f 100644
--- a/net/http/http_network_session.h
+++ b/net/http/http_network_session.h
@@ -32,7 +32,7 @@
#include "base/ref_counted.h"
#include "net/base/auth_cache.h"
-#include "net/http/http_connection_manager.h"
+#include "net/base/client_socket_pool.h"
#include "net/http/http_proxy_service.h"
namespace net {
@@ -40,19 +40,24 @@ namespace net {
// This class holds session objects used by HttpNetworkTransaction objects.
class HttpNetworkSession : public base::RefCounted<HttpNetworkSession> {
public:
+ // Allow up to 6 connections per host.
+ enum {
+ MAX_SOCKETS_PER_GROUP = 6
+ };
+
HttpNetworkSession(HttpProxyResolver* proxy_resolver)
- : connection_manager_(new HttpConnectionManager()),
+ : connection_pool_(new ClientSocketPool(MAX_SOCKETS_PER_GROUP)),
proxy_resolver_(proxy_resolver),
proxy_service_(proxy_resolver) {
}
AuthCache* auth_cache() { return &auth_cache_; }
- HttpConnectionManager* connection_manager() { return connection_manager_; }
+ ClientSocketPool* connection_pool() { return connection_pool_; }
HttpProxyService* proxy_service() { return &proxy_service_; }
private:
AuthCache auth_cache_;
- scoped_refptr<HttpConnectionManager> connection_manager_;
+ scoped_refptr<ClientSocketPool> connection_pool_;
scoped_ptr<HttpProxyResolver> proxy_resolver_;
HttpProxyService proxy_service_;
};
diff --git a/net/http/http_network_transaction.cc b/net/http/http_network_transaction.cc
index 807c87d..1d45191 100644
--- a/net/http/http_network_transaction.cc
+++ b/net/http/http_network_transaction.cc
@@ -60,7 +60,7 @@ HttpNetworkTransaction::HttpNetworkTransaction(HttpNetworkSession* session,
request_(NULL),
pac_request_(NULL),
socket_factory_(csf),
- connection_(session->connection_manager()),
+ connection_(session->connection_pool()),
reused_socket_(false),
using_ssl_(false),
using_proxy_(false),