summaryrefslogtreecommitdiffstats
path: root/chrome
diff options
context:
space:
mode:
authorukai@chromium.org <ukai@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-10-29 06:18:11 +0000
committerukai@chromium.org <ukai@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2009-10-29 06:18:11 +0000
commit327344ef227af4c66b42cb7e948d4c4096eab83f (patch)
treee66b340b198dcd9ed8db57ae067eb9fd8d11c26b /chrome
parent50220030753d7d0ba1fcea95e5f889033bdeb382 (diff)
downloadchromium_src-327344ef227af4c66b42cb7e948d4c4096eab83f.zip
chromium_src-327344ef227af4c66b42cb7e948d4c4096eab83f.tar.gz
chromium_src-327344ef227af4c66b42cb7e948d4c4096eab83f.tar.bz2
WebSocket support in chromium.
Run with --enable-web-sockets enables WebSocket features. BUG=12497 TEST=none Review URL: http://codereview.chromium.org/292044 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@30440 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome')
-rw-r--r--chrome/browser/in_process_webkit/browser_webkitclient_impl.cc5
-rw-r--r--chrome/browser/in_process_webkit/browser_webkitclient_impl.h1
-rw-r--r--chrome/browser/renderer_host/resource_message_filter.cc7
-rw-r--r--chrome/browser/renderer_host/resource_message_filter.h4
-rw-r--r--chrome/browser/renderer_host/socket_stream_dispatcher_host.cc161
-rw-r--r--chrome/browser/renderer_host/socket_stream_dispatcher_host.h56
-rw-r--r--chrome/browser/renderer_host/socket_stream_host.cc69
-rw-r--r--chrome/browser/renderer_host/socket_stream_host.h55
-rwxr-xr-xchrome/chrome.gyp7
-rw-r--r--chrome/common/net/socket_stream.h14
-rw-r--r--chrome/renderer/render_thread.cc4
-rw-r--r--chrome/renderer/render_thread.h6
-rw-r--r--chrome/renderer/renderer_glue.cc8
-rw-r--r--chrome/renderer/socket_stream_dispatcher.cc214
-rw-r--r--chrome/renderer/socket_stream_dispatcher.h38
15 files changed, 644 insertions, 5 deletions
diff --git a/chrome/browser/in_process_webkit/browser_webkitclient_impl.cc b/chrome/browser/in_process_webkit/browser_webkitclient_impl.cc
index 53ced24..6a13013 100644
--- a/chrome/browser/in_process_webkit/browser_webkitclient_impl.cc
+++ b/chrome/browser/in_process_webkit/browser_webkitclient_impl.cc
@@ -78,6 +78,11 @@ WebKit::WebURLLoader* BrowserWebKitClientImpl::createURLLoader() {
return NULL;
}
+WebKit::WebSocketStreamHandle* BrowserWebKitClientImpl::createSocketStreamHandle() {
+ NOTREACHED();
+ return NULL;
+}
+
void BrowserWebKitClientImpl::getPluginList(bool refresh,
WebKit::WebPluginListBuilder* builder) {
NOTREACHED();
diff --git a/chrome/browser/in_process_webkit/browser_webkitclient_impl.h b/chrome/browser/in_process_webkit/browser_webkitclient_impl.h
index 07824db..0024bfb 100644
--- a/chrome/browser/in_process_webkit/browser_webkitclient_impl.h
+++ b/chrome/browser/in_process_webkit/browser_webkitclient_impl.h
@@ -27,6 +27,7 @@ class BrowserWebKitClientImpl : public webkit_glue::WebKitClientImpl {
virtual WebKit::WebString defaultLocale();
virtual WebKit::WebThemeEngine* themeEngine();
virtual WebKit::WebURLLoader* createURLLoader();
+ virtual WebKit::WebSocketStreamHandle* createSocketStreamHandle();
virtual void getPluginList(bool refresh, WebKit::WebPluginListBuilder*);
virtual WebKit::WebData loadResource(const char* name);
virtual WebKit::WebStorageNamespace* createLocalStorageNamespace(
diff --git a/chrome/browser/renderer_host/resource_message_filter.cc b/chrome/browser/renderer_host/resource_message_filter.cc
index ce16753..046ea92 100644
--- a/chrome/browser/renderer_host/resource_message_filter.cc
+++ b/chrome/browser/renderer_host/resource_message_filter.cc
@@ -30,6 +30,7 @@
#include "chrome/browser/renderer_host/database_dispatcher_host.h"
#include "chrome/browser/renderer_host/file_system_accessor.h"
#include "chrome/browser/renderer_host/render_widget_helper.h"
+#include "chrome/browser/renderer_host/socket_stream_dispatcher_host.h"
#include "chrome/browser/spellchecker.h"
#include "chrome/browser/spellchecker_platform_engine.h"
#include "chrome/browser/task_manager.h"
@@ -172,6 +173,7 @@ ResourceMessageFilter::ResourceMessageFilter(
new DatabaseDispatcherHost(profile->GetPath(), this))),
notification_prefs_(
profile->GetDesktopNotificationService()->prefs_cache()),
+ socket_stream_dispatcher_host_(new SocketStreamDispatcherHost),
off_the_record_(profile->IsOffTheRecord()),
next_route_id_callback_(NewCallbackWithReturnValue(
render_widget_helper, &RenderWidgetHelper::GetNextRoutingID)) {
@@ -180,6 +182,7 @@ ResourceMessageFilter::ResourceMessageFilter(
DCHECK(audio_renderer_host_.get());
DCHECK(appcache_dispatcher_host_.get());
DCHECK(dom_storage_dispatcher_host_.get());
+ DCHECK(socket_stream_dispatcher_host_.get());
}
ResourceMessageFilter::~ResourceMessageFilter() {
@@ -233,6 +236,7 @@ void ResourceMessageFilter::OnChannelConnected(int32 peer_pid) {
WorkerService::GetInstance()->Initialize(
resource_dispatcher_host_, ui_loop());
appcache_dispatcher_host_->Initialize(this, id(), handle());
+ socket_stream_dispatcher_host_->Initialize(this, id());
dom_storage_dispatcher_host_->Init(handle());
}
@@ -266,7 +270,8 @@ bool ResourceMessageFilter::OnMessageReceived(const IPC::Message& msg) {
audio_renderer_host_->OnMessageReceived(msg, &msg_is_ok) ||
db_dispatcher_host_->OnMessageReceived(msg, &msg_is_ok) ||
mp_dispatcher->OnMessageReceived(
- msg, this, next_route_id_callback(), &msg_is_ok);
+ msg, this, next_route_id_callback(), &msg_is_ok) ||
+ socket_stream_dispatcher_host_->OnMessageReceived(msg, &msg_is_ok);
if (!handled) {
DCHECK(msg_is_ok); // It should have been marked handled if it wasn't OK.
diff --git a/chrome/browser/renderer_host/resource_message_filter.h b/chrome/browser/renderer_host/resource_message_filter.h
index 958c642..0134c37 100644
--- a/chrome/browser/renderer_host/resource_message_filter.h
+++ b/chrome/browser/renderer_host/resource_message_filter.h
@@ -39,6 +39,7 @@ class ExtensionMessageService;
class NotificationsPrefsCache;
class Profile;
class RenderWidgetHelper;
+class SocketStreamDispatcherHost;
class SpellChecker;
class URLRequestContextGetter;
struct ViewHostMsg_Audio_CreateStream;
@@ -370,6 +371,9 @@ class ResourceMessageFilter : public IPC::ChannelProxy::MessageFilter,
// Desktop Notifications permission messages.
scoped_refptr<NotificationsPrefsCache> notification_prefs_;
+ // Handles Socket Stream related messages.
+ scoped_ptr<SocketStreamDispatcherHost> socket_stream_dispatcher_host_;
+
// Whether this process is used for off the record tabs.
bool off_the_record_;
diff --git a/chrome/browser/renderer_host/socket_stream_dispatcher_host.cc b/chrome/browser/renderer_host/socket_stream_dispatcher_host.cc
new file mode 100644
index 0000000..b2ae133
--- /dev/null
+++ b/chrome/browser/renderer_host/socket_stream_dispatcher_host.cc
@@ -0,0 +1,161 @@
+// Copyright (c) 2009 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 "chrome/browser/renderer_host/socket_stream_dispatcher_host.h"
+
+#include "base/logging.h"
+#include "chrome/browser/renderer_host/socket_stream_host.h"
+#include "chrome/common/render_messages.h"
+#include "chrome/common/net/socket_stream.h"
+#include "ipc/ipc_message.h"
+
+SocketStreamDispatcherHost::SocketStreamDispatcherHost()
+ : sender_(NULL) {
+}
+
+SocketStreamDispatcherHost::~SocketStreamDispatcherHost() {
+ // TODO(ukai): Implement IDMap::RemoveAll().
+ for (IDMap<SocketStreamHost>::const_iterator iter(&hosts_);
+ !iter.IsAtEnd();
+ iter.Advance()) {
+ int socket_id = iter.GetCurrentKey();
+ const SocketStreamHost* socket_stream_host = iter.GetCurrentValue();
+ delete socket_stream_host;
+ hosts_.Remove(socket_id);
+ }
+}
+
+void SocketStreamDispatcherHost::Initialize(
+ IPC::Message::Sender* sender, int process_id) {
+ DLOG(INFO) << "Initialize: SocketStreamDispatcherHost process_id="
+ << process_id_;
+ DCHECK(sender);
+ sender_ = sender;
+ process_id_ = process_id;
+}
+
+bool SocketStreamDispatcherHost::OnMessageReceived(const IPC::Message& msg,
+ bool* msg_ok) {
+ DCHECK(sender_);
+ *msg_ok = true;
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP_EX(SocketStreamDispatcherHost, msg, *msg_ok)
+ IPC_MESSAGE_HANDLER(ViewHostMsg_SocketStream_Connect, OnConnect)
+ IPC_MESSAGE_HANDLER(ViewHostMsg_SocketStream_SendData, OnSendData)
+ IPC_MESSAGE_HANDLER(ViewHostMsg_SocketStream_Close, OnCloseReq)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP_EX()
+ return handled;
+}
+
+// SocketStream::Delegate methods implementations.
+void SocketStreamDispatcherHost::OnConnected(net::SocketStream* socket,
+ int max_pending_send_allowed) {
+ int socket_id = SocketStreamHost::SocketIdFromSocketStream(socket);
+ DLOG(INFO) << "SocketStreamDispatcherHost::OnConnected socket_id="
+ << socket_id
+ << " max_pending_send_allowed=" << max_pending_send_allowed;
+ if (socket_id == chrome_common_net::kNoSocketId) {
+ LOG(ERROR) << "NoSocketId in OnConnected";
+ return;
+ }
+ if (!sender_->Send(new ViewMsg_SocketStream_Connected(
+ socket_id, max_pending_send_allowed))) {
+ LOG(ERROR) << "ViewMsg_SocketStream_Connected failed.";
+ DeleteSocketStreamHost(socket_id);
+ }
+}
+
+void SocketStreamDispatcherHost::OnSentData(net::SocketStream* socket,
+ int amount_sent) {
+ int socket_id = SocketStreamHost::SocketIdFromSocketStream(socket);
+ DLOG(INFO) << "SocketStreamDispatcherHost::OnSentData socket_id="
+ << socket_id
+ << " amount_sent=" << amount_sent;
+ if (socket_id == chrome_common_net::kNoSocketId) {
+ LOG(ERROR) << "NoSocketId in OnReceivedData";
+ return;
+ }
+ if (!sender_->Send(
+ new ViewMsg_SocketStream_SentData(socket_id, amount_sent))) {
+ LOG(ERROR) << "ViewMsg_SocketStream_SentData failed.";
+ DeleteSocketStreamHost(socket_id);
+ }
+}
+
+void SocketStreamDispatcherHost::OnReceivedData(
+ net::SocketStream* socket, const char* data, int len) {
+ int socket_id = SocketStreamHost::SocketIdFromSocketStream(socket);
+ DLOG(INFO) << "SocketStreamDispatcherHost::OnReceiveData socket_id="
+ << socket_id;
+ if (socket_id == chrome_common_net::kNoSocketId) {
+ LOG(ERROR) << "NoSocketId in OnReceivedData";
+ return;
+ }
+ if (!sender_->Send(new ViewMsg_SocketStream_ReceivedData(
+ socket_id, std::vector<char>(data, data + len)))) {
+ LOG(ERROR) << "ViewMsg_SocketStream_ReceivedData failed.";
+ DeleteSocketStreamHost(socket_id);
+ }
+}
+
+void SocketStreamDispatcherHost::OnClose(net::SocketStream* socket) {
+ int socket_id = SocketStreamHost::SocketIdFromSocketStream(socket);
+ DLOG(INFO) << "SocketStreamDispatcherHost::OnClosed socket_id="
+ << socket_id;
+ if (socket_id == chrome_common_net::kNoSocketId) {
+ LOG(ERROR) << "NoSocketId in OnClose";
+ return;
+ }
+ DeleteSocketStreamHost(socket_id);
+}
+
+// Message handlers called by OnMessageReceived.
+void SocketStreamDispatcherHost::OnConnect(const GURL& url, int socket_id) {
+ DLOG(INFO) << "SocketStreamDispatcherHost::OnConnect url=" << url
+ << " socket_id=" << socket_id;
+ DCHECK_NE(chrome_common_net::kNoSocketId, socket_id);
+ if (hosts_.Lookup(socket_id)) {
+ LOG(ERROR) << "socket_id=" << socket_id << " already registered.";
+ return;
+ }
+ SocketStreamHost* socket_stream_host = new SocketStreamHost(this, socket_id);
+ hosts_.AddWithID(socket_stream_host, socket_id);
+ socket_stream_host->Connect(url);
+ DLOG(INFO) << "SocketStreamDispatcherHost::OnConnect -> " << socket_id;
+}
+
+void SocketStreamDispatcherHost::OnSendData(
+ int socket_id, const std::vector<char>& data) {
+ DLOG(INFO) << "SocketStreamDispatcherHost::OnSendData socket_id="
+ << socket_id;
+ SocketStreamHost* socket_stream_host = hosts_.Lookup(socket_id);
+ if (!socket_stream_host) {
+ LOG(ERROR) << "socket_id=" << socket_id << " already closed.";
+ return;
+ }
+ if (!socket_stream_host->SendData(data)) {
+ // Cannot accept more data to send.
+ socket_stream_host->Close();
+ }
+}
+
+void SocketStreamDispatcherHost::OnCloseReq(int socket_id) {
+ DLOG(INFO) << "SocketStreamDispatcherHost::OnCloseReq socket_id="
+ << socket_id;
+ SocketStreamHost* socket_stream_host = hosts_.Lookup(socket_id);
+ if (!socket_stream_host)
+ return;
+ socket_stream_host->Close();
+}
+
+void SocketStreamDispatcherHost::DeleteSocketStreamHost(int socket_id) {
+ SocketStreamHost* socket_stream_host = hosts_.Lookup(socket_id);
+ DCHECK(socket_stream_host);
+ delete socket_stream_host;
+ hosts_.Remove(socket_id);
+ if (!sender_->Send(new ViewMsg_SocketStream_Closed(socket_id))) {
+ LOG(ERROR) << "ViewMsg_SocketStream_Closed failed.";
+ }
+}
diff --git a/chrome/browser/renderer_host/socket_stream_dispatcher_host.h b/chrome/browser/renderer_host/socket_stream_dispatcher_host.h
new file mode 100644
index 0000000..58bfaaa
--- /dev/null
+++ b/chrome/browser/renderer_host/socket_stream_dispatcher_host.h
@@ -0,0 +1,56 @@
+// Copyright (c) 2009 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.
+
+#ifndef CHROME_BROWSER_RENDERER_HOST_SOCKET_STREAM_DISPATCHER_HOST_H_
+#define CHROME_BROWSER_RENDERER_HOST_SOCKET_STREAM_DISPATCHER_HOST_H_
+
+#include <vector>
+
+#include "base/id_map.h"
+#include "ipc/ipc_message.h"
+#include "net/socket_stream/socket_stream.h"
+
+class GURL;
+class SocketStreamHost;
+
+// Dispatches ViewHostMsg_SocketStream_* messages sent from renderer.
+// It also acts as SocketStream::Delegate so that it sends
+// ViewMsg_SocketStream_* messages back to renderer.
+class SocketStreamDispatcherHost : public net::SocketStream::Delegate {
+ public:
+ SocketStreamDispatcherHost();
+ virtual ~SocketStreamDispatcherHost();
+
+ void Initialize(IPC::Message::Sender* sender, int process_id);
+ bool OnMessageReceived(const IPC::Message& msg, bool* msg_ok);
+
+ // SocketStream::Delegate methods.
+ virtual void OnConnected(net::SocketStream* socket,
+ int max_pending_send_allowed);
+ virtual void OnSentData(net::SocketStream* socket, int amount_sent);
+ virtual void OnReceivedData(net::SocketStream* socket,
+ const char* data, int len);
+ virtual void OnClose(net::SocketStream* socket);
+
+ // For sync message.
+ bool Send(IPC::Message* message) {
+ return sender_->Send(message);
+ }
+
+ private:
+ // Message handlers called by OnMessageReceived.
+ void OnConnect(const GURL& url, int socket_id);
+ void OnSendData(int socket_id, const std::vector<char>& data);
+ void OnCloseReq(int socket_id);
+
+ void DeleteSocketStreamHost(int socket_id);
+
+ IPC::Message::Sender* sender_;
+ int process_id_;
+ IDMap<SocketStreamHost> hosts_;
+
+ DISALLOW_COPY_AND_ASSIGN(SocketStreamDispatcherHost);
+};
+
+#endif // CHROME_BROWSER_RENDERER_HOST_SOCKET_STREAM_DISPATCHER_HOST_H_
diff --git a/chrome/browser/renderer_host/socket_stream_host.cc b/chrome/browser/renderer_host/socket_stream_host.cc
new file mode 100644
index 0000000..864cbf2
--- /dev/null
+++ b/chrome/browser/renderer_host/socket_stream_host.cc
@@ -0,0 +1,69 @@
+// Copyright (c) 2009 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 "chrome/browser/renderer_host/socket_stream_host.h"
+
+#include "base/logging.h"
+#include "chrome/browser/profile.h"
+#include "chrome/browser/net/url_request_context_getter.h"
+#include "chrome/common/net/socket_stream.h"
+#include "net/socket_stream/socket_stream.h"
+
+static const char* kSocketIdKey = "socketId";
+
+class SocketStreamId : public net::SocketStream::UserData {
+ public:
+ explicit SocketStreamId(int socket_id) : socket_id_(socket_id) {}
+ virtual ~SocketStreamId() {}
+ int socket_id() const { return socket_id_; }
+ private:
+ int socket_id_;
+};
+
+SocketStreamHost::SocketStreamHost(
+ net::SocketStream::Delegate* delegate, int socket_id)
+ : delegate_(delegate),
+ socket_id_(socket_id) {
+ DCHECK_NE(socket_id_, chrome_common_net::kNoSocketId);
+ LOG(INFO) << "SocketStreamHost: socket_id=" << socket_id_;
+}
+
+/* static */
+int SocketStreamHost::SocketIdFromSocketStream(net::SocketStream* socket) {
+ net::SocketStream::UserData* d = socket->GetUserData(kSocketIdKey);
+ if (d) {
+ SocketStreamId* socket_stream_id = static_cast<SocketStreamId*>(d);
+ return socket_stream_id->socket_id();
+ }
+ return chrome_common_net::kNoSocketId;
+}
+
+SocketStreamHost::~SocketStreamHost() {
+ LOG(INFO) << "SocketStreamHost destructed socket_id=" << socket_id_;
+ socket_->DetachDelegate();
+}
+
+void SocketStreamHost::Connect(const GURL& url) {
+ LOG(INFO) << "SocketStreamHost::Connect url=" << url;
+ socket_ = new net::SocketStream(url, delegate_);
+ URLRequestContextGetter* context_getter = Profile::GetDefaultRequestContext();
+ if (context_getter)
+ socket_->set_context(context_getter->GetURLRequestContext());
+ socket_->SetUserData(kSocketIdKey, new SocketStreamId(socket_id_));
+ socket_->Connect();
+}
+
+bool SocketStreamHost::SendData(const std::vector<char>& data) {
+ LOG(INFO) << "SocketStreamHost::SendData";
+ if (!socket_)
+ return false;
+ return socket_->SendData(&data[0], data.size());
+}
+
+void SocketStreamHost::Close() {
+ LOG(INFO) << "SocketStreamHost::Close";
+ if (!socket_)
+ return;
+ return socket_->Close();
+}
diff --git a/chrome/browser/renderer_host/socket_stream_host.h b/chrome/browser/renderer_host/socket_stream_host.h
new file mode 100644
index 0000000..d7c1b46
--- /dev/null
+++ b/chrome/browser/renderer_host/socket_stream_host.h
@@ -0,0 +1,55 @@
+// Copyright (c) 2009 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.
+
+#ifndef CHROME_BROWSER_RENDERER_HOST_SOCKET_STREAM_HOST_H_
+#define CHROME_BROWSER_RENDERER_HOST_SOCKET_STREAM_HOST_H_
+
+#include <vector>
+
+#include "base/ref_counted.h"
+#include "net/socket_stream/socket_stream.h"
+
+class GURL;
+
+// Host of SocketStreamHandle.
+// Each SocketStreamHandle will have an unique socket_id assigned by
+// SocketStreamHost constructor. If socket id is chrome_common_net::kNoSocketId,
+// there is no SocketStreamHost.
+// Each SocketStreamHost has SocketStream to manage bi-directional
+// communication over socket stream.
+// The lifetime of an instance of this class is completely controlled by the
+// SocketStreamDispatcherHost.
+class SocketStreamHost {
+ public:
+ SocketStreamHost(net::SocketStream::Delegate* delegate, int socket_id);
+ ~SocketStreamHost();
+
+ // Gets socket_id associated with |socket|.
+ static int SocketIdFromSocketStream(net::SocketStream* socket);
+
+ int socket_id() const { return socket_id_; }
+
+ // Starts to open connection to |url|.
+ void Connect(const GURL& url);
+
+ // Sends |data| over the socket stream.
+ // socket stream must be open to send data.
+ // Returns true if the data is put in transmit buffer in socket stream.
+ // Returns false otherwise (transmit buffer exceeds limit, or socket
+ // stream is closed).
+ bool SendData(const std::vector<char>& data);
+
+ // Closes the socket stream.
+ void Close();
+
+ private:
+ net::SocketStream::Delegate* delegate_;
+ int socket_id_;
+
+ scoped_refptr<net::SocketStream> socket_;
+
+ DISALLOW_COPY_AND_ASSIGN(SocketStreamHost);
+};
+
+#endif // CHROME_BROWSER_RENDERER_HOST_SOCKET_STREAM_HOST_H_
diff --git a/chrome/chrome.gyp b/chrome/chrome.gyp
index 1de45fb..fe923ff 100755
--- a/chrome/chrome.gyp
+++ b/chrome/chrome.gyp
@@ -553,6 +553,7 @@
'common/net/dns.h',
'common/net/net_resource_provider.cc',
'common/net/net_resource_provider.h',
+ 'common/net/socket_stream.h',
'common/net/url_request_intercept_job.cc',
'common/net/url_request_intercept_job.h',
'common/web_resource/web_resource_unpacker.cc',
@@ -1966,6 +1967,10 @@
'browser/renderer_host/save_file_resource_handler.h',
'browser/renderer_host/site_instance.cc',
'browser/renderer_host/site_instance.h',
+ 'browser/renderer_host/socket_stream_dispatcher_host.cc',
+ 'browser/renderer_host/socket_stream_dispatcher_host.h',
+ 'browser/renderer_host/socket_stream_host.cc',
+ 'browser/renderer_host/socket_stream_host.h',
'browser/renderer_host/sync_resource_handler.cc',
'browser/renderer_host/sync_resource_handler.h',
'browser/renderer_host/web_cache_manager.cc',
@@ -3262,6 +3267,8 @@
'renderer/renderer_webstoragenamespace_impl.h',
'renderer/renderer_web_database_observer.cc',
'renderer/renderer_web_database_observer.h',
+ 'renderer/socket_stream_dispatcher.cc',
+ 'renderer/socket_stream_dispatcher.h',
'renderer/user_script_slave.cc',
'renderer/user_script_slave.h',
'renderer/visitedlink_slave.cc',
diff --git a/chrome/common/net/socket_stream.h b/chrome/common/net/socket_stream.h
new file mode 100644
index 0000000..844328b
--- /dev/null
+++ b/chrome/common/net/socket_stream.h
@@ -0,0 +1,14 @@
+// Copyright (c) 2009 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.
+
+#ifndef CHROME_COMMON_SOCKET_STREAM_H_
+#define CHROME_COMMON_SOCKET_STREAM_H_
+
+namespace chrome_common_net {
+
+const int kNoSocketId = 0;
+
+} // namespace chrome_common_net
+
+#endif // CHROME_COMMON_SOCKET_STREAM_H_
diff --git a/chrome/renderer/render_thread.cc b/chrome/renderer/render_thread.cc
index 998a2fa..33702fc 100644
--- a/chrome/renderer/render_thread.cc
+++ b/chrome/renderer/render_thread.cc
@@ -44,6 +44,7 @@
#include "chrome/renderer/render_view.h"
#include "chrome/renderer/renderer_webkitclient_impl.h"
#include "chrome/renderer/renderer_web_database_observer.h"
+#include "chrome/renderer/socket_stream_dispatcher.h"
#include "chrome/renderer/user_script_slave.h"
#include "ipc/ipc_message.h"
#include "webkit/api/public/WebCache.h"
@@ -139,6 +140,7 @@ void RenderThread::Init() {
dns_master_.reset(new RenderDnsMaster());
histogram_snapshots_.reset(new RendererHistogramSnapshots());
appcache_dispatcher_.reset(new AppCacheDispatcher(this));
+ socket_stream_dispatcher_.reset(new SocketStreamDispatcher());
devtools_agent_filter_ = new DevToolsAgentFilter();
AddFilter(devtools_agent_filter_.get());
db_message_filter_ = new DBMessageFilter();
@@ -277,6 +279,8 @@ void RenderThread::OnControlMessageReceived(const IPC::Message& msg) {
// App cache messages are handled by a delegate.
if (appcache_dispatcher_->OnMessageReceived(msg))
return;
+ if (socket_stream_dispatcher_->OnMessageReceived(msg))
+ return;
IPC_BEGIN_MESSAGE_MAP(RenderThread, msg)
IPC_MESSAGE_HANDLER(ViewMsg_VisitedLink_NewTable, OnUpdateVisitedLinks)
diff --git a/chrome/renderer/render_thread.h b/chrome/renderer/render_thread.h
index 3c3bc78..5dfb1c9 100644
--- a/chrome/renderer/render_thread.h
+++ b/chrome/renderer/render_thread.h
@@ -29,6 +29,7 @@ class RendererHistogram;
class RendererWebDatabaseObserver;
class RendererWebKitClientImpl;
class SkBitmap;
+class SocketStreamDispatcher;
class UserScriptSlave;
class URLPattern;
@@ -115,6 +116,10 @@ class RenderThread : public RenderThreadBase,
return appcache_dispatcher_.get();
}
+ SocketStreamDispatcher* socket_stream_dispatcher() const {
+ return socket_stream_dispatcher_.get();
+ }
+
bool plugin_refresh_allowed() const { return plugin_refresh_allowed_; }
// Do DNS prefetch resolution of a hostname.
@@ -202,6 +207,7 @@ class RenderThread : public RenderThreadBase,
scoped_ptr<RendererHistogramSnapshots> histogram_snapshots_;
scoped_ptr<RendererWebKitClientImpl> webkit_client_;
scoped_ptr<WebKit::WebStorageEventDispatcher> dom_storage_event_dispatcher_;
+ scoped_ptr<SocketStreamDispatcher> socket_stream_dispatcher_;
scoped_ptr<RendererWebDatabaseObserver> renderer_web_database_observer_;
// Used on the renderer and IPC threads.
diff --git a/chrome/renderer/renderer_glue.cc b/chrome/renderer/renderer_glue.cc
index 43012e9..2dab562 100644
--- a/chrome/renderer/renderer_glue.cc
+++ b/chrome/renderer/renderer_glue.cc
@@ -24,6 +24,7 @@
#include "chrome/renderer/net/render_dns_master.h"
#include "chrome/renderer/render_process.h"
#include "chrome/renderer/render_thread.h"
+#include "chrome/renderer/socket_stream_dispatcher.h"
#include "googleurl/src/url_util.h"
#include "third_party/skia/include/core/SkBitmap.h"
#include "webkit/api/public/WebKit.h"
@@ -245,14 +246,13 @@ ResourceLoaderBridge* ResourceLoaderBridge::Create(
appcache_host_id, routing_id);
}
-
// static factory function
WebSocketStreamHandleBridge* WebSocketStreamHandleBridge::Create(
WebKit::WebSocketStreamHandle* handle,
WebSocketStreamHandleDelegate* delegate) {
- // TODO(ukai): implement dispathcer class.
- NOTREACHED();
- return NULL;
+ SocketStreamDispatcher* dispatcher =
+ RenderThread::current()->socket_stream_dispatcher();
+ return dispatcher->CreateBridge(handle, delegate);
}
void NotifyCacheStats() {
diff --git a/chrome/renderer/socket_stream_dispatcher.cc b/chrome/renderer/socket_stream_dispatcher.cc
new file mode 100644
index 0000000..aa9caec
--- /dev/null
+++ b/chrome/renderer/socket_stream_dispatcher.cc
@@ -0,0 +1,214 @@
+// Copyright (c) 2009 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 "chrome/renderer/socket_stream_dispatcher.h"
+
+#include <vector>
+
+#include "base/id_map.h"
+#include "base/ref_counted.h"
+#include "chrome/common/render_messages.h"
+#include "chrome/common/net/socket_stream.h"
+#include "chrome/renderer/render_thread.h"
+#include "googleurl/src/gurl.h"
+#include "webkit/glue/websocketstreamhandle_bridge.h"
+#include "webkit/glue/websocketstreamhandle_delegate.h"
+
+// IPCWebSocketStreamHandleBridge is owned by each SocketStreamHandle.
+// It communicates with the main browser process via SocketStreamDispatcher.
+class IPCWebSocketStreamHandleBridge
+ : public webkit_glue::WebSocketStreamHandleBridge {
+ public:
+ IPCWebSocketStreamHandleBridge(
+ IPC::Message::Sender* sender,
+ WebKit::WebSocketStreamHandle* handle,
+ webkit_glue::WebSocketStreamHandleDelegate* delegate)
+ : socket_id_(chrome_common_net::kNoSocketId),
+ sender_(sender),
+ handle_(handle),
+ delegate_(delegate) {}
+
+ // Returns the handle having given id or NULL if there is no such handle.
+ static IPCWebSocketStreamHandleBridge* FromSocketId(int id);
+
+ // webkit_glue::WebSocketStreamHandleBridge methods.
+ virtual void Connect(const GURL& url);
+ virtual bool Send(const std::vector<char>& data);
+ virtual void Close();
+
+ // Called by SocketStreamDispatcher.
+ void OnConnected(int max_amount_send_allowed);
+ void OnSentData(int amount_sent);
+ void OnReceivedData(const std::vector<char>& data);
+ void OnClosed();
+
+ private:
+ virtual ~IPCWebSocketStreamHandleBridge();
+
+ void DoConnect(const GURL& url);
+ int socket_id_;
+
+ IPC::Message::Sender* sender_;
+ WebKit::WebSocketStreamHandle* handle_;
+ webkit_glue::WebSocketStreamHandleDelegate* delegate_;
+
+ static IDMap<IPCWebSocketStreamHandleBridge> all_bridges;
+};
+
+IDMap<IPCWebSocketStreamHandleBridge>
+IPCWebSocketStreamHandleBridge::all_bridges;
+
+/* static */
+IPCWebSocketStreamHandleBridge* IPCWebSocketStreamHandleBridge::FromSocketId(
+ int id) {
+ return all_bridges.Lookup(id);
+}
+
+IPCWebSocketStreamHandleBridge::~IPCWebSocketStreamHandleBridge() {
+ DLOG(INFO) << "IPCWebSocketStreamHandleBridge destructor socket_id="
+ << socket_id_;
+ if (socket_id_ != chrome_common_net::kNoSocketId) {
+ sender_->Send(new ViewHostMsg_Close(socket_id_));
+ socket_id_ = chrome_common_net::kNoSocketId;
+ }
+}
+
+void IPCWebSocketStreamHandleBridge::Connect(const GURL& url) {
+ DCHECK(sender_);
+ DLOG(INFO) << "Connect url=" << url;
+ MessageLoop::current()->PostTask(
+ FROM_HERE,
+ NewRunnableMethod(this, &IPCWebSocketStreamHandleBridge::DoConnect,
+ url));
+}
+
+bool IPCWebSocketStreamHandleBridge::Send(
+ const std::vector<char>& data) {
+ DLOG(INFO) << "Send data.size=" << data.size();
+ if (sender_->Send(new ViewHostMsg_SocketStream_SendData(socket_id_, data))) {
+ if (delegate_)
+ delegate_->WillSendData(handle_, &data[0], data.size());
+ return true;
+ }
+ return false;
+}
+
+void IPCWebSocketStreamHandleBridge::Close() {
+ DLOG(INFO) << "Close socket_id" << socket_id_;
+ sender_->Send(new ViewHostMsg_SocketStream_Close(socket_id_));
+}
+
+void IPCWebSocketStreamHandleBridge::OnConnected(int max_pending_send_allowed) {
+ DLOG(INFO) << "IPCWebSocketStreamHandleBridge::OnConnected socket_id="
+ << socket_id_;
+ if (delegate_)
+ delegate_->DidOpenStream(handle_, max_pending_send_allowed);
+}
+
+void IPCWebSocketStreamHandleBridge::OnSentData(int amount_sent) {
+ if (delegate_)
+ delegate_->DidSendData(handle_, amount_sent);
+}
+
+void IPCWebSocketStreamHandleBridge::OnReceivedData(
+ const std::vector<char>& data) {
+ if (delegate_)
+ delegate_->DidReceiveData(handle_, &data[0], data.size());
+}
+
+void IPCWebSocketStreamHandleBridge::OnClosed() {
+ DLOG(INFO) << "IPCWebSocketStreamHandleBridge::OnClosed";
+ if (socket_id_ != chrome_common_net::kNoSocketId) {
+ all_bridges.Remove(socket_id_);
+ socket_id_ = chrome_common_net::kNoSocketId;
+ }
+ if (delegate_) {
+ delegate_->DidClose(handle_);
+ }
+ delegate_ = NULL;
+ Release();
+}
+
+void IPCWebSocketStreamHandleBridge::DoConnect(const GURL& url) {
+ DCHECK(sender_);
+ DCHECK_EQ(socket_id_, chrome_common_net::kNoSocketId);
+ if (delegate_)
+ delegate_->WillOpenStream(handle_, url);
+
+ socket_id_ = all_bridges.Add(this);
+ DCHECK_NE(socket_id_, chrome_common_net::kNoSocketId);
+ if (sender_->Send(new ViewHostMsg_SocketStream_Connect(url, socket_id_))) {
+ DLOG(INFO) << "Connect socket_id=" << socket_id_;
+ AddRef(); // Released in OnClosed().
+ // TODO(ukai): timeout to OnConnected.
+ } else {
+ LOG(ERROR) << "IPC SocketStream_Connect failed.";
+ OnClosed();
+ }
+}
+
+SocketStreamDispatcher::SocketStreamDispatcher() {
+}
+
+/* static */
+webkit_glue::WebSocketStreamHandleBridge*
+SocketStreamDispatcher::CreateBridge(
+ WebKit::WebSocketStreamHandle* handle,
+ webkit_glue::WebSocketStreamHandleDelegate* delegate) {
+ return new IPCWebSocketStreamHandleBridge(
+ ChildThread::current(), handle, delegate);
+}
+
+bool SocketStreamDispatcher::OnMessageReceived(const IPC::Message& msg) {
+ DLOG(INFO) << "SocketStreamDispatcher::OnMessageReceived";
+ bool handled = true;
+ IPC_BEGIN_MESSAGE_MAP(SocketStreamDispatcher, msg)
+ IPC_MESSAGE_HANDLER(ViewMsg_SocketStream_Connected, OnConnected)
+ IPC_MESSAGE_HANDLER(ViewMsg_SocketStream_SentData, OnSentData)
+ IPC_MESSAGE_HANDLER(ViewMsg_SocketStream_ReceivedData, OnReceivedData)
+ IPC_MESSAGE_HANDLER(ViewMsg_SocketStream_Closed, OnClosed)
+ IPC_MESSAGE_UNHANDLED(handled = false)
+ IPC_END_MESSAGE_MAP()
+ return handled;
+}
+
+void SocketStreamDispatcher::OnConnected(int socket_id,
+ int max_pending_send_allowed) {
+ DLOG(INFO) << "SocketStreamDispatcher::OnConnected socket_id=" << socket_id
+ << " max_pending_send_allowed=" << max_pending_send_allowed;
+ IPCWebSocketStreamHandleBridge* bridge =
+ IPCWebSocketStreamHandleBridge::FromSocketId(socket_id);
+ if (bridge)
+ bridge->OnConnected(max_pending_send_allowed);
+ else
+ DLOG(ERROR) << "No SocketStreamHandleBridge for socket_id=" << socket_id;
+}
+
+void SocketStreamDispatcher::OnSentData(int socket_id, int amount_sent) {
+ IPCWebSocketStreamHandleBridge* bridge =
+ IPCWebSocketStreamHandleBridge::FromSocketId(socket_id);
+ if (bridge)
+ bridge->OnSentData(amount_sent);
+ else
+ DLOG(ERROR) << "No SocketStreamHandleBridge for socket_id=" << socket_id;
+}
+
+void SocketStreamDispatcher::OnReceivedData(
+ int socket_id, const std::vector<char>& data) {
+ IPCWebSocketStreamHandleBridge* bridge =
+ IPCWebSocketStreamHandleBridge::FromSocketId(socket_id);
+ if (bridge)
+ bridge->OnReceivedData(data);
+ else
+ DLOG(ERROR) << "No SocketStreamHandleBridge for socket_id=" << socket_id;
+}
+
+void SocketStreamDispatcher::OnClosed(int socket_id) {
+ IPCWebSocketStreamHandleBridge* bridge =
+ IPCWebSocketStreamHandleBridge::FromSocketId(socket_id);
+ if (bridge)
+ bridge->OnClosed();
+ else
+ DLOG(ERROR) << "No SocketStreamHandleBridge for socket_id=" << socket_id;
+}
diff --git a/chrome/renderer/socket_stream_dispatcher.h b/chrome/renderer/socket_stream_dispatcher.h
new file mode 100644
index 0000000..5399030
--- /dev/null
+++ b/chrome/renderer/socket_stream_dispatcher.h
@@ -0,0 +1,38 @@
+// Copyright (c) 2009 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.
+
+#ifndef CHROME_RENDERER_SOCKET_STREAM_DISPATCHER_H_
+#define CHROME_RENDERER_SOCKET_STREAM_DISPATCHER_H_
+
+#include <vector>
+
+#include "base/basictypes.h"
+#include "ipc/ipc_channel.h"
+#include "ipc/ipc_message.h"
+#include "webkit/glue/websocketstreamhandle_bridge.h"
+
+// Dispatches socket stream related messages sent to a child process from the
+// main browser process. There is one instance per child process. Messages
+// are dispatched on the main child thread. The RenderThread class
+// creates an instance of SocketStreamDispatcher and delegates calls to it.
+class SocketStreamDispatcher {
+ public:
+ SocketStreamDispatcher();
+ ~SocketStreamDispatcher() {}
+
+ static webkit_glue::WebSocketStreamHandleBridge* CreateBridge(
+ WebKit::WebSocketStreamHandle* handle,
+ webkit_glue::WebSocketStreamHandleDelegate* delegate);
+ bool OnMessageReceived(const IPC::Message& msg);
+
+ private:
+ void OnConnected(int socket_id, int max_amount_send_allowed);
+ void OnSentData(int socket_id, int amount_sent);
+ void OnReceivedData(int socket_id, const std::vector<char>& data);
+ void OnClosed(int socket_id);
+
+ DISALLOW_COPY_AND_ASSIGN(SocketStreamDispatcher);
+};
+
+#endif // CHROME_RENDERER_SOCKET_STREAM_DISPATCHER_H_