[SCM] WebKit Debian packaging branch, debian/experimental, updated. upstream/1.3.3-9427-gc2be6fc
mrobinson at webkit.org
mrobinson at webkit.org
Wed Dec 22 13:11:25 UTC 2010
The following commit has been merged in the debian/experimental branch:
commit 3b14f9074f220236a134647df7f2093c500c347a
Author: mrobinson at webkit.org <mrobinson at webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Date: Wed Sep 8 15:27:17 2010 +0000
2010-09-08 Martin Robinson <mrobinson at igalia.com>
Reviewed by Xan Lopez.
[GTK] Need a WebSocket implementation
https://bugs.webkit.org/show_bug.cgi?id=45197
* configure.ac: Enable WebSocket by default.
2010-09-08 Martin Robinson <mrobinson at igalia.com>
Reviewed by Xan Lopez.
[GTK] Need a WebSocket implementation
https://bugs.webkit.org/show_bug.cgi?id=45197
Add a GIO-based WebSocket implementation.
* wtf/gobject/GRefPtr.cpp: Added PlatformRefPtr support for GSource.
(WTF::refPlatformPtr):
(WTF::derefPlatformPtr):
* wtf/gobject/GRefPtr.h: Added new template specialization declarations.
* wtf/gobject/GTypedefs.h: Add some more GLib/GIO forward declarations.
2010-09-08 Martin Robinson <mrobinson at igalia.com>
Reviewed by Xan Lopez.
[GTK] Need a WebSocket implementation
https://bugs.webkit.org/show_bug.cgi?id=45197
* platform/gtk/Skipped: Unskip all WebSocket tests, as they are passing.
2010-09-08 Martin Robinson <mrobinson at igalia.com>
Reviewed by Xan Lopez.
[GTK] Need a WebSocket implementation
https://bugs.webkit.org/show_bug.cgi?id=45197
Add a GIO-based WebSocket implementation. This does not yet support
SSL sockets or proxies, but these should be possible to add as support
arrives in GLib/GIO for them.
* platform/network/soup/SocketStreamHandle.h:
* platform/network/soup/SocketStreamHandleSoup.cpp: Add a GIO-based WebSocket implementation.
(WebCore::isActiveHandle): Added.
(WebCore::deactivateHandle): Added.
(WebCore::SocketStreamHandle::SocketStreamHandle): Filled out stub.
(WebCore::SocketStreamHandle::~SocketStreamHandle): Ditto.
(WebCore::SocketStreamHandle::connected): Added.
(WebCore::SocketStreamHandle::readBytes): Added.
(WebCore::SocketStreamHandle::writeReady): Added.
(WebCore::SocketStreamHandle::platformSend): Filled out stub.
(WebCore::SocketStreamHandle::platformClose): Filled out stub.
(WebCore::SocketStreamHandle::beginWaitingForSocketWritability): Added.
(WebCore::SocketStreamHandle::stopWaitingForSocketWritability):
(WebCore::connectedCallback): Added.
(WebCore::readReadyCallback): Added.
(WebCore::writeReadyCallback): Added.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@66986 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/ChangeLog b/ChangeLog
index fe273ac..f262075 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,12 @@
+2010-09-08 Martin Robinson <mrobinson at igalia.com>
+
+ Reviewed by Xan Lopez.
+
+ [GTK] Need a WebSocket implementation
+ https://bugs.webkit.org/show_bug.cgi?id=45197
+
+ * configure.ac: Enable WebSocket by default.
+
2010-09-08 Gyuyoung Kim <gyuyoung.kim at samsung.com>
Reviewed by Kenneth Rohde Christiansen.
diff --git a/JavaScriptCore/ChangeLog b/JavaScriptCore/ChangeLog
index 0340a1c..9ca5b8c 100644
--- a/JavaScriptCore/ChangeLog
+++ b/JavaScriptCore/ChangeLog
@@ -1,3 +1,18 @@
+2010-09-08 Martin Robinson <mrobinson at igalia.com>
+
+ Reviewed by Xan Lopez.
+
+ [GTK] Need a WebSocket implementation
+ https://bugs.webkit.org/show_bug.cgi?id=45197
+
+ Add a GIO-based WebSocket implementation.
+
+ * wtf/gobject/GRefPtr.cpp: Added PlatformRefPtr support for GSource.
+ (WTF::refPlatformPtr):
+ (WTF::derefPlatformPtr):
+ * wtf/gobject/GRefPtr.h: Added new template specialization declarations.
+ * wtf/gobject/GTypedefs.h: Add some more GLib/GIO forward declarations.
+
2010-08-30 Maciej Stachowiak <mjs at apple.com>
Reviewed by Darin Adler.
diff --git a/JavaScriptCore/wtf/gobject/GRefPtr.cpp b/JavaScriptCore/wtf/gobject/GRefPtr.cpp
index c16024c..14f7cf4 100644
--- a/JavaScriptCore/wtf/gobject/GRefPtr.cpp
+++ b/JavaScriptCore/wtf/gobject/GRefPtr.cpp
@@ -66,4 +66,17 @@ template <> void derefPlatformPtr(GVariant* ptr)
#endif
+template <> GSource* refPlatformPtr(GSource* ptr)
+{
+ if (ptr)
+ g_source_ref(ptr);
+ return ptr;
+}
+
+template <> void derefPlatformPtr(GSource* ptr)
+{
+ if (ptr)
+ g_source_unref(ptr);
+}
+
} // namespace WTF
diff --git a/JavaScriptCore/wtf/gobject/GRefPtr.h b/JavaScriptCore/wtf/gobject/GRefPtr.h
index 1ca55ce..ede0a7a 100644
--- a/JavaScriptCore/wtf/gobject/GRefPtr.h
+++ b/JavaScriptCore/wtf/gobject/GRefPtr.h
@@ -36,6 +36,8 @@ template <> GHashTable* refPlatformPtr(GHashTable* ptr);
template <> void derefPlatformPtr(GHashTable* ptr);
template <> GVariant* refPlatformPtr(GVariant* ptr);
template <> void derefPlatformPtr(GVariant* ptr);
+template <> GSource* refPlatformPtr(GSource* ptr);
+template <> void derefPlatformPtr(GSource* ptr);
template <typename T> inline T* refPlatformPtr(T* ptr)
{
diff --git a/JavaScriptCore/wtf/gobject/GTypedefs.h b/JavaScriptCore/wtf/gobject/GTypedefs.h
index ff9283e..e79ba33 100644
--- a/JavaScriptCore/wtf/gobject/GTypedefs.h
+++ b/JavaScriptCore/wtf/gobject/GTypedefs.h
@@ -36,6 +36,8 @@ typedef unsigned long gulong;
typedef unsigned short gushort;
typedef void* gpointer;
+typedef struct _GAsyncResult GAsyncResult;
+typedef struct _GCancellable GCancellable;
typedef struct _GCond GCond;
typedef struct _GDir GDir;
typedef struct _GdkAtom* GdkAtom;
@@ -47,9 +49,14 @@ typedef struct _GdkPixbuf GdkPixbuf;
typedef struct _GError GError;
typedef struct _GFile GFile;
typedef struct _GHashTable GHashTable;
+typedef struct _GInputStream GInputStream;
typedef struct _GList GList;
typedef struct _GMutex GMutex;
+typedef struct _GOutputStream GOutputStream;
typedef struct _GPatternSpec GPatternSpec;
+typedef struct _GSocketClient GSocketClient;
+typedef struct _GSocketConnection GSocketConnection;
+typedef struct _GSource GSource;
typedef struct _GVariant GVariant;
typedef union _GdkEvent GdkEvent;
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 43a2f18..bbfbbe0 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,12 @@
+2010-09-08 Martin Robinson <mrobinson at igalia.com>
+
+ Reviewed by Xan Lopez.
+
+ [GTK] Need a WebSocket implementation
+ https://bugs.webkit.org/show_bug.cgi?id=45197
+
+ * platform/gtk/Skipped: Unskip all WebSocket tests, as they are passing.
+
2010-09-08 Sergio Villar Senin <svillar at igalia.com>
Reviewed by Adam Barth.
diff --git a/LayoutTests/platform/gtk/Skipped b/LayoutTests/platform/gtk/Skipped
index dd8405b..a3ee333 100644
--- a/LayoutTests/platform/gtk/Skipped
+++ b/LayoutTests/platform/gtk/Skipped
@@ -5181,9 +5181,6 @@ fast/ruby/rubyDOM-remove-rt2.html
fast/ruby/rubyDOM-remove-text1.html
fast/ruby/rubyDOM-remove-text2.html
-# Missing SocketStreamHandle implementation
-websocket/tests
-
# New color correction tests
fast/css/color-correction-backgrounds-and-text.html
fast/css/color-correction-on-backgrounds.html
diff --git a/WebCore/ChangeLog b/WebCore/ChangeLog
index dd47ff7..2661247 100644
--- a/WebCore/ChangeLog
+++ b/WebCore/ChangeLog
@@ -1,3 +1,31 @@
+2010-09-08 Martin Robinson <mrobinson at igalia.com>
+
+ Reviewed by Xan Lopez.
+
+ [GTK] Need a WebSocket implementation
+ https://bugs.webkit.org/show_bug.cgi?id=45197
+
+ Add a GIO-based WebSocket implementation. This does not yet support
+ SSL sockets or proxies, but these should be possible to add as support
+ arrives in GLib/GIO for them.
+
+ * platform/network/soup/SocketStreamHandle.h:
+ * platform/network/soup/SocketStreamHandleSoup.cpp: Add a GIO-based WebSocket implementation.
+ (WebCore::isActiveHandle): Added.
+ (WebCore::deactivateHandle): Added.
+ (WebCore::SocketStreamHandle::SocketStreamHandle): Filled out stub.
+ (WebCore::SocketStreamHandle::~SocketStreamHandle): Ditto.
+ (WebCore::SocketStreamHandle::connected): Added.
+ (WebCore::SocketStreamHandle::readBytes): Added.
+ (WebCore::SocketStreamHandle::writeReady): Added.
+ (WebCore::SocketStreamHandle::platformSend): Filled out stub.
+ (WebCore::SocketStreamHandle::platformClose): Filled out stub.
+ (WebCore::SocketStreamHandle::beginWaitingForSocketWritability): Added.
+ (WebCore::SocketStreamHandle::stopWaitingForSocketWritability):
+ (WebCore::connectedCallback): Added.
+ (WebCore::readReadyCallback): Added.
+ (WebCore::writeReadyCallback): Added.
+
2010-09-07 Martin Robinson <mrobinson at igalia.com>
Reviewed by Dirk Schulze.
diff --git a/WebCore/platform/network/soup/SocketStreamHandle.h b/WebCore/platform/network/soup/SocketStreamHandle.h
index 64139e5..2ba4504 100644
--- a/WebCore/platform/network/soup/SocketStreamHandle.h
+++ b/WebCore/platform/network/soup/SocketStreamHandle.h
@@ -32,8 +32,8 @@
#ifndef SocketStreamHandle_h
#define SocketStreamHandle_h
+#include "GRefPtr.h"
#include "SocketStreamHandleBase.h"
-
#include <wtf/PassRefPtr.h>
#include <wtf/RefCounted.h>
@@ -48,12 +48,21 @@ namespace WebCore {
static PassRefPtr<SocketStreamHandle> create(const KURL& url, SocketStreamHandleClient* client) { return adoptRef(new SocketStreamHandle(url, client)); }
virtual ~SocketStreamHandle();
+ void connected(GSocketConnection*, GError*);
+ void readBytes(signed long, GError*);
+ void writeReady();
protected:
virtual int platformSend(const char* data, int length);
virtual void platformClose();
private:
+ PlatformRefPtr<GSocketConnection> m_socketConnection;
+ PlatformRefPtr<GInputStream> m_inputStream;
+ PlatformRefPtr<GOutputStream> m_outputStream;
+ PlatformRefPtr<GSource> m_writeReadySource;
+ char* m_readBuffer;
+
SocketStreamHandle(const KURL&, SocketStreamHandleClient*);
// No authentication for streams per se, but proxy may ask for credentials.
@@ -61,6 +70,8 @@ namespace WebCore {
void receivedCredential(const AuthenticationChallenge&, const Credential&);
void receivedRequestToContinueWithoutCredential(const AuthenticationChallenge&);
void receivedCancellation(const AuthenticationChallenge&);
+ void beginWaitingForSocketWritability();
+ void stopWaitingForSocketWritability();
};
} // namespace WebCore
diff --git a/WebCore/platform/network/soup/SocketStreamHandleSoup.cpp b/WebCore/platform/network/soup/SocketStreamHandleSoup.cpp
index 6aa33fc..d73b499 100644
--- a/WebCore/platform/network/soup/SocketStreamHandleSoup.cpp
+++ b/WebCore/platform/network/soup/SocketStreamHandleSoup.cpp
@@ -31,38 +31,161 @@
#include "config.h"
#include "SocketStreamHandle.h"
+#include "CString.h"
+#include "GOwnPtr.h"
#include "KURL.h"
#include "Logging.h"
+#include "NotFound.h"
#include "NotImplemented.h"
+#include "SocketStreamError.h"
#include "SocketStreamHandleClient.h"
+#include "Vector.h"
+#include <gio/gio.h>
+#include <glib.h>
+
+#define READ_BUFFER_SIZE 1024
namespace WebCore {
+// These functions immediately call the similarly named SocketStreamHandle methods.
+static void connectedCallback(GSocketClient*, GAsyncResult*, SocketStreamHandle*);
+static void readReadyCallback(GInputStream*, GAsyncResult*, SocketStreamHandle*);
+static gboolean writeReadyCallback(GSocket*, GIOCondition, SocketStreamHandle*);
+
+// Having a list of active handles means that we do not have to worry about WebCore
+// reference counting in GLib callbacks. Once the handle is off the active handles list
+// we just ignore it in the callback. We avoid a lot of extra checks and tricky
+// situations this way.
+static Vector<SocketStreamHandle*> gActiveHandles;
+bool isActiveHandle(SocketStreamHandle* handle)
+{
+ return gActiveHandles.find(handle) != notFound;
+}
+
+void deactivateHandle(SocketStreamHandle* handle)
+{
+ size_t handleIndex = gActiveHandles.find(handle);
+ if (handleIndex != notFound)
+ gActiveHandles.remove(handleIndex);
+}
+
SocketStreamHandle::SocketStreamHandle(const KURL& url, SocketStreamHandleClient* client)
: SocketStreamHandleBase(url, client)
+ , m_readBuffer(0)
{
- LOG(Network, "SocketStreamHandle %p new client %p", this, m_client);
- notImplemented();
+ // No support for SSL sockets yet.
+ if (url.protocolIs("wss"))
+ return;
+ unsigned int port = url.hasPort() ? url.port() : 80;
+
+ gActiveHandles.append(this);
+ PlatformRefPtr<GSocketClient> socketClient = adoptPlatformRef(g_socket_client_new());
+ g_socket_client_connect_to_host_async(socketClient.get(), url.host().utf8().data(), port, 0,
+ reinterpret_cast<GAsyncReadyCallback>(connectedCallback), this);
}
SocketStreamHandle::~SocketStreamHandle()
{
- LOG(Network, "SocketStreamHandle %p delete", this);
+ // If for some reason we were destroyed without closing, ensure that we are deactivated.
+ deactivateHandle(this);
setClient(0);
- notImplemented();
}
-int SocketStreamHandle::platformSend(const char*, int)
+void SocketStreamHandle::connected(GSocketConnection* socketConnection, GError* error)
{
- LOG(Network, "SocketStreamHandle %p platformSend", this);
- notImplemented();
- return 0;
+ if (error) {
+ m_client->didFail(this, SocketStreamError(error->code));
+ return;
+ }
+
+ m_socketConnection = adoptPlatformRef(socketConnection);
+ m_outputStream = g_io_stream_get_output_stream(G_IO_STREAM(m_socketConnection.get()));
+ m_inputStream = g_io_stream_get_input_stream(G_IO_STREAM(m_socketConnection.get()));
+
+ m_readBuffer = new char[READ_BUFFER_SIZE];
+ g_input_stream_read_async(m_inputStream.get(), m_readBuffer, READ_BUFFER_SIZE, G_PRIORITY_DEFAULT, 0,
+ reinterpret_cast<GAsyncReadyCallback>(readReadyCallback), this);
+
+ // The client can close the handle, potentially removing the last reference.
+ RefPtr<SocketStreamHandle> protect(this);
+ m_state = Open;
+ m_client->didOpen(this);
+ if (!m_socketConnection) // Client closed the connection.
+ return;
+}
+
+void SocketStreamHandle::readBytes(signed long bytesRead, GError* error)
+{
+ if (error) {
+ m_client->didFail(this, SocketStreamError(error->code));
+ return;
+ }
+
+ if (!bytesRead) {
+ close();
+ return;
+ }
+
+ // The client can close the handle, potentially removing the last reference.
+ RefPtr<SocketStreamHandle> protect(this);
+ m_client->didReceiveData(this, m_readBuffer, bytesRead);
+ if (m_inputStream) // The client may have closed the connection.
+ g_input_stream_read_async(m_inputStream.get(), m_readBuffer, READ_BUFFER_SIZE, G_PRIORITY_DEFAULT, 0,
+ reinterpret_cast<GAsyncReadyCallback>(readReadyCallback), this);
+}
+
+void SocketStreamHandle::writeReady()
+{
+ // We no longer have buffered data, so stop waiting for the socket to be writable.
+ if (!bufferedAmount()) {
+ stopWaitingForSocketWritability();
+ return;
+ }
+
+ sendPendingData();
+}
+
+int SocketStreamHandle::platformSend(const char* data, int length)
+{
+ if (!g_socket_condition_check(g_socket_connection_get_socket(m_socketConnection.get()), G_IO_OUT)) {
+ beginWaitingForSocketWritability();
+ return 0;
+ }
+
+ GOwnPtr<GError> error;
+ gssize written = g_output_stream_write(m_outputStream.get(), data, length, 0, &error.outPtr());
+ if (error) {
+ m_client->didFail(this, SocketStreamError(error->code)); // FIXME: Provide a sensible error.
+ return 0;
+ }
+
+ // If we did not send all the bytes we were given, we know that
+ // SocketStreamHandleBase will need to send more in the future.
+ if (written < length)
+ beginWaitingForSocketWritability();
+
+ return written;
}
void SocketStreamHandle::platformClose()
{
- LOG(Network, "SocketStreamHandle %p platformClose", this);
- notImplemented();
+ // We remove this handle from the active handles list first, to disable all callbacks.
+ deactivateHandle(this);
+ stopWaitingForSocketWritability();
+
+ if (m_socketConnection) {
+ GOwnPtr<GError> error;
+ g_io_stream_close(G_IO_STREAM(m_socketConnection.get()), 0, &error.outPtr());
+ if (error)
+ m_client->didFail(this, SocketStreamError(error->code)); // FIXME: Provide a sensible error.
+ m_socketConnection = 0;
+ }
+
+ m_outputStream = 0;
+ m_inputStream = 0;
+ delete m_readBuffer;
+
+ m_client->didClose(this);
}
void SocketStreamHandle::didReceiveAuthenticationChallenge(const AuthenticationChallenge&)
@@ -85,4 +208,70 @@ void SocketStreamHandle::receivedCancellation(const AuthenticationChallenge&)
notImplemented();
}
+void SocketStreamHandle::beginWaitingForSocketWritability()
+{
+ if (m_writeReadySource) // Already waiting.
+ return;
+
+ m_writeReadySource = adoptPlatformRef(g_socket_create_source(
+ g_socket_connection_get_socket(m_socketConnection.get()), static_cast<GIOCondition>(G_IO_OUT), 0));
+ g_source_set_callback(m_writeReadySource.get(), reinterpret_cast<GSourceFunc>(writeReadyCallback), this, 0);
+ g_source_attach(m_writeReadySource.get(), 0);
+}
+
+void SocketStreamHandle::stopWaitingForSocketWritability()
+{
+ if (!m_writeReadySource) // Not waiting.
+ return;
+
+ g_source_remove(g_source_get_id(m_writeReadySource.get()));
+ m_writeReadySource = 0;
+}
+
+static void connectedCallback(GSocketClient* client, GAsyncResult* result, SocketStreamHandle* handle)
+{
+ // Always finish the connection, even if this SocketStreamHandle was deactivated earlier.
+ GOwnPtr<GError> error;
+ GSocketConnection* socketConnection = g_socket_client_connect_to_host_finish(client, result, &error.outPtr());
+
+ // The SocketStreamHandle has been deactivated, so just close the connection, ignoring errors.
+ if (!isActiveHandle(handle)) {
+ g_io_stream_close(G_IO_STREAM(socketConnection), 0, &error.outPtr());
+ return;
+ }
+
+ handle->connected(socketConnection, error.get());
+}
+
+static void readReadyCallback(GInputStream* stream, GAsyncResult* result, SocketStreamHandle* handle)
+{
+ // Always finish the read, even if this SocketStreamHandle was deactivated earlier.
+ GOwnPtr<GError> error;
+ gssize bytesRead = g_input_stream_read_finish(stream, result, &error.outPtr());
+
+ if (!isActiveHandle(handle))
+ return;
+ handle->readBytes(bytesRead, error.get());
+}
+
+static gboolean writeReadyCallback(GSocket*, GIOCondition condition, SocketStreamHandle* handle)
+{
+ if (!isActiveHandle(handle))
+ return FALSE;
+
+ // G_IO_HUP and G_IO_ERR are are always active. See:
+ // http://library.gnome.org/devel/gio/stable/GSocket.html#g-socket-create-source
+ if (condition & G_IO_HUP) {
+ handle->close();
+ return FALSE;
+ }
+ if (condition & G_IO_ERR) {
+ handle->client()->didFail(handle, SocketStreamError(0)); // FIXME: Provide a sensible error.
+ return FALSE;
+ }
+ if (condition & G_IO_OUT)
+ handle->writeReady();
+ return TRUE;
+}
+
} // namespace WebCore
diff --git a/configure.ac b/configure.ac
index 64908a2..2e93cd3 100644
--- a/configure.ac
+++ b/configure.ac
@@ -628,8 +628,8 @@ fi
AC_MSG_CHECKING([whether to enable Web Sockets support])
AC_ARG_ENABLE(web_sockets,
AC_HELP_STRING([--enable-web-sockets],
- [enable support for Web Sockets [default=no]]),
- [],[enable_web_sockets="no"])
+ [enable support for Web Sockets [default=yes]]),
+ [],[enable_web_sockets="yes"])
AC_MSG_RESULT([$enable_web_sockets])
# check whether to enable Web Timing support
--
WebKit Debian packaging
More information about the Pkg-webkit-commits
mailing list