summaryrefslogtreecommitdiffstats
path: root/net
diff options
context:
space:
mode:
authorpliard@chromium.org <pliard@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-04-23 18:23:26 +0000
committerpliard@chromium.org <pliard@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2012-04-23 18:23:26 +0000
commit83088b2c3cf332a53d866c92b8106c26fb2395a3 (patch)
treebd025d079b6c380dfb8731abe7fe3b19b6b0f16f /net
parent2cd6eac027ab13ee08800130d5738ca4950d5079 (diff)
downloadchromium_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
Diffstat (limited to 'net')
-rw-r--r--net/base/listen_socket.cc315
-rw-r--r--net/base/listen_socket.h98
-rw-r--r--net/base/tcp_listen_socket.cc322
-rw-r--r--net/base/tcp_listen_socket.h112
-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.gyp8
-rw-r--r--net/server/http_server.cc5
-rw-r--r--net/socket/transport_client_socket_unittest.cc16
-rw-r--r--net/tools/fetch/http_listen_socket.cc16
-rw-r--r--net/tools/fetch/http_listen_socket.h6
11 files changed, 538 insertions, 478 deletions
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 {