diff options
20 files changed, 859 insertions, 13 deletions
diff --git a/chrome/renderer/renderer_glue.cc b/chrome/renderer/renderer_glue.cc index ccd4989..1410376 100644 --- a/chrome/renderer/renderer_glue.cc +++ b/chrome/renderer/renderer_glue.cc @@ -31,6 +31,7 @@ #include "webkit/api/public/WebString.h" #include "webkit/glue/scoped_clipboard_writer_glue.h" #include "webkit/glue/webkit_glue.h" +#include "webkit/glue/websocketstreamhandle_bridge.h" #if defined(OS_WIN) #include <strsafe.h> // note: per msdn docs, this must *follow* other includes @@ -243,6 +244,16 @@ 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; +} + void NotifyCacheStats() { // Update the browser about our cache // NOTE: Since this can be called from the plugin process, we might not have diff --git a/webkit/DEPS b/webkit/DEPS index 15f1b46..2dbe2ac 100644 --- a/webkit/DEPS +++ b/webkit/DEPS @@ -19,6 +19,7 @@ include_rules = [ "+net/http", "+net/proxy", "+net/socket", + "+net/socket_stream", "+net/url_request", "+third_party/npapi/bindings", ] diff --git a/webkit/api/public/WebKitClient.h b/webkit/api/public/WebKitClient.h index 6f2b3dd..905355f 100644 --- a/webkit/api/public/WebKitClient.h +++ b/webkit/api/public/WebKitClient.h @@ -50,6 +50,7 @@ namespace WebKit { class WebMimeRegistry; class WebPluginListBuilder; class WebSandboxSupport; + class WebSocketStreamHandle; class WebStorageNamespace; class WebString; class WebThemeEngine; @@ -166,6 +167,9 @@ namespace WebKit { // Returns a new WebURLLoader instance. virtual WebURLLoader* createURLLoader() = 0; + // Returns a new WebSocketStreamHandle instance. + virtual WebSocketStreamHandle* createSocketStreamHandle() = 0; + // Plugins ------------------------------------------------------------- diff --git a/webkit/api/public/WebSocketStreamError.h b/webkit/api/public/WebSocketStreamError.h new file mode 100644 index 0000000..72e8f3c --- /dev/null +++ b/webkit/api/public/WebSocketStreamError.h @@ -0,0 +1,45 @@ +/* + * Copyright (C) 2009 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WebSocketStreamError_h +#define WebSocketStreamError_h + +#include "WebCommon.h" + +namespace WebKit { + + class WebSocketStreamError { + public: + // FIXME: Define SocketStream Error codes and accessor methods. + }; + +} // namespace WebKit + +#endif diff --git a/webkit/api/public/WebSocketStreamHandle.h b/webkit/api/public/WebSocketStreamHandle.h new file mode 100644 index 0000000..909e317 --- /dev/null +++ b/webkit/api/public/WebSocketStreamHandle.h @@ -0,0 +1,57 @@ +/* + * Copyright (C) 2009 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WebSocketStreamHandle_h +#define WebSocketStreamHandle_h + +#include "WebCommon.h" + +namespace WebKit { + class WebData; + class WebSocketStreamHandleClient; + class WebURL; + + class WebSocketStreamHandle { + public: + virtual ~WebSocketStreamHandle() { } + + // Connect new socket stream asynchronously. + virtual void connect(const WebURL&, WebSocketStreamHandleClient*) = 0; + + // Send web socket frame data on the socket stream. + virtual bool send(const WebData&) = 0; + + // Close the socket stream. + virtual void close() = 0; + }; + +} // namespace WebKit + +#endif diff --git a/webkit/api/public/WebSocketStreamHandleClient.h b/webkit/api/public/WebSocketStreamHandleClient.h new file mode 100644 index 0000000..34a1494 --- /dev/null +++ b/webkit/api/public/WebSocketStreamHandleClient.h @@ -0,0 +1,66 @@ +/* + * Copyright (C) 2009 Google Inc. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following disclaimer + * in the documentation and/or other materials provided with the + * distribution. + * * Neither the name of Google Inc. nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef WebSocketStreamHandleClient_h +#define WebSocketStreamHandleClient_h + +#include "WebCommon.h" + +namespace WebKit { + class WebData; + class WebSocketStreamError; + + class WebSocketStreamHandleClient { + public: + + // Called when WebSocketStreamHandle is going to open the URL. + virtual void willOpenStream(WebSocketStreamHandle*, const WebURL&) = 0; + + // Called when Socket Stream is opened. + virtual void didOpenStream(WebSocketStreamHandle*, int /* maxPendingSendAllowed */) = 0; + + // Called when |amountSent| bytes are sent. + virtual void didSendData(WebSocketStreamHandle*, int /* amountSent */) = 0; + + // Called when data are received. + virtual void didReceiveData(WebSocketStreamHandle*, const WebData&) = 0; + + // Called when Socket Stream is closed. + virtual void didClose(WebSocketStreamHandle*) = 0; + + // Called when Socket Stream has an error. + virtual void didFail(WebSocketStreamHandle*, const WebSocketStreamError&) = 0; + + // FIXME: auth challenge for proxy + }; + +} // namespace WebKit + +#endif diff --git a/webkit/api/src/SocketStreamHandle.cpp b/webkit/api/src/SocketStreamHandle.cpp index a011482..738ea4b 100644 --- a/webkit/api/src/SocketStreamHandle.cpp +++ b/webkit/api/src/SocketStreamHandle.cpp @@ -38,13 +38,16 @@ #include "SocketStreamHandleClient.h" #include "WebData.h" #include "WebKit.h" +#include "WebKitClient.h" +#include "WebSocketStreamHandle.h" +#include "WebSocketStreamHandleClient.h" #include <wtf/PassOwnPtr.h> using namespace WebKit; namespace WebCore { -class SocketStreamHandleInternal { +class SocketStreamHandleInternal : public WebSocketStreamHandleClient { public: static PassOwnPtr<SocketStreamHandleInternal> create(SocketStreamHandle* handle) { @@ -52,16 +55,32 @@ public: } virtual ~SocketStreamHandleInternal(); - // TODO(ukai): implement this. + void connect(const KURL&); + int send(const char*, int); + void close(); + + virtual void willOpenStream(WebSocketStreamHandle*, const WebURL&); + + virtual void didOpenStream(WebSocketStreamHandle*, int); + virtual void didSendData(WebSocketStreamHandle*, int); + virtual void didReceiveData(WebSocketStreamHandle*, const WebData&); + virtual void didClose(WebSocketStreamHandle*); + virtual void didFail(WebSocketStreamHandle*, const WebSocketStreamError&); private: explicit SocketStreamHandleInternal(SocketStreamHandle*); SocketStreamHandle* m_handle; + OwnPtr<WebSocketStreamHandle> m_socket; + int m_maxPendingSendAllowed; + int m_pendingAmountSent; }; -SocketStreamHandleInternal::SocketStreamHandleInternal(SocketStreamHandle* handle) +SocketStreamHandleInternal::SocketStreamHandleInternal( + SocketStreamHandle *handle) : m_handle(handle) + , m_maxPendingSendAllowed(0) + , m_pendingAmountSent(0) { } @@ -70,13 +89,125 @@ SocketStreamHandleInternal::~SocketStreamHandleInternal() m_handle = 0; } +void SocketStreamHandleInternal::connect(const KURL& url) +{ + m_socket.set(webKitClient()->createSocketStreamHandle()); + LOG(Network, "connect"); + ASSERT(m_socket.get()); + m_socket->connect(url, this); +} + +int SocketStreamHandleInternal::send(const char* data, int len) +{ + LOG(Network, "send len=%d", len); + ASSERT(m_socket.get()); + if (m_pendingAmountSent + len >= m_maxPendingSendAllowed) + len = m_maxPendingSendAllowed - m_pendingAmountSent - 1; + + if (len <= 0) + return len; + WebData webdata(data, len); + if (m_socket->send(webdata)) { + m_pendingAmountSent += len; + LOG(Network, "sent"); + if (m_handle && m_handle->m_client) + m_handle->m_client->willSendData(m_handle, webdata.data(), webdata.size()); + return len; + } + LOG(Network, "busy. buffering"); + return 0; +} + +void SocketStreamHandleInternal::close() +{ + LOG(Network, "close"); + m_socket->close(); +} + +void SocketStreamHandleInternal::willOpenStream(WebSocketStreamHandle* socketHandle, const WebURL& url) +{ + LOG(Network, "willOpenStream"); + if (m_handle && m_socket.get()) { + ASSERT(socketHandle == m_socket.get()); + if (m_handle->m_client) + m_handle->m_client->willOpenStream(m_handle, url); + } +} + +void SocketStreamHandleInternal::didOpenStream(WebSocketStreamHandle* socketHandle, int maxPendingSendAllowed) +{ + LOG(Network, "SocketStreamHandleInternal::didOpen %d", + maxPendingSendAllowed); + ASSERT(maxPendingSendAllowed > 0); + if (m_handle && m_socket.get()) { + ASSERT(socketHandle == m_socket.get()); + m_maxPendingSendAllowed = maxPendingSendAllowed; + m_handle->m_state = SocketStreamHandleBase::Open; + if (m_handle->m_client) { + m_handle->m_client->didOpen(m_handle); + return; + } + } + LOG(Network, "no m_handle or m_socket?"); +} + +void SocketStreamHandleInternal::didSendData(WebSocketStreamHandle* socketHandle, int amountSent) +{ + LOG(Network, "SocketStreamHandleInternal::didSendData %d", amountSent); + ASSERT(amountSent > 0); + if (m_handle && m_socket.get()) { + ASSERT(socketHandle == m_socket.get()); + m_pendingAmountSent -= amountSent; + ASSERT(m_pendingAmountSent >= 0); + m_handle->sendPendingData(); + } +} + +void SocketStreamHandleInternal::didReceiveData(WebSocketStreamHandle* socketHandle, const WebData& data) +{ + LOG(Network, "didReceiveData"); + if (m_handle && m_socket.get()) { + ASSERT(socketHandle == m_socket.get()); + if (m_handle->m_client) + m_handle->m_client->didReceiveData(m_handle, data.data(), data.size()); + } +} + +void SocketStreamHandleInternal::didClose(WebSocketStreamHandle* socketHandle) +{ + LOG(Network, "didClose"); + if (m_handle && m_socket.get()) { + ASSERT(socketHandle == m_socket.get()); + m_socket.clear(); + SocketStreamHandle* h = m_handle; + m_handle = NULL; + if (h->m_client) + h->m_client->didClose(h); + } +} + +void SocketStreamHandleInternal::didFail(WebSocketStreamHandle* socketHandle, const WebSocketStreamError& err) +{ + LOG(Network, "didFail"); + if (m_handle && m_socket.get()) { + ASSERT(socketHandle == m_socket.get()); + m_socket.clear(); + SocketStreamHandle* h = m_handle; + m_handle = NULL; + if (h->m_client) + h->m_client->didClose(h); // didFail(h, err); + } +} + +// FIXME: auth + // SocketStreamHandle ---------------------------------------------------------- SocketStreamHandle::SocketStreamHandle(const KURL& url, SocketStreamHandleClient* client) - : SocketStreamHandleBase(url, client) + : SocketStreamHandleBase(url, client) { m_internal = SocketStreamHandleInternal::create(this); - notImplemented(); + m_internal->connect(m_url); } SocketStreamHandle::~SocketStreamHandle() @@ -87,18 +218,21 @@ SocketStreamHandle::~SocketStreamHandle() int SocketStreamHandle::platformSend(const char* buf, int len) { - notImplemented(); - return 0; + if (!m_internal.get()) + return 0; + return m_internal->send(buf, len); } void SocketStreamHandle::platformClose() { - notImplemented(); + if (m_internal.get()) + m_internal->close(); } void SocketStreamHandle::didReceiveAuthenticationChallenge(const AuthenticationChallenge& challenge) { - notImplemented(); + if (m_client) + m_client->didReceiveAuthenticationChallenge(this, challenge); } void SocketStreamHandle::receivedCredential(const AuthenticationChallenge& challenge, const Credential& credential) @@ -113,7 +247,8 @@ void SocketStreamHandle::receivedRequestToContinueWithoutCredential(const Authen void SocketStreamHandle::receivedCancellation(const AuthenticationChallenge& challenge) { - notImplemented(); + if (m_client) + m_client->receivedCancellation(this, challenge); } } // namespace WebCore diff --git a/webkit/glue/webkitclient_impl.cc b/webkit/glue/webkitclient_impl.cc index d36f043..c549dab 100644 --- a/webkit/glue/webkitclient_impl.cc +++ b/webkit/glue/webkitclient_impl.cc @@ -34,6 +34,7 @@ #include "webkit/glue/plugins/plugin_instance.h" #include "webkit/glue/webkit_glue.h" #include "webkit/glue/webplugininfo.h" +#include "webkit/glue/websocketstreamhandle_impl.h" #include "webkit/glue/weburlloader_impl.h" #include "webkit/glue/webview_impl.h" #include "webkit/glue/webworkerclient_impl.h" @@ -46,6 +47,7 @@ using WebKit::WebLocalizedString; using WebKit::WebPluginListBuilder; using WebKit::WebStorageNamespace; using WebKit::WebString; +using WebKit::WebSocketStreamHandle; using WebKit::WebThemeEngine; using WebKit::WebURLLoader; using WebKit::WebWidgetClient; @@ -154,6 +156,10 @@ WebURLLoader* WebKitClientImpl::createURLLoader() { return new WebURLLoaderImpl(); } +WebSocketStreamHandle* WebKitClientImpl::createSocketStreamHandle() { + return new WebSocketStreamHandleImpl(); +} + void WebKitClientImpl::getPluginList(bool refresh, WebPluginListBuilder* builder) { std::vector<WebPluginInfo> plugins; diff --git a/webkit/glue/webkitclient_impl.h b/webkit/glue/webkitclient_impl.h index 45352c6..9686730 100644 --- a/webkit/glue/webkitclient_impl.h +++ b/webkit/glue/webkitclient_impl.h @@ -23,6 +23,7 @@ class WebKitClientImpl : public WebKit::WebKitClient { // WebKitClient methods (partial implementation): virtual WebKit::WebThemeEngine* themeEngine(); virtual WebKit::WebURLLoader* createURLLoader(); + virtual WebKit::WebSocketStreamHandle* createSocketStreamHandle(); virtual void getPluginList(bool refresh, WebKit::WebPluginListBuilder*); virtual void decrementStatsCounter(const char* name); virtual void incrementStatsCounter(const char* name); diff --git a/webkit/glue/websocketstreamhandle_bridge.h b/webkit/glue/websocketstreamhandle_bridge.h new file mode 100644 index 0000000..3c995f5 --- /dev/null +++ b/webkit/glue/websocketstreamhandle_bridge.h @@ -0,0 +1,45 @@ +// 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 WEBKIT_GLUE_WEBSOCKETSTREAMHANDLE_BRIDGE_H_ +#define WEBKIT_GLUE_WEBSOCKETSTREAMHANDLE_BRIDGE_H_ + +#include <vector> + +#include "base/basictypes.h" + +class GURL; + +namespace WebKit { +class WebSocketStreamHandle; +} + +namespace webkit_glue { + +class WebSocketStreamHandleDelegate; + +class WebSocketStreamHandleBridge { + public: + virtual ~WebSocketStreamHandleBridge() {} + + static WebSocketStreamHandleBridge* Create( + WebKit::WebSocketStreamHandle* handle, + WebSocketStreamHandleDelegate* delegate); + + virtual void Connect(const GURL& url) = 0; + + virtual bool Send(const std::vector<char>& data) = 0; + + virtual void Close() = 0; + + protected: + WebSocketStreamHandleBridge() {} + + private: + DISALLOW_COPY_AND_ASSIGN(WebSocketStreamHandleBridge); +}; + +} // namespace webkit_glue + +#endif // WEBKIT_GLUE_WEBSOCKETSTREAMHANDLE_BRIDGE_H_ diff --git a/webkit/glue/websocketstreamhandle_delegate.h b/webkit/glue/websocketstreamhandle_delegate.h new file mode 100644 index 0000000..2148699 --- /dev/null +++ b/webkit/glue/websocketstreamhandle_delegate.h @@ -0,0 +1,37 @@ +// 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 WEBKIT_GLUE_WEBSOCKETSTREAMHANDLE_DELEGATE_H_ +#define WEBKIT_GLUE_WEBSOCKETSTREAMHANDLE_DELEGATE_H_ + +class GURL; + +namespace WebKit { +class WebSocketStreamHandle; +} + +namespace webkit_glue { + +class WebSocketStreamHandleDelegate { + public: + WebSocketStreamHandleDelegate() {} + virtual ~WebSocketStreamHandleDelegate() {} + + virtual void WillOpenStream(WebKit::WebSocketStreamHandle* handle, + const GURL& url) {} + virtual void WillSendData(WebKit::WebSocketStreamHandle* handle, + const char* data, int len) {} + + virtual void DidOpenStream(WebKit::WebSocketStreamHandle* handle, + int max_amount_send_allowed) {} + virtual void DidSendData(WebKit::WebSocketStreamHandle* handle, + int amount_sent) {} + virtual void DidReceiveData(WebKit::WebSocketStreamHandle* handle, + const char* data, int len) {} + virtual void DidClose(WebKit::WebSocketStreamHandle*) {} +}; + +} // namespace webkit_glue + +#endif // WEBKIT_GLUE_WEBSOCKETSTREAMHANDLE_DELEGATE_H_ diff --git a/webkit/glue/websocketstreamhandle_impl.cc b/webkit/glue/websocketstreamhandle_impl.cc new file mode 100644 index 0000000..b72c718 --- /dev/null +++ b/webkit/glue/websocketstreamhandle_impl.cc @@ -0,0 +1,151 @@ +// 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. + +// An implementation of WebSocketStreamHandle. + +#include "webkit/glue/websocketstreamhandle_impl.h" + +#include <vector> + +#include "base/compiler_specific.h" +#include "base/logging.h" +#include "base/ref_counted.h" +#include "base/scoped_ptr.h" +#include "webkit/api/public/WebData.h" +#include "webkit/api/public/WebURL.h" +#include "webkit/api/public/WebSocketStreamHandleClient.h" +#include "webkit/glue/websocketstreamhandle_bridge.h" +#include "webkit/glue/websocketstreamhandle_delegate.h" + +namespace webkit_glue { + +// WebSocketStreamHandleImpl::Context ----------------------------------------- + +class WebSocketStreamHandleImpl::Context + : public base::RefCounted<Context>, + public WebSocketStreamHandleDelegate { + public: + explicit Context(WebSocketStreamHandleImpl* handle); + + WebKit::WebSocketStreamHandleClient* client() const { return client_; } + void set_client(WebKit::WebSocketStreamHandleClient* client) { + client_ = client; + } + + void Connect(const WebKit::WebURL& url); + bool Send(const WebKit::WebData& data); + void Close(); + + // WebSocketStreamHandleDelegate methods: + virtual void WillOpenStream(WebKit::WebSocketStreamHandle*, const GURL&); + virtual void DidOpenStream(WebKit::WebSocketStreamHandle*, int); + virtual void DidSendData(WebKit::WebSocketStreamHandle*, int); + virtual void DidReceiveData( + WebKit::WebSocketStreamHandle*, const char*, int); + virtual void DidClose(WebKit::WebSocketStreamHandle*); + + private: + friend class base::RefCounted<Context>; + ~Context() {} + + WebSocketStreamHandleImpl* handle_; + WebKit::WebSocketStreamHandleClient* client_; + WebSocketStreamHandleBridge* bridge_; + + DISALLOW_COPY_AND_ASSIGN(Context); +}; + +WebSocketStreamHandleImpl::Context::Context(WebSocketStreamHandleImpl* handle) + : handle_(handle), + client_(NULL), + bridge_(ALLOW_THIS_IN_INITIALIZER_LIST( + WebSocketStreamHandleBridge::Create(handle_, this))) { +} + +void WebSocketStreamHandleImpl::Context::Connect(const WebKit::WebURL& url) { + LOG(INFO) << "Connect url=" << url; + DCHECK(bridge_); + bridge_->Connect(url); +} + +bool WebSocketStreamHandleImpl::Context::Send(const WebKit::WebData& data) { + LOG(INFO) << "Send data.size=" << data.size(); + DCHECK(bridge_); + return bridge_->Send( + std::vector<char>(data.data(), data.data() + data.size())); +} + +void WebSocketStreamHandleImpl::Context::Close() { + LOG(INFO) << "Close"; + if (bridge_) + bridge_->Close(); +} + +void WebSocketStreamHandleImpl::Context::WillOpenStream( + WebKit::WebSocketStreamHandle* web_handle, const GURL& url) { + LOG(INFO) << "WillOpenStream url=" << url; + if (client_) + client_->willOpenStream(handle_, url); +} + +void WebSocketStreamHandleImpl::Context::DidOpenStream( + WebKit::WebSocketStreamHandle* web_handle, int max_amount_send_allowed) { + LOG(INFO) << "DidOpen"; + if (client_) + client_->didOpenStream(handle_, max_amount_send_allowed); +} + +void WebSocketStreamHandleImpl::Context::DidSendData( + WebKit::WebSocketStreamHandle* web_handle, int amount_sent) { + if (client_) + client_->didSendData(handle_, amount_sent); +} + +void WebSocketStreamHandleImpl::Context::DidReceiveData( + WebKit::WebSocketStreamHandle* web_handle, const char* data, int size) { + if (client_) + client_->didReceiveData(handle_, WebKit::WebData(data, size)); +} + +void WebSocketStreamHandleImpl::Context::DidClose( + WebKit::WebSocketStreamHandle* web_handle) { + LOG(INFO) << "DidClose"; + bridge_ = 0; + WebSocketStreamHandleImpl* handle = handle_; + handle_ = 0; + if (client_) { + WebKit::WebSocketStreamHandleClient* client = client_; + client_ = NULL; + client->didClose(handle); + } +} + +// WebSocketStreamHandleImpl ------------------------------------------------ + +WebSocketStreamHandleImpl::WebSocketStreamHandleImpl() + : ALLOW_THIS_IN_INITIALIZER_LIST(context_(new Context(this))) { +} + +WebSocketStreamHandleImpl::~WebSocketStreamHandleImpl() { + close(); +} + +void WebSocketStreamHandleImpl::connect( + const WebKit::WebURL& url, WebKit::WebSocketStreamHandleClient* client) { + LOG(INFO) << "connect url=" << url; + DCHECK(!context_->client()); + context_->set_client(client); + + context_->Connect(url); +} + +bool WebSocketStreamHandleImpl::send(const WebKit::WebData& data) { + return context_->Send(data); +} + +void WebSocketStreamHandleImpl::close() { + context_->Close(); +} + +} // namespace webkit_glue diff --git a/webkit/glue/websocketstreamhandle_impl.h b/webkit/glue/websocketstreamhandle_impl.h new file mode 100644 index 0000000..657884e --- /dev/null +++ b/webkit/glue/websocketstreamhandle_impl.h @@ -0,0 +1,34 @@ +// 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 WEBKIT_GLUE_WEBSOCKETSTREAMHANDLE_IMPL_H_ +#define WEBKIT_GLUE_WEBSOCKETSTREAMHANDLE_IMPL_H_ + +#include "base/ref_counted.h" +#include "webkit/api/public/WebSocketStreamHandle.h" + +namespace webkit_glue { + +class WebSocketStreamHandleImpl : public WebKit::WebSocketStreamHandle { + public: + WebSocketStreamHandleImpl(); + virtual ~WebSocketStreamHandleImpl(); + + // WebSocketStreamHandle methods: + virtual void connect( + const WebKit::WebURL& url, + WebKit::WebSocketStreamHandleClient* client); + virtual bool send(const WebKit::WebData& data); + virtual void close(); + + private: + class Context; + scoped_refptr<Context> context_; + + DISALLOW_COPY_AND_ASSIGN(WebSocketStreamHandleImpl); +}; + +} // namespace webkit_glue + +#endif // WEBKIT_GLUE_WEBSOCKETSTREAMHANDLE_IMPL_H_ diff --git a/webkit/tools/layout_tests/test_expectations.txt b/webkit/tools/layout_tests/test_expectations.txt index 08e3e1e..45d6bca 100644 --- a/webkit/tools/layout_tests/test_expectations.txt +++ b/webkit/tools/layout_tests/test_expectations.txt @@ -3115,9 +3115,6 @@ BUG_23475 WIN : LayoutTests/svg/custom/junk-data.svg = PASS IMAGE // WebKit roll 49405:49413 BUG_HCLAM : LayoutTests/http/tests/xmlhttprequest/logout.html = FAIL -// WebKit roll 49473:49502 -BUG24756 : LayoutTests/fast/websockets/websocket-event-target.html = FAIL - // WebKit roll 49502:49562 BUG_DIMICH : LayoutTests/fast/events/add-event-without-document.html = TIMEOUT diff --git a/webkit/tools/test_shell/simple_resource_loader_bridge.cc b/webkit/tools/test_shell/simple_resource_loader_bridge.cc index 0f1be30..d45d443 100644 --- a/webkit/tools/test_shell/simple_resource_loader_bridge.cc +++ b/webkit/tools/test_shell/simple_resource_loader_bridge.cc @@ -50,6 +50,7 @@ #include "webkit/appcache/appcache_interfaces.h" #include "webkit/glue/resource_loader_bridge.h" #include "webkit/tools/test_shell/simple_appcache_system.h" +#include "webkit/tools/test_shell/simple_socket_stream_bridge.h" #include "webkit/tools/test_shell/test_shell_request_context.h" using webkit_glue::ResourceLoaderBridge; @@ -76,9 +77,11 @@ class IOThread : public base::Thread { virtual void Init() { SimpleAppCacheSystem::InitializeOnIOThread(request_context); + SimpleSocketStreamBridge::InitializeOnIOThread(request_context); } virtual void CleanUp() { + SimpleSocketStreamBridge::Cleanup(); if (request_context) { request_context->Release(); request_context = NULL; diff --git a/webkit/tools/test_shell/simple_socket_stream_bridge.cc b/webkit/tools/test_shell/simple_socket_stream_bridge.cc new file mode 100644 index 0000000..c8380cd --- /dev/null +++ b/webkit/tools/test_shell/simple_socket_stream_bridge.cc @@ -0,0 +1,227 @@ +// 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 <vector> + +#include "webkit/tools/test_shell/simple_socket_stream_bridge.h" + +#include "base/message_loop.h" +#include "base/ref_counted.h" +#include "googleurl/src/gurl.h" +#include "net/socket_stream/socket_stream.h" +#include "net/url_request/url_request_context.h" +#include "webkit/api/public/WebSocketStreamHandle.h" +#include "webkit/glue/websocketstreamhandle_bridge.h" +#include "webkit/glue/websocketstreamhandle_delegate.h" + +using webkit_glue::WebSocketStreamHandleBridge; + +static const int kNoSocketId = 0; + +namespace { + +MessageLoop* g_io_thread; +scoped_refptr<URLRequestContext> g_request_context; + +class WebSocketStreamHandleBridgeImpl + : public base::RefCountedThreadSafe<WebSocketStreamHandleBridgeImpl>, + public WebSocketStreamHandleBridge, + public net::SocketStream::Delegate { + public: + WebSocketStreamHandleBridgeImpl( + WebKit::WebSocketStreamHandle* handle, + webkit_glue::WebSocketStreamHandleDelegate* delegate); + virtual ~WebSocketStreamHandleBridgeImpl(); + + // WebSocketStreamHandleBridge methods. + virtual void Connect(const GURL& url); + virtual bool Send(const std::vector<char>& data); + virtual void Close(); + + // net::SocketStream::Delegate methods. + virtual void OnConnected(net::SocketStream* req, + int max_pending_send_allowed); + virtual void OnSentData(net::SocketStream* req, + int amount_sent); + virtual void OnReceivedData(net::SocketStream* req, + const char* data, int len); + virtual void OnClose(net::SocketStream* req); + + + private: + // Runs on |g_io_thread|; + void DoConnect(const GURL& url); + void DoSend(std::vector<char>* data); + void DoClose(); + + // Runs on |message_loop_|; + void DoOnConnected(int max_amount_send_allowed); + void DoOnSentData(int amount_sent); + void DoOnReceivedData(std::vector<char>* data); + void DoOnClose(webkit_glue::WebSocketStreamHandleDelegate* delegate); + + int socket_id_; + MessageLoop* message_loop_; + WebKit::WebSocketStreamHandle* handle_; + webkit_glue::WebSocketStreamHandleDelegate* delegate_; + + scoped_refptr<net::SocketStream> socket_; + + DISALLOW_COPY_AND_ASSIGN(WebSocketStreamHandleBridgeImpl); +}; + +WebSocketStreamHandleBridgeImpl::WebSocketStreamHandleBridgeImpl( + WebKit::WebSocketStreamHandle* handle, + webkit_glue::WebSocketStreamHandleDelegate* delegate) + : socket_id_(kNoSocketId), + message_loop_(MessageLoop::current()), + handle_(handle), + delegate_(delegate) { +} + +WebSocketStreamHandleBridgeImpl::~WebSocketStreamHandleBridgeImpl() { + CHECK(socket_id_ == kNoSocketId); +} + +void WebSocketStreamHandleBridgeImpl::Connect(const GURL& url) { + CHECK(g_io_thread); + AddRef(); // Released in DoOnClose(). + g_io_thread->PostTask( + FROM_HERE, + NewRunnableMethod(this, &WebSocketStreamHandleBridgeImpl::DoConnect, + url)); + if (delegate_) + delegate_->WillOpenStream(handle_, url); +} + +bool WebSocketStreamHandleBridgeImpl::Send( + const std::vector<char>& data) { + CHECK(g_io_thread); + g_io_thread->PostTask( + FROM_HERE, + NewRunnableMethod(this, &WebSocketStreamHandleBridgeImpl::DoSend, + new std::vector<char>(data))); + return true; +} + +void WebSocketStreamHandleBridgeImpl::Close() { + CHECK(g_io_thread); + g_io_thread->PostTask( + FROM_HERE, + NewRunnableMethod(this, &WebSocketStreamHandleBridgeImpl::DoClose)); +} + +void WebSocketStreamHandleBridgeImpl::OnConnected( + net::SocketStream* socket, int max_pending_send_allowed) { + message_loop_->PostTask( + FROM_HERE, + NewRunnableMethod(this, &WebSocketStreamHandleBridgeImpl::DoOnConnected, + max_pending_send_allowed)); +} + +void WebSocketStreamHandleBridgeImpl::OnSentData( + net::SocketStream* socket, int amount_sent) { + message_loop_->PostTask( + FROM_HERE, + NewRunnableMethod(this, &WebSocketStreamHandleBridgeImpl::DoOnSentData, + amount_sent)); +} + +void WebSocketStreamHandleBridgeImpl::OnReceivedData( + net::SocketStream* socket, const char* data, int len) { + message_loop_->PostTask( + FROM_HERE, + NewRunnableMethod(this, + &WebSocketStreamHandleBridgeImpl::DoOnReceivedData, + new std::vector<char>(data, data + len))); +} + +void WebSocketStreamHandleBridgeImpl::OnClose(net::SocketStream* socket) { + webkit_glue::WebSocketStreamHandleDelegate* delegate = delegate_; + delegate_ = NULL; + socket_ = 0; + socket_id_ = kNoSocketId; + message_loop_->PostTask( + FROM_HERE, + NewRunnableMethod(this, &WebSocketStreamHandleBridgeImpl::DoOnClose, + delegate)); +} + +void WebSocketStreamHandleBridgeImpl::DoConnect(const GURL& url) { + CHECK(MessageLoop::current() == g_io_thread); + socket_ = new net::SocketStream(url, this); + socket_->set_context(g_request_context); + socket_->Connect(); +} + +void WebSocketStreamHandleBridgeImpl::DoSend(std::vector<char>* data) { + CHECK(MessageLoop::current() == g_io_thread); + scoped_ptr<std::vector<char> > scoped_data(data); + if (!socket_) + return; + if (!socket_->SendData(&(data->at(0)), data->size())) + socket_->Close(); +} + +void WebSocketStreamHandleBridgeImpl::DoClose() { + CHECK(MessageLoop::current() == g_io_thread); + if (!socket_) + return; + socket_->Close(); +} + +void WebSocketStreamHandleBridgeImpl::DoOnConnected( + int max_pending_send_allowed) { + CHECK(MessageLoop::current() == message_loop_); + if (delegate_) + delegate_->DidOpenStream(handle_, max_pending_send_allowed); +} + +void WebSocketStreamHandleBridgeImpl::DoOnSentData(int amount_sent) { + CHECK(MessageLoop::current() == message_loop_); + if (delegate_) + delegate_->DidSendData(handle_, amount_sent); +} + +void WebSocketStreamHandleBridgeImpl::DoOnReceivedData( + std::vector<char>* data) { + CHECK(MessageLoop::current() == message_loop_); + scoped_ptr<std::vector<char> > scoped_data(data); + if (delegate_) + delegate_->DidReceiveData(handle_, &(data->at(0)), data->size()); +} + +void WebSocketStreamHandleBridgeImpl::DoOnClose( + webkit_glue::WebSocketStreamHandleDelegate* delegate) { + CHECK(MessageLoop::current() == message_loop_); + CHECK(!socket_); + if (delegate) + delegate->DidClose(handle_); + Release(); +} + +} // namespace + +/* static */ +void SimpleSocketStreamBridge::InitializeOnIOThread( + URLRequestContext* request_context) { + g_io_thread = MessageLoop::current(); + g_request_context = request_context; +} + +void SimpleSocketStreamBridge::Cleanup() { + g_io_thread = NULL; + g_request_context = NULL; +} + +namespace webkit_glue { + +/* static */ +WebSocketStreamHandleBridge* WebSocketStreamHandleBridge::Create( + WebKit::WebSocketStreamHandle* handle, + WebSocketStreamHandleDelegate* delegate) { + return new WebSocketStreamHandleBridgeImpl(handle, delegate); +} + +} // namespace webkit_glue diff --git a/webkit/tools/test_shell/simple_socket_stream_bridge.h b/webkit/tools/test_shell/simple_socket_stream_bridge.h new file mode 100644 index 0000000..8840323 --- /dev/null +++ b/webkit/tools/test_shell/simple_socket_stream_bridge.h @@ -0,0 +1,16 @@ +// 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 WEBKIT_TOOLS_TEST_SHELL_SIMPLE_SOCKET_STREAM_BRIDGE_H_ +#define WEBKIT_TOOLS_TEST_SHELL_SIMPLE_SOCKET_STREAM_BRIDGE_H_ + +class URLRequestContext; + +class SimpleSocketStreamBridge { + public: + static void InitializeOnIOThread(URLRequestContext* request_context); + static void Cleanup(); +}; + +#endif // WEBKIT_TOOLS_TEST_SHELL_SIMPLE_SOCKET_STREAM_BRIDGE_H_ diff --git a/webkit/tools/test_shell/test_shell.gyp b/webkit/tools/test_shell/test_shell.gyp index 50f6628..06b1ed4 100644 --- a/webkit/tools/test_shell/test_shell.gyp +++ b/webkit/tools/test_shell/test_shell.gyp @@ -74,6 +74,8 @@ 'simple_database_system.h', 'simple_resource_loader_bridge.cc', 'simple_resource_loader_bridge.h', + 'simple_socket_stream_bridge.cc', + 'simple_socket_stream_bridge.h', 'test_navigation_controller.cc', 'test_navigation_controller.h', 'test_shell.cc', diff --git a/webkit/tools/test_shell/test_shell_webkit_init.h b/webkit/tools/test_shell/test_shell_webkit_init.h index 4bcc74b..6363523 100644 --- a/webkit/tools/test_shell/test_shell_webkit_init.h +++ b/webkit/tools/test_shell/test_shell_webkit_init.h @@ -52,6 +52,7 @@ class TestShellWebKitInit : public webkit_glue::WebKitClientImpl { WebKit::enableV8SingleThreadMode(); WebKit::registerExtension(extensions_v8::GearsExtension::Get()); WebKit::registerExtension(extensions_v8::IntervalExtension::Get()); + WebKit::enableWebSockets(); // Load libraries for media and enable the media player. FilePath module_path; diff --git a/webkit/webkit.gyp b/webkit/webkit.gyp index 3ef4f5a..927463a 100644 --- a/webkit/webkit.gyp +++ b/webkit/webkit.gyp @@ -137,6 +137,9 @@ 'api/public/WebSecurityOrigin.h', 'api/public/WebSettings.h', 'api/public/WebSize.h', + 'api/public/WebSocketStreamError.h', + 'api/public/WebSocketStreamHandle.h', + 'api/public/WebSocketStreamHandleClient.h', 'api/public/WebStorageArea.h', 'api/public/WebStorageEventDispatcher.h', 'api/public/WebStorageNamespace.h', @@ -645,6 +648,10 @@ 'glue/webpopupmenu_impl.h', 'glue/webpreferences.cc', 'glue/webpreferences.h', + 'glue/websocketstreamhandle_bridge.h', + 'glue/websocketstreamhandle_delegate.h', + 'glue/websocketstreamhandle_impl.cc', + 'glue/websocketstreamhandle_impl.h', 'glue/webthemeengine_impl_win.cc', 'glue/weburlloader_impl.cc', 'glue/weburlloader_impl.h', |