diff options
author | pliard@chromium.org <pliard@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-04-23 18:23:26 +0000 |
---|---|---|
committer | pliard@chromium.org <pliard@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2012-04-23 18:23:26 +0000 |
commit | 83088b2c3cf332a53d866c92b8106c26fb2395a3 (patch) | |
tree | bd025d079b6c380dfb8731abe7fe3b19b6b0f16f | |
parent | 2cd6eac027ab13ee08800130d5738ca4950d5079 (diff) | |
download | chromium_src-83088b2c3cf332a53d866c92b8106c26fb2395a3.zip chromium_src-83088b2c3cf332a53d866c92b8106c26fb2395a3.tar.gz chromium_src-83088b2c3cf332a53d866c92b8106c26fb2395a3.tar.bz2 |
Upstream changes making ListenSocket an abstract class.
This is part of Chrome for Android upstreaming.
This CL makes ListenSocket an abstract class instead of a concrete class
implementing a TCP Listen Socket. This abstraction will be used later to make
HttpServer seamlessly operate on TCP sockets and Unix domain sockets (will be
upstreamed in a separate CL).
The TCP Listen socket implementation, previously in listen_socket.{cc,h}, is
now in tcp_listen_socket.{cc,h}.
TEST=net_unittests
Review URL: http://codereview.chromium.org/10108015
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@133480 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome_frame/test/test_server.cc | 6 | ||||
-rw-r--r-- | chrome_frame/test/test_server.h | 1 | ||||
-rw-r--r-- | net/base/listen_socket.cc | 315 | ||||
-rw-r--r-- | net/base/listen_socket.h | 98 | ||||
-rw-r--r-- | net/base/tcp_listen_socket.cc | 322 | ||||
-rw-r--r-- | net/base/tcp_listen_socket.h | 112 | ||||
-rw-r--r-- | net/base/tcp_listen_socket_unittest.cc (renamed from net/base/listen_socket_unittest.cc) | 83 | ||||
-rw-r--r-- | net/base/tcp_listen_socket_unittest.h (renamed from net/base/listen_socket_unittest.h) | 35 | ||||
-rw-r--r-- | net/net.gyp | 8 | ||||
-rw-r--r-- | net/server/http_server.cc | 5 | ||||
-rw-r--r-- | net/socket/transport_client_socket_unittest.cc | 16 | ||||
-rw-r--r-- | net/tools/fetch/http_listen_socket.cc | 16 | ||||
-rw-r--r-- | net/tools/fetch/http_listen_socket.h | 6 |
13 files changed, 543 insertions, 480 deletions
diff --git a/chrome_frame/test/test_server.cc b/chrome_frame/test/test_server.cc index ea4923e..b38b143 100644 --- a/chrome_frame/test/test_server.cc +++ b/chrome_frame/test/test_server.cc @@ -14,6 +14,7 @@ #include "base/stringprintf.h" #include "base/utf_string_conversions.h" #include "chrome_frame/test/test_server.h" +#include "net/base/tcp_listen_socket.h" #include "net/base/winsock_init.h" #include "net/http/http_util.h" @@ -132,7 +133,7 @@ SimpleWebServer::SimpleWebServer(int port) { CHECK(MessageLoop::current()) << "SimpleWebServer requires a message loop"; net::EnsureWinsockInit(); AddResponse(&quit_); - server_ = net::ListenSocket::Listen("127.0.0.1", port, this); + server_ = net::TCPListenSocket::CreateAndListen("127.0.0.1", port, this); DCHECK(server_.get() != NULL); } @@ -236,7 +237,8 @@ HTTPTestServer::HTTPTestServer(int port, const std::wstring& address, FilePath root_dir) : port_(port), address_(address), root_dir_(root_dir) { net::EnsureWinsockInit(); - server_ = net::ListenSocket::Listen(WideToUTF8(address), port, this); + server_ = + net::TCPListenSocket::CreateAndListen(WideToUTF8(address), port, this); } HTTPTestServer::~HTTPTestServer() { diff --git a/chrome_frame/test/test_server.h b/chrome_frame/test/test_server.h index 50ddf37..2fef7d2 100644 --- a/chrome_frame/test/test_server.h +++ b/chrome_frame/test/test_server.h @@ -40,6 +40,7 @@ #include "base/basictypes.h" #include "base/file_util.h" +#include "base/message_loop.h" #include "net/base/listen_socket.h" namespace test_server { diff --git a/net/base/listen_socket.cc b/net/base/listen_socket.cc index c600594..499bb76 100644 --- a/net/base/listen_socket.cc +++ b/net/base/listen_socket.cc @@ -2,331 +2,22 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "build/build_config.h" - -#if defined(OS_WIN) -// winsock2.h must be included first in order to ensure it is included before -// windows.h. -#include <winsock2.h> -#elif defined(OS_POSIX) -#include <errno.h> -#include <sys/types.h> -#include <sys/socket.h> -#include <netinet/in.h> -#include <arpa/inet.h> -#include "net/base/net_errors.h" -#endif - -#include "base/eintr_wrapper.h" -#include "base/sys_byteorder.h" -#include "base/threading/platform_thread.h" -#include "net/base/net_util.h" #include "net/base/listen_socket.h" -#if defined(OS_WIN) -typedef int socklen_t; -#endif // defined(OS_WIN) - namespace net { -namespace { +ListenSocket::ListenSocket(ListenSocketDelegate* del) : socket_delegate_(del) {} -const int kReadBufSize = 4096; - -} // namespace - -#if defined(OS_WIN) -const SOCKET ListenSocket::kInvalidSocket = INVALID_SOCKET; -const int ListenSocket::kSocketError = SOCKET_ERROR; -#elif defined(OS_POSIX) -const SOCKET ListenSocket::kInvalidSocket = -1; -const int ListenSocket::kSocketError = -1; -#endif - -ListenSocket* ListenSocket::Listen(std::string ip, int port, - ListenSocketDelegate* del) { - SOCKET s = Listen(ip, port); - if (s == kInvalidSocket) { - // TODO(erikkay): error handling - } else { - ListenSocket* sock = new ListenSocket(s, del); - sock->Listen(); - return sock; - } - return NULL; -} +ListenSocket::~ListenSocket() {} void ListenSocket::Send(const char* bytes, int len, bool append_linefeed) { SendInternal(bytes, len); - if (append_linefeed) { + if (append_linefeed) SendInternal("\r\n", 2); - } } void ListenSocket::Send(const std::string& str, bool append_linefeed) { Send(str.data(), static_cast<int>(str.length()), append_linefeed); } -void ListenSocket::PauseReads() { - DCHECK(!reads_paused_); - reads_paused_ = true; -} - -void ListenSocket::ResumeReads() { - DCHECK(reads_paused_); - reads_paused_ = false; - if (has_pending_reads_) { - has_pending_reads_ = false; - Read(); - } -} - -ListenSocket::ListenSocket(SOCKET s, ListenSocketDelegate *del) - : socket_(s), - socket_delegate_(del), - reads_paused_(false), - has_pending_reads_(false) { -#if defined(OS_WIN) - socket_event_ = WSACreateEvent(); - // TODO(ibrar): error handling in case of socket_event_ == WSA_INVALID_EVENT - WatchSocket(NOT_WAITING); -#elif defined(OS_POSIX) - wait_state_ = NOT_WAITING; -#endif -} - -ListenSocket::~ListenSocket() { -#if defined(OS_WIN) - if (socket_event_) { - WSACloseEvent(socket_event_); - socket_event_ = WSA_INVALID_EVENT; - } -#endif - CloseSocket(socket_); -} - -SOCKET ListenSocket::Listen(std::string ip, int port) { - SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - if (s != kInvalidSocket) { -#if defined(OS_POSIX) - // Allow rapid reuse. - static const int kOn = 1; - setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &kOn, sizeof(kOn)); -#endif - sockaddr_in addr; - memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_addr.s_addr = inet_addr(ip.c_str()); - addr.sin_port = base::HostToNet16(port); - if (bind(s, reinterpret_cast<sockaddr*>(&addr), sizeof(addr))) { -#if defined(OS_WIN) - closesocket(s); -#elif defined(OS_POSIX) - close(s); -#endif - s = kInvalidSocket; - } - } - return s; -} - -SOCKET ListenSocket::Accept(SOCKET s) { - sockaddr_in from; - socklen_t from_len = sizeof(from); - SOCKET conn = - HANDLE_EINTR(accept(s, reinterpret_cast<sockaddr*>(&from), &from_len)); - if (conn != kInvalidSocket) { - SetNonBlocking(conn); - } - return conn; -} - -void ListenSocket::SendInternal(const char* bytes, int len) { - char* send_buf = const_cast<char *>(bytes); - int len_left = len; - while (true) { - int sent = HANDLE_EINTR(send(socket_, send_buf, len_left, 0)); - if (sent == len_left) { // A shortcut to avoid extraneous checks. - break; - } - if (sent == kSocketError) { -#if defined(OS_WIN) - if (WSAGetLastError() != WSAEWOULDBLOCK) { - LOG(ERROR) << "send failed: WSAGetLastError()==" << WSAGetLastError(); -#elif defined(OS_POSIX) - if (errno != EWOULDBLOCK && errno != EAGAIN) { - LOG(ERROR) << "send failed: errno==" << errno; -#endif - break; - } - // Otherwise we would block, and now we have to wait for a retry. - // Fall through to PlatformThread::YieldCurrentThread() - } else { - // sent != len_left according to the shortcut above. - // Shift the buffer start and send the remainder after a short while. - send_buf += sent; - len_left -= sent; - } - base::PlatformThread::YieldCurrentThread(); - } -} - -void ListenSocket::Listen() { - int backlog = 10; // TODO(erikkay): maybe don't allow any backlog? - listen(socket_, backlog); - // TODO(erikkay): error handling -#if defined(OS_POSIX) - WatchSocket(WAITING_ACCEPT); -#endif -} - -void ListenSocket::Accept() { - SOCKET conn = Accept(socket_); - if (conn != kInvalidSocket) { - scoped_refptr<ListenSocket> sock( - new ListenSocket(conn, socket_delegate_)); - // it's up to the delegate to AddRef if it wants to keep it around -#if defined(OS_POSIX) - sock->WatchSocket(WAITING_READ); -#endif - socket_delegate_->DidAccept(this, sock); - } else { - // TODO(ibrar): some error handling required here - } -} - -void ListenSocket::Read() { - char buf[kReadBufSize + 1]; // +1 for null termination - int len; - do { - len = HANDLE_EINTR(recv(socket_, buf, kReadBufSize, 0)); - if (len == kSocketError) { -#if defined(OS_WIN) - int err = WSAGetLastError(); - if (err == WSAEWOULDBLOCK) { -#elif defined(OS_POSIX) - if (errno == EWOULDBLOCK || errno == EAGAIN) { -#endif - break; - } else { - // TODO(ibrar): some error handling required here - break; - } - } else if (len == 0) { - // In Windows, Close() is called by OnObjectSignaled. In POSIX, we need - // to call it here. -#if defined(OS_POSIX) - Close(); -#endif - } else { - // TODO(ibrar): maybe change DidRead to take a length instead - DCHECK_GT(len, 0); - DCHECK_LE(len, kReadBufSize); - buf[len] = 0; // already create a buffer with +1 length - socket_delegate_->DidRead(this, buf, len); - } - } while (len == kReadBufSize); -} - -void ListenSocket::Close() { -#if defined(OS_POSIX) - if (wait_state_ == NOT_WAITING) - return; - wait_state_ = NOT_WAITING; -#endif - UnwatchSocket(); - socket_delegate_->DidClose(this); -} - -void ListenSocket::CloseSocket(SOCKET s) { - if (s && s != kInvalidSocket) { - UnwatchSocket(); -#if defined(OS_WIN) - closesocket(s); -#elif defined(OS_POSIX) - close(s); -#endif - } -} - -void ListenSocket::WatchSocket(WaitState state) { -#if defined(OS_WIN) - WSAEventSelect(socket_, socket_event_, FD_ACCEPT | FD_CLOSE | FD_READ); - watcher_.StartWatching(socket_event_, this); -#elif defined(OS_POSIX) - // Implicitly calls StartWatchingFileDescriptor(). - MessageLoopForIO::current()->WatchFileDescriptor( - socket_, true, MessageLoopForIO::WATCH_READ, &watcher_, this); - wait_state_ = state; -#endif -} - -void ListenSocket::UnwatchSocket() { -#if defined(OS_WIN) - watcher_.StopWatching(); -#elif defined(OS_POSIX) - watcher_.StopWatchingFileDescriptor(); -#endif -} - -// TODO(ibrar): We can add these functions into OS dependent files -#if defined(OS_WIN) -// MessageLoop watcher callback -void ListenSocket::OnObjectSignaled(HANDLE object) { - WSANETWORKEVENTS ev; - if (kSocketError == WSAEnumNetworkEvents(socket_, socket_event_, &ev)) { - // TODO - return; - } - - // The object was reset by WSAEnumNetworkEvents. Watch for the next signal. - watcher_.StartWatching(object, this); - - if (ev.lNetworkEvents == 0) { - // Occasionally the event is set even though there is no new data. - // The net seems to think that this is ignorable. - return; - } - if (ev.lNetworkEvents & FD_ACCEPT) { - Accept(); - } - if (ev.lNetworkEvents & FD_READ) { - if (reads_paused_) { - has_pending_reads_ = true; - } else { - Read(); - } - } - if (ev.lNetworkEvents & FD_CLOSE) { - Close(); - } -} -#elif defined(OS_POSIX) -void ListenSocket::OnFileCanReadWithoutBlocking(int fd) { - switch (wait_state_) { - case WAITING_ACCEPT: - Accept(); - break; - case WAITING_READ: - if (reads_paused_) { - has_pending_reads_ = true; - } else { - Read(); - } - break; - default: - // Close() is called by Read() in the Linux case. - NOTREACHED(); - break; - } -} - -void ListenSocket::OnFileCanWriteWithoutBlocking(int fd) { - // MessagePumpLibevent callback, we don't listen for write events - // so we shouldn't ever reach here. - NOTREACHED(); -} - -#endif - } // namespace net diff --git a/net/base/listen_socket.h b/net/base/listen_socket.h index 8223767..f102462 100644 --- a/net/base/listen_socket.h +++ b/net/base/listen_socket.h @@ -1,47 +1,26 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. -// TCP/IP server that handles IO asynchronously in the specified MessageLoop. -// These objects are NOT thread safe. They use WSAEVENT handles to monitor -// activity in a given MessageLoop. This means that callbacks will -// happen in that loop's thread always and that all other methods (including -// constructors and destructors) should also be called from the same thread. +// Abstract socket server that handles IO asynchronously in the specified +// MessageLoop. #ifndef NET_BASE_LISTEN_SOCKET_H_ #define NET_BASE_LISTEN_SOCKET_H_ #pragma once -#include "build/build_config.h" - -#if defined(OS_WIN) -#include <winsock2.h> -#endif #include <string> -#if defined(OS_WIN) -#include "base/win/object_watcher.h" -#elif defined(OS_POSIX) -#include "base/message_loop.h" -#endif #include "base/basictypes.h" -#include "base/compiler_specific.h" #include "base/memory/ref_counted.h" +#include "build/build_config.h" #include "net/base/net_export.h" -#if defined(OS_POSIX) -typedef int SOCKET; -#endif - namespace net { -// Implements a raw socket interface -class NET_EXPORT ListenSocket : public base::RefCountedThreadSafe<ListenSocket>, -#if defined(OS_WIN) - public base::win::ObjectWatcher::Delegate { -#elif defined(OS_POSIX) - public MessageLoopForIO::Watcher { -#endif +// Defines a socket interface for a server. +class NET_EXPORT ListenSocket + : public base::RefCountedThreadSafe<ListenSocket> { public: // TODO(erikkay): this delegate should really be split into two parts // to split up the listener from the connected socket. Perhaps this class @@ -53,79 +32,28 @@ class NET_EXPORT ListenSocket : public base::RefCountedThreadSafe<ListenSocket>, // server is the original listening Socket, connection is the new // Socket that was created. Ownership of connection is transferred // to the delegate with this call. - virtual void DidAccept(ListenSocket *server, ListenSocket *connection) = 0; + virtual void DidAccept(ListenSocket *server, + ListenSocket *connection) = 0; virtual void DidRead(ListenSocket *connection, const char* data, int len) = 0; virtual void DidClose(ListenSocket *sock) = 0; }; - // Listen on port for the specified IP address. Use 127.0.0.1 to only - // accept local connections. - static ListenSocket* Listen(std::string ip, int port, - ListenSocketDelegate* del); - // Send data to the socket. void Send(const char* bytes, int len, bool append_linefeed = false); void Send(const std::string& str, bool append_linefeed = false); - // NOTE: This is for unit test use only! - // Pause/Resume calling Read(). Note that ResumeReads() will also call - // Read() if there is anything to read. - void PauseReads(); - void ResumeReads(); - protected: - friend class base::RefCountedThreadSafe<ListenSocket>; - - enum WaitState { - NOT_WAITING = 0, - WAITING_ACCEPT = 1, - WAITING_READ = 2 - }; - - static const SOCKET kInvalidSocket; - static const int kSocketError; - - ListenSocket(SOCKET s, ListenSocketDelegate* del); + ListenSocket(ListenSocketDelegate* del); virtual ~ListenSocket(); - static SOCKET Listen(std::string ip, int port); - // if valid, returned SOCKET is non-blocking - static SOCKET Accept(SOCKET s); - - virtual void SendInternal(const char* bytes, int len); - virtual void Listen(); - virtual void Accept(); - virtual void Read(); - virtual void Close(); - virtual void CloseSocket(SOCKET s); + virtual void SendInternal(const char* bytes, int len) = 0; - // Pass any value in case of Windows, because in Windows - // we are not using state. - void WatchSocket(WaitState state); - void UnwatchSocket(); - -#if defined(OS_WIN) - // ObjectWatcher delegate - virtual void OnObjectSignaled(HANDLE object); - base::win::ObjectWatcher watcher_; - HANDLE socket_event_; -#elif defined(OS_POSIX) - // Called by MessagePumpLibevent when the socket is ready to do I/O - virtual void OnFileCanReadWithoutBlocking(int fd) OVERRIDE; - virtual void OnFileCanWriteWithoutBlocking(int fd) OVERRIDE; - WaitState wait_state_; - // The socket's libevent wrapper - MessageLoopForIO::FileDescriptorWatcher watcher_; -#endif - - SOCKET socket_; - ListenSocketDelegate *socket_delegate_; + ListenSocketDelegate* const socket_delegate_; private: - bool reads_paused_; - bool has_pending_reads_; + friend class base::RefCountedThreadSafe<ListenSocket>; DISALLOW_COPY_AND_ASSIGN(ListenSocket); }; diff --git a/net/base/tcp_listen_socket.cc b/net/base/tcp_listen_socket.cc new file mode 100644 index 0000000..dfec16f --- /dev/null +++ b/net/base/tcp_listen_socket.cc @@ -0,0 +1,322 @@ +// Copyright (c) 2012 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 "build/build_config.h" + +#if defined(OS_WIN) +// winsock2.h must be included first in order to ensure it is included before +// windows.h. +#include <winsock2.h> +#elif defined(OS_POSIX) +#include <errno.h> +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> +#include "net/base/net_errors.h" +#endif + +#include "base/eintr_wrapper.h" +#include "base/sys_byteorder.h" +#include "base/threading/platform_thread.h" +#include "net/base/net_util.h" +#include "net/base/tcp_listen_socket.h" + +#if defined(OS_WIN) +typedef int socklen_t; +#endif // defined(OS_WIN) + +namespace net { + +namespace { + +const int kReadBufSize = 4096; + +} // namespace + +#if defined(OS_WIN) +const SOCKET TCPListenSocket::kInvalidSocket = INVALID_SOCKET; +const int TCPListenSocket::kSocketError = SOCKET_ERROR; +#elif defined(OS_POSIX) +const SOCKET TCPListenSocket::kInvalidSocket = -1; +const int TCPListenSocket::kSocketError = -1; +#endif + +TCPListenSocket* TCPListenSocket::CreateAndListen( + std::string ip, int port, ListenSocket::ListenSocketDelegate *del) { + SOCKET s = CreateAndBind(ip, port); + if (s == kInvalidSocket) { + // TODO(erikkay): error handling + } else { + TCPListenSocket* sock = new TCPListenSocket(s, del); + sock->Listen(); + return sock; + } + return NULL; +} + +void TCPListenSocket::PauseReads() { + DCHECK(!reads_paused_); + reads_paused_ = true; +} + +void TCPListenSocket::ResumeReads() { + DCHECK(reads_paused_); + reads_paused_ = false; + if (has_pending_reads_) { + has_pending_reads_ = false; + Read(); + } +} + +TCPListenSocket::TCPListenSocket(SOCKET s, + ListenSocket::ListenSocketDelegate *del) + : ListenSocket(del), + socket_(s), + reads_paused_(false), + has_pending_reads_(false) { +#if defined(OS_WIN) + socket_event_ = WSACreateEvent(); + // TODO(ibrar): error handling in case of socket_event_ == WSA_INVALID_EVENT + WatchSocket(NOT_WAITING); +#elif defined(OS_POSIX) + wait_state_ = NOT_WAITING; +#endif +} + +TCPListenSocket::~TCPListenSocket() { +#if defined(OS_WIN) + if (socket_event_) { + WSACloseEvent(socket_event_); + socket_event_ = WSA_INVALID_EVENT; + } +#endif + CloseSocket(socket_); +} + +SOCKET TCPListenSocket::CreateAndBind(std::string ip, int port) { + SOCKET s = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); + if (s != kInvalidSocket) { +#if defined(OS_POSIX) + // Allow rapid reuse. + static const int kOn = 1; + setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &kOn, sizeof(kOn)); +#endif + sockaddr_in addr; + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_addr.s_addr = inet_addr(ip.c_str()); + addr.sin_port = base::HostToNet16(port); + if (bind(s, reinterpret_cast<sockaddr*>(&addr), sizeof(addr))) { +#if defined(OS_WIN) + closesocket(s); +#elif defined(OS_POSIX) + close(s); +#endif + s = kInvalidSocket; + } + } + return s; +} + +SOCKET TCPListenSocket::Accept(SOCKET s) { + sockaddr_in from; + socklen_t from_len = sizeof(from); + SOCKET conn = + HANDLE_EINTR(accept(s, reinterpret_cast<sockaddr*>(&from), &from_len)); + if (conn != kInvalidSocket) { + SetNonBlocking(conn); + } + return conn; +} + +void TCPListenSocket::SendInternal(const char* bytes, int len) { + char* send_buf = const_cast<char *>(bytes); + int len_left = len; + while (true) { + int sent = HANDLE_EINTR(send(socket_, send_buf, len_left, 0)); + if (sent == len_left) { // A shortcut to avoid extraneous checks. + break; + } + if (sent == kSocketError) { +#if defined(OS_WIN) + if (WSAGetLastError() != WSAEWOULDBLOCK) { + LOG(ERROR) << "send failed: WSAGetLastError()==" << WSAGetLastError(); +#elif defined(OS_POSIX) + if (errno != EWOULDBLOCK && errno != EAGAIN) { + LOG(ERROR) << "send failed: errno==" << errno; +#endif + break; + } + // Otherwise we would block, and now we have to wait for a retry. + // Fall through to PlatformThread::YieldCurrentThread() + } else { + // sent != len_left according to the shortcut above. + // Shift the buffer start and send the remainder after a short while. + send_buf += sent; + len_left -= sent; + } + base::PlatformThread::YieldCurrentThread(); + } +} + +void TCPListenSocket::Listen() { + int backlog = 10; // TODO(erikkay): maybe don't allow any backlog? + listen(socket_, backlog); + // TODO(erikkay): error handling +#if defined(OS_POSIX) + WatchSocket(WAITING_ACCEPT); +#endif +} + +void TCPListenSocket::Accept() { + SOCKET conn = Accept(socket_); + if (conn != kInvalidSocket) { + scoped_refptr<TCPListenSocket> sock( + new TCPListenSocket(conn, socket_delegate_)); + // it's up to the delegate to AddRef if it wants to keep it around +#if defined(OS_POSIX) + sock->WatchSocket(WAITING_READ); +#endif + socket_delegate_->DidAccept(this, sock); + } else { + // TODO(ibrar): some error handling required here + } +} + +void TCPListenSocket::Read() { + char buf[kReadBufSize + 1]; // +1 for null termination + int len; + do { + len = HANDLE_EINTR(recv(socket_, buf, kReadBufSize, 0)); + if (len == kSocketError) { +#if defined(OS_WIN) + int err = WSAGetLastError(); + if (err == WSAEWOULDBLOCK) { +#elif defined(OS_POSIX) + if (errno == EWOULDBLOCK || errno == EAGAIN) { +#endif + break; + } else { + // TODO(ibrar): some error handling required here + break; + } + } else if (len == 0) { + // In Windows, Close() is called by OnObjectSignaled. In POSIX, we need + // to call it here. +#if defined(OS_POSIX) + Close(); +#endif + } else { + // TODO(ibrar): maybe change DidRead to take a length instead + DCHECK_GT(len, 0); + DCHECK_LE(len, kReadBufSize); + buf[len] = 0; // already create a buffer with +1 length + socket_delegate_->DidRead(this, buf, len); + } + } while (len == kReadBufSize); +} + +void TCPListenSocket::Close() { +#if defined(OS_POSIX) + if (wait_state_ == NOT_WAITING) + return; + wait_state_ = NOT_WAITING; +#endif + UnwatchSocket(); + socket_delegate_->DidClose(this); +} + +void TCPListenSocket::CloseSocket(SOCKET s) { + if (s && s != kInvalidSocket) { + UnwatchSocket(); +#if defined(OS_WIN) + closesocket(s); +#elif defined(OS_POSIX) + close(s); +#endif + } +} + +void TCPListenSocket::WatchSocket(WaitState state) { +#if defined(OS_WIN) + WSAEventSelect(socket_, socket_event_, FD_ACCEPT | FD_CLOSE | FD_READ); + watcher_.StartWatching(socket_event_, this); +#elif defined(OS_POSIX) + // Implicitly calls StartWatchingFileDescriptor(). + MessageLoopForIO::current()->WatchFileDescriptor( + socket_, true, MessageLoopForIO::WATCH_READ, &watcher_, this); + wait_state_ = state; +#endif +} + +void TCPListenSocket::UnwatchSocket() { +#if defined(OS_WIN) + watcher_.StopWatching(); +#elif defined(OS_POSIX) + watcher_.StopWatchingFileDescriptor(); +#endif +} + +// TODO(ibrar): We can add these functions into OS dependent files +#if defined(OS_WIN) +// MessageLoop watcher callback +void TCPListenSocket::OnObjectSignaled(HANDLE object) { + WSANETWORKEVENTS ev; + if (kSocketError == WSAEnumNetworkEvents(socket_, socket_event_, &ev)) { + // TODO + return; + } + + // The object was reset by WSAEnumNetworkEvents. Watch for the next signal. + watcher_.StartWatching(object, this); + + if (ev.lNetworkEvents == 0) { + // Occasionally the event is set even though there is no new data. + // The net seems to think that this is ignorable. + return; + } + if (ev.lNetworkEvents & FD_ACCEPT) { + Accept(); + } + if (ev.lNetworkEvents & FD_READ) { + if (reads_paused_) { + has_pending_reads_ = true; + } else { + Read(); + } + } + if (ev.lNetworkEvents & FD_CLOSE) { + Close(); + } +} +#elif defined(OS_POSIX) +void TCPListenSocket::OnFileCanReadWithoutBlocking(int fd) { + switch (wait_state_) { + case WAITING_ACCEPT: + Accept(); + break; + case WAITING_READ: + if (reads_paused_) { + has_pending_reads_ = true; + } else { + Read(); + } + break; + default: + // Close() is called by Read() in the Linux case. + NOTREACHED(); + break; + } +} + +void TCPListenSocket::OnFileCanWriteWithoutBlocking(int fd) { + // MessagePumpLibevent callback, we don't listen for write events + // so we shouldn't ever reach here. + NOTREACHED(); +} + +#endif + +} // namespace net diff --git a/net/base/tcp_listen_socket.h b/net/base/tcp_listen_socket.h new file mode 100644 index 0000000..57d4679 --- /dev/null +++ b/net/base/tcp_listen_socket.h @@ -0,0 +1,112 @@ +// Copyright (c) 2012 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. + +// TCP/IP server that handles IO asynchronously in the specified MessageLoop. +// These objects are NOT thread safe. They use WSAEVENT handles to monitor +// activity in a given MessageLoop. This means that callbacks will +// happen in that loop's thread always and that all other methods (including +// constructors and destructors) should also be called from the same thread. + +#ifndef NET_BASE_TCP_LISTEN_SOCKET_H_ +#define NET_BASE_TCP_LISTEN_SOCKET_H_ +#pragma once + +#include "build/build_config.h" + +#if defined(OS_WIN) +#include <winsock2.h> +#endif +#include <string> +#if defined(OS_WIN) +#include "base/win/object_watcher.h" +#elif defined(OS_POSIX) +#include "base/message_loop.h" +#endif + +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "net/base/listen_socket.h" +#include "net/base/net_export.h" + +#if defined(OS_POSIX) +typedef int SOCKET; +#endif + +namespace net { + +// Implements a TCP socket interface. Note that this is ref counted. +class NET_EXPORT TCPListenSocket : public ListenSocket, +#if defined(OS_WIN) + public base::win::ObjectWatcher::Delegate { +#elif defined(OS_POSIX) + public MessageLoopForIO::Watcher { +#endif + public: + // Listen on port for the specified IP address. Use 127.0.0.1 to only + // accept local connections. + static TCPListenSocket* CreateAndListen(std::string ip, int port, + ListenSocketDelegate* del); + + // NOTE: This is for unit test use only! + // Pause/Resume calling Read(). Note that ResumeReads() will also call + // Read() if there is anything to read. + void PauseReads(); + void ResumeReads(); + + protected: + enum WaitState { + NOT_WAITING = 0, + WAITING_ACCEPT = 1, + WAITING_READ = 2 + }; + + static const SOCKET kInvalidSocket; + static const int kSocketError; + + TCPListenSocket(SOCKET s, ListenSocketDelegate* del); + virtual ~TCPListenSocket(); + static SOCKET CreateAndBind(std::string ip, int port); + // if valid, returned SOCKET is non-blocking + static SOCKET Accept(SOCKET s); + + // Implements ListenSocket::SendInternal. + virtual void SendInternal(const char* bytes, int len) OVERRIDE; + + virtual void Listen(); + virtual void Accept(); + virtual void Read(); + virtual void Close(); + virtual void CloseSocket(SOCKET s); + + // Pass any value in case of Windows, because in Windows + // we are not using state. + void WatchSocket(WaitState state); + void UnwatchSocket(); + +#if defined(OS_WIN) + // ObjectWatcher delegate + virtual void OnObjectSignaled(HANDLE object); + base::win::ObjectWatcher watcher_; + HANDLE socket_event_; +#elif defined(OS_POSIX) + // Called by MessagePumpLibevent when the socket is ready to do I/O + virtual void OnFileCanReadWithoutBlocking(int fd) OVERRIDE; + virtual void OnFileCanWriteWithoutBlocking(int fd) OVERRIDE; + WaitState wait_state_; + // The socket's libevent wrapper + MessageLoopForIO::FileDescriptorWatcher watcher_; +#endif + + SOCKET socket_; + + private: + bool reads_paused_; + bool has_pending_reads_; + + DISALLOW_COPY_AND_ASSIGN(TCPListenSocket); +}; + +} // namespace net + +#endif // NET_BASE_TCP_LISTEN_SOCKET_H_ diff --git a/net/base/listen_socket_unittest.cc b/net/base/tcp_listen_socket_unittest.cc index 5e3811e..30cde3cb1 100644 --- a/net/base/listen_socket_unittest.cc +++ b/net/base/tcp_listen_socket_unittest.cc @@ -2,7 +2,7 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. -#include "net/base/listen_socket_unittest.h" +#include "net/base/tcp_listen_socket_unittest.h" #include <fcntl.h> #include <sys/types.h> @@ -15,7 +15,7 @@ namespace net { -const int ListenSocketTester::kTestPort = 9999; +const int TCPListenSocketTester::kTestPort = 9999; static const int kReadBufSize = 1024; static const char kHelloWorld[] = "HELLO, WORLD"; @@ -23,7 +23,7 @@ static const int kMaxQueueSize = 20; static const char kLoopback[] = "127.0.0.1"; static const int kDefaultTimeoutMs = 5000; -ListenSocketTester::ListenSocketTester() +TCPListenSocketTester::TCPListenSocketTester() : thread_(NULL), loop_(NULL), server_(NULL), @@ -31,14 +31,15 @@ ListenSocketTester::ListenSocketTester() cv_(&lock_) { } -void ListenSocketTester::SetUp() { +void TCPListenSocketTester::SetUp() { base::Thread::Options options; options.message_loop_type = MessageLoop::TYPE_IO; thread_.reset(new base::Thread("socketio_test")); thread_->StartWithOptions(options); loop_ = reinterpret_cast<MessageLoopForIO*>(thread_->message_loop()); - loop_->PostTask(FROM_HERE, base::Bind(&ListenSocketTester::Listen, this)); + loop_->PostTask(FROM_HERE, base::Bind( + &TCPListenSocketTester::Listen, this)); // verify Listen succeeded NextAction(); @@ -61,7 +62,7 @@ void ListenSocketTester::SetUp() { ASSERT_EQ(ACTION_ACCEPT, last_action_.type()); } -void ListenSocketTester::TearDown() { +void TCPListenSocketTester::TearDown() { #if defined(OS_WIN) ASSERT_EQ(0, closesocket(test_socket_)); #elif defined(OS_POSIX) @@ -70,7 +71,8 @@ void ListenSocketTester::TearDown() { NextAction(); ASSERT_EQ(ACTION_CLOSE, last_action_.type()); - loop_->PostTask(FROM_HERE, base::Bind(&ListenSocketTester::Shutdown, this)); + loop_->PostTask(FROM_HERE, base::Bind( + &TCPListenSocketTester::Shutdown, this)); NextAction(); ASSERT_EQ(ACTION_SHUTDOWN, last_action_.type()); @@ -78,13 +80,14 @@ void ListenSocketTester::TearDown() { loop_ = NULL; } -void ListenSocketTester::ReportAction(const ListenSocketTestAction& action) { +void TCPListenSocketTester::ReportAction( + const TCPListenSocketTestAction& action) { base::AutoLock locked(lock_); queue_.push_back(action); cv_.Broadcast(); } -void ListenSocketTester::NextAction() { +void TCPListenSocketTester::NextAction() { base::AutoLock locked(lock_); while (queue_.empty()) cv_.Wait(); @@ -92,7 +95,7 @@ void ListenSocketTester::NextAction() { queue_.pop_front(); } -int ListenSocketTester::ClearTestSocket() { +int TCPListenSocketTester::ClearTestSocket() { char buf[kReadBufSize]; int len_ret = 0; do { @@ -106,35 +109,35 @@ int ListenSocketTester::ClearTestSocket() { return len_ret; } -void ListenSocketTester::Shutdown() { +void TCPListenSocketTester::Shutdown() { connection_->Release(); connection_ = NULL; server_->Release(); server_ = NULL; - ReportAction(ListenSocketTestAction(ACTION_SHUTDOWN)); + ReportAction(TCPListenSocketTestAction(ACTION_SHUTDOWN)); } -void ListenSocketTester::Listen() { +void TCPListenSocketTester::Listen() { server_ = DoListen(); if (server_) { server_->AddRef(); - ReportAction(ListenSocketTestAction(ACTION_LISTEN)); + ReportAction(TCPListenSocketTestAction(ACTION_LISTEN)); } } -void ListenSocketTester::SendFromTester() { +void TCPListenSocketTester::SendFromTester() { connection_->Send(kHelloWorld); - ReportAction(ListenSocketTestAction(ACTION_SEND)); + ReportAction(TCPListenSocketTestAction(ACTION_SEND)); } -void ListenSocketTester::TestClientSend() { +void TCPListenSocketTester::TestClientSend() { ASSERT_TRUE(Send(test_socket_, kHelloWorld)); NextAction(); ASSERT_EQ(ACTION_READ, last_action_.type()); ASSERT_EQ(last_action_.data(), kHelloWorld); } -void ListenSocketTester::TestClientSendLong() { +void TCPListenSocketTester::TestClientSendLong() { size_t hello_len = strlen(kHelloWorld); std::string long_string; size_t long_len = 0; @@ -157,9 +160,9 @@ void ListenSocketTester::TestClientSendLong() { ASSERT_EQ(read_len, long_len); } -void ListenSocketTester::TestServerSend() { +void TCPListenSocketTester::TestServerSend() { loop_->PostTask(FROM_HERE, base::Bind( - &ListenSocketTester::SendFromTester, this)); + &TCPListenSocketTester::SendFromTester, this)); NextAction(); ASSERT_EQ(ACTION_SEND, last_action_.type()); const int buf_len = 200; @@ -176,7 +179,7 @@ void ListenSocketTester::TestServerSend() { ASSERT_STREQ(buf, kHelloWorld); } -bool ListenSocketTester::Send(SOCKET sock, const std::string& str) { +bool TCPListenSocketTester::Send(SOCKET sock, const std::string& str) { int len = static_cast<int>(str.length()); int send_len = HANDLE_EINTR(send(sock, str.data(), len, 0)); if (send_len == SOCKET_ERROR) { @@ -188,39 +191,39 @@ bool ListenSocketTester::Send(SOCKET sock, const std::string& str) { return true; } -void ListenSocketTester::DidAccept(ListenSocket *server, - ListenSocket *connection) { +void TCPListenSocketTester::DidAccept(ListenSocket *server, + ListenSocket *connection) { connection_ = connection; connection_->AddRef(); - ReportAction(ListenSocketTestAction(ACTION_ACCEPT)); + ReportAction(TCPListenSocketTestAction(ACTION_ACCEPT)); } -void ListenSocketTester::DidRead(ListenSocket *connection, - const char* data, - int len) { +void TCPListenSocketTester::DidRead(ListenSocket *connection, + const char* data, + int len) { std::string str(data, len); - ReportAction(ListenSocketTestAction(ACTION_READ, str)); + ReportAction(TCPListenSocketTestAction(ACTION_READ, str)); } -void ListenSocketTester::DidClose(ListenSocket *sock) { - ReportAction(ListenSocketTestAction(ACTION_CLOSE)); +void TCPListenSocketTester::DidClose(ListenSocket *sock) { + ReportAction(TCPListenSocketTestAction(ACTION_CLOSE)); } -ListenSocketTester::~ListenSocketTester() {} +TCPListenSocketTester::~TCPListenSocketTester() {} -ListenSocket* ListenSocketTester::DoListen() { - return ListenSocket::Listen(kLoopback, kTestPort, this); +TCPListenSocket* TCPListenSocketTester::DoListen() { + return TCPListenSocket::CreateAndListen(kLoopback, kTestPort, this); } -class ListenSocketTest: public PlatformTest { +class TCPListenSocketTest: public PlatformTest { public: - ListenSocketTest() { + TCPListenSocketTest() { tester_ = NULL; } virtual void SetUp() { PlatformTest::SetUp(); - tester_ = new ListenSocketTester(); + tester_ = new TCPListenSocketTester(); tester_->SetUp(); } @@ -230,18 +233,18 @@ class ListenSocketTest: public PlatformTest { tester_ = NULL; } - scoped_refptr<ListenSocketTester> tester_; + scoped_refptr<TCPListenSocketTester> tester_; }; -TEST_F(ListenSocketTest, ClientSend) { +TEST_F(TCPListenSocketTest, ClientSend) { tester_->TestClientSend(); } -TEST_F(ListenSocketTest, ClientSendLong) { +TEST_F(TCPListenSocketTest, ClientSendLong) { tester_->TestClientSendLong(); } -TEST_F(ListenSocketTest, ServerSend) { +TEST_F(TCPListenSocketTest, ServerSend) { tester_->TestServerSend(); } diff --git a/net/base/listen_socket_unittest.h b/net/base/tcp_listen_socket_unittest.h index 1f63bc9..4e24b30 100644 --- a/net/base/listen_socket_unittest.h +++ b/net/base/tcp_listen_socket_unittest.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -23,8 +23,8 @@ #include "base/synchronization/condition_variable.h" #include "base/synchronization/lock.h" #include "base/threading/thread.h" -#include "net/base/listen_socket.h" #include "net/base/net_util.h" +#include "net/base/tcp_listen_socket.h" #include "net/base/winsock_init.h" #include "testing/gtest/include/gtest/gtest.h" @@ -47,11 +47,11 @@ enum ActionType { ACTION_SHUTDOWN = 6 }; -class ListenSocketTestAction { +class TCPListenSocketTestAction { public: - ListenSocketTestAction() : action_(ACTION_NONE) {} - explicit ListenSocketTestAction(ActionType action) : action_(action) {} - ListenSocketTestAction(ActionType action, std::string data) + TCPListenSocketTestAction() : action_(ACTION_NONE) {} + explicit TCPListenSocketTestAction(ActionType action) : action_(action) {} + TCPListenSocketTestAction(ActionType action, std::string data) : action_(action), data_(data) {} @@ -66,17 +66,17 @@ class ListenSocketTestAction { // This had to be split out into a separate class because I couldn't // make the testing::Test class refcounted. -class ListenSocketTester : +class TCPListenSocketTester : public ListenSocket::ListenSocketDelegate, - public base::RefCountedThreadSafe<ListenSocketTester> { + public base::RefCountedThreadSafe<TCPListenSocketTester> { public: - ListenSocketTester(); + TCPListenSocketTester(); void SetUp(); void TearDown(); - void ReportAction(const ListenSocketTestAction& action); + void ReportAction(const TCPListenSocketTestAction& action); void NextAction(); // read all pending data from the test socket @@ -97,30 +97,29 @@ class ListenSocketTester : // ListenSocket::ListenSocketDelegate: virtual void DidAccept(ListenSocket *server, ListenSocket *connection) OVERRIDE; - virtual void DidRead(ListenSocket *connection, - const char* data, + virtual void DidRead(ListenSocket *connection, const char* data, int len) OVERRIDE; virtual void DidClose(ListenSocket *sock) OVERRIDE; scoped_ptr<base::Thread> thread_; MessageLoopForIO* loop_; - ListenSocket* server_; + TCPListenSocket* server_; ListenSocket* connection_; - ListenSocketTestAction last_action_; + TCPListenSocketTestAction last_action_; SOCKET test_socket_; static const int kTestPort; base::Lock lock_; // protects |queue_| and wraps |cv_| base::ConditionVariable cv_; - std::deque<ListenSocketTestAction> queue_; + std::deque<TCPListenSocketTestAction> queue_; protected: - friend class base::RefCountedThreadSafe<ListenSocketTester>; + friend class base::RefCountedThreadSafe<TCPListenSocketTester>; - virtual ~ListenSocketTester(); + virtual ~TCPListenSocketTester(); - virtual ListenSocket* DoListen(); + virtual TCPListenSocket* DoListen(); }; } // namespace net diff --git a/net/net.gyp b/net/net.gyp index 6a33eda..21556b4 100644 --- a/net/net.gyp +++ b/net/net.gyp @@ -112,9 +112,9 @@ 'base/escape.cc', 'base/escape.h', 'base/escape_icu.cc', - 'base/expiring_cache.h', 'base/ev_root_ca_metadata.cc', 'base/ev_root_ca_metadata.h', + 'base/expiring_cache.h', 'base/file_stream.cc', 'base/file_stream.h', 'base/file_stream_metrics.cc', @@ -247,6 +247,8 @@ 'base/static_cookie_policy.cc', 'base/static_cookie_policy.h', 'base/sys_addrinfo.h', + 'base/tcp_listen_socket.cc', + 'base/tcp_listen_socket.h', 'base/test_data_stream.cc', 'base/test_data_stream.h', 'base/test_root_certs.cc', @@ -1057,8 +1059,6 @@ 'base/host_resolver_impl_unittest.cc', 'base/ip_endpoint_unittest.cc', 'base/keygen_handler_unittest.cc', - 'base/listen_socket_unittest.cc', - 'base/listen_socket_unittest.h', 'base/mapped_host_resolver_unittest.cc', 'base/mime_sniffer_unittest.cc', 'base/mime_util_unittest.cc', @@ -1082,6 +1082,8 @@ 'base/ssl_client_auth_cache_unittest.cc', 'base/ssl_config_service_unittest.cc', 'base/static_cookie_policy_unittest.cc', + 'base/tcp_listen_socket_unittest.cc', + 'base/tcp_listen_socket_unittest.h', 'base/test_certificate_data.h', 'base/test_completion_callback_unittest.cc', 'base/transport_security_state_unittest.cc', diff --git a/net/server/http_server.cc b/net/server/http_server.cc index f56ff96..ad1fa6e 100644 --- a/net/server/http_server.cc +++ b/net/server/http_server.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -10,6 +10,7 @@ #include "base/stringprintf.h" #include "base/sys_byteorder.h" #include "build/build_config.h" +#include "net/base/tcp_listen_socket.h" #include "net/server/http_connection.h" #include "net/server/http_server_request_info.h" #include "net/server/web_socket.h" @@ -20,7 +21,7 @@ HttpServer::HttpServer(const std::string& host, int port, HttpServer::Delegate* del) : delegate_(del) { - server_ = ListenSocket::Listen(host, port, this); + server_ = TCPListenSocket::CreateAndListen(host, port, this); } HttpServer::~HttpServer() { diff --git a/net/socket/transport_client_socket_unittest.cc b/net/socket/transport_client_socket_unittest.cc index 4ba4c000..9ab9044 100644 --- a/net/socket/transport_client_socket_unittest.cc +++ b/net/socket/transport_client_socket_unittest.cc @@ -1,17 +1,19 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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/socket/tcp_client_socket.h" #include "base/basictypes.h" +#include "base/memory/ref_counted.h" +#include "base/memory/scoped_ptr.h" #include "net/base/address_list.h" #include "net/base/host_resolver.h" #include "net/base/io_buffer.h" -#include "net/base/listen_socket.h" #include "net/base/net_log.h" #include "net/base/net_log_unittest.h" #include "net/base/net_errors.h" +#include "net/base/tcp_listen_socket.h" #include "net/base/test_completion_callback.h" #include "net/base/winsock_init.h" #include "net/socket/client_socket_factory.h" @@ -45,7 +47,7 @@ class TransportClientSocketTest // Implement ListenSocketDelegate methods virtual void DidAccept(ListenSocket* server, ListenSocket* connection) { - connected_sock_ = connection; + connected_sock_ = reinterpret_cast<TCPListenSocket*>(connection); } virtual void DidRead(ListenSocket*, const char* str, int len) { // TODO(dkegel): this might not be long enough to tickle some bugs. @@ -90,8 +92,8 @@ class TransportClientSocketTest scoped_ptr<StreamSocket> sock_; private: - scoped_refptr<ListenSocket> listen_sock_; - scoped_refptr<ListenSocket> connected_sock_; + scoped_refptr<TCPListenSocket> listen_sock_; + scoped_refptr<TCPListenSocket> connected_sock_; bool close_server_socket_on_next_send_; }; @@ -99,7 +101,7 @@ void TransportClientSocketTest::SetUp() { ::testing::TestWithParam<ClientSocketTestTypes>::SetUp(); // Find a free port to listen on - ListenSocket *sock = NULL; + TCPListenSocket *sock = NULL; int port; // Range of ports to listen on. Shouldn't need to try many. const int kMinPort = 10100; @@ -108,7 +110,7 @@ void TransportClientSocketTest::SetUp() { EnsureWinsockInit(); #endif for (port = kMinPort; port < kMaxPort; port++) { - sock = ListenSocket::Listen("127.0.0.1", port, this); + sock = TCPListenSocket::CreateAndListen("127.0.0.1", port, this); if (sock) break; } diff --git a/net/tools/fetch/http_listen_socket.cc b/net/tools/fetch/http_listen_socket.cc index fc9f5f3..60c6f94 100644 --- a/net/tools/fetch/http_listen_socket.cc +++ b/net/tools/fetch/http_listen_socket.cc @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -16,7 +16,7 @@ // must run in the IO thread HttpListenSocket::HttpListenSocket(SOCKET s, HttpListenSocket::Delegate* delegate) - : ALLOW_THIS_IN_INITIALIZER_LIST(net::ListenSocket(s, this)), + : ALLOW_THIS_IN_INITIALIZER_LIST(net::TCPListenSocket(s, this)), delegate_(delegate) { } @@ -25,13 +25,13 @@ HttpListenSocket::~HttpListenSocket() { } void HttpListenSocket::Listen() { - net::ListenSocket::Listen(); + net::TCPListenSocket::Listen(); } void HttpListenSocket::Accept() { - SOCKET conn = net::ListenSocket::Accept(socket_); - DCHECK_NE(conn, net::ListenSocket::kInvalidSocket); - if (conn == net::ListenSocket::kInvalidSocket) { + SOCKET conn = net::TCPListenSocket::Accept(socket_); + DCHECK_NE(conn, net::TCPListenSocket::kInvalidSocket); + if (conn == net::TCPListenSocket::kInvalidSocket) { // TODO } else { scoped_refptr<HttpListenSocket> sock( @@ -45,8 +45,8 @@ HttpListenSocket* HttpListenSocket::Listen( const std::string& ip, int port, HttpListenSocket::Delegate* delegate) { - SOCKET s = net::ListenSocket::Listen(ip, port); - if (s == net::ListenSocket::kInvalidSocket) { + SOCKET s = net::TCPListenSocket::CreateAndBind(ip, port); + if (s == net::TCPListenSocket::kInvalidSocket) { // TODO (ibrar): error handling } else { HttpListenSocket *serv = new HttpListenSocket(s, delegate); diff --git a/net/tools/fetch/http_listen_socket.h b/net/tools/fetch/http_listen_socket.h index 18e3a46..8a09a9e 100644 --- a/net/tools/fetch/http_listen_socket.h +++ b/net/tools/fetch/http_listen_socket.h @@ -1,4 +1,4 @@ -// Copyright (c) 2011 The Chromium Authors. All rights reserved. +// Copyright (c) 2012 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. @@ -7,13 +7,13 @@ #pragma once #include "base/message_loop.h" -#include "net/base/listen_socket.h" +#include "net/base/tcp_listen_socket.h" class HttpServerRequestInfo; class HttpServerResponseInfo; // Implements a simple HTTP listen socket on top of the raw socket interface. -class HttpListenSocket : public net::ListenSocket, +class HttpListenSocket : public net::TCPListenSocket, public net::ListenSocket::ListenSocketDelegate { public: class Delegate { |