Title: [246877] trunk/Source
Revision
246877
Author
[email protected]
Date
2019-06-27 01:52:38 -0700 (Thu, 27 Jun 2019)

Log Message

[SOUP] Use libsoup WebSockets API
https://bugs.webkit.org/show_bug.cgi?id=199151

Reviewed by Michael Catanzaro.

Source/WebCore:

Use createWebSocketChannel() from the provider also for libsoup when WEBKIT_USE_SOUP_WEBSOCKETS env var is set.

* Modules/websockets/ThreadableWebSocketChannel.cpp:
(WebCore::ThreadableWebSocketChannel::create):

Source/WebKit:

Use the new WebSockets code path that depends on platform specific WebSockets implementation using the libsoup
API. This is an initial implementation manually tested using the layout tests, which most of them fail due to
missing console messages, missing features in the new code path or differences in the platform
implementation. It will be disabled by default until it's feature complete compared to the internal WebKit
implementation.

* NetworkProcess/NetworkSocketChannel.cpp:
(WebKit::NetworkSocketChannel::NetworkSocketChannel): Null check m_socket before using it, because
createWebSocketTask() can return nullptr;
(WebKit::NetworkSocketChannel::didConnect): Receive the protocol accepted by the server.
(WebKit::NetworkSocketChannel::didReceiveMessageError): Something failed in the server side.
* NetworkProcess/NetworkSocketChannel.h:
* NetworkProcess/WebSocketTask.h:
* NetworkProcess/soup/NetworkSessionSoup.cpp:
(WebKit::NetworkSessionSoup::createWebSocketTask): Create a WebSocketTask.
* NetworkProcess/soup/NetworkSessionSoup.h:
* NetworkProcess/soup/WebSocketTaskSoup.cpp: Added.
(WebKit::WebSocketTask::WebSocketTask):
(WebKit::WebSocketTask::~WebSocketTask):
(WebKit::WebSocketTask::didConnect):
(WebKit::WebSocketTask::didReceiveMessageCallback):
(WebKit::WebSocketTask::didReceiveErrorCallback):
(WebKit::WebSocketTask::didFail):
(WebKit::WebSocketTask::didCloseCallback):
(WebKit::WebSocketTask::didClose):
(WebKit::WebSocketTask::sendString):
(WebKit::WebSocketTask::sendData):
(WebKit::WebSocketTask::close):
(WebKit::WebSocketTask::cancel):
(WebKit::WebSocketTask::resume):
* NetworkProcess/soup/WebSocketTaskSoup.h: Copied from Source/WebKit/NetworkProcess/WebSocketTask.h.
* SourcesGTK.txt:
* WebProcess/Network/WebSocketChannel.cpp:
(WebKit::WebSocketChannel::subprotocol): Return the protocol accepted by the server.
(WebKit::WebSocketChannel::didConnect): Set the protocol accepted by the server.
(WebKit::WebSocketChannel::didReceiveMessageError): It's now an IPC message handler and receives the reason as parameter.
(WebKit::WebSocketChannel::networkProcessCrashed): Pass empty reason.
* WebProcess/Network/WebSocketChannel.h:
* WebProcess/Network/WebSocketChannel.messages.in:

Modified Paths

Added Paths

Diff

Modified: trunk/Source/WebCore/ChangeLog (246876 => 246877)


--- trunk/Source/WebCore/ChangeLog	2019-06-27 08:25:04 UTC (rev 246876)
+++ trunk/Source/WebCore/ChangeLog	2019-06-27 08:52:38 UTC (rev 246877)
@@ -1,3 +1,15 @@
+2019-06-27  Carlos Garcia Campos  <[email protected]>
+
+        [SOUP] Use libsoup WebSockets API
+        https://bugs.webkit.org/show_bug.cgi?id=199151
+
+        Reviewed by Michael Catanzaro.
+
+        Use createWebSocketChannel() from the provider also for libsoup when WEBKIT_USE_SOUP_WEBSOCKETS env var is set.
+
+        * Modules/websockets/ThreadableWebSocketChannel.cpp:
+        (WebCore::ThreadableWebSocketChannel::create):
+
 2019-06-27  Devin Rousso  <[email protected]>
 
         Web Inspector: throw an error if console.count/console.countReset is called with an object that throws an error from toString

Modified: trunk/Source/WebCore/Modules/websockets/ThreadableWebSocketChannel.cpp (246876 => 246877)


--- trunk/Source/WebCore/Modules/websockets/ThreadableWebSocketChannel.cpp	2019-06-27 08:25:04 UTC (rev 246876)
+++ trunk/Source/WebCore/Modules/websockets/ThreadableWebSocketChannel.cpp	2019-06-27 08:52:38 UTC (rev 246877)
@@ -58,12 +58,19 @@
 
     auto& document = downcast<Document>(context);
 
+    bool shouldProviderCreateSocketChannel = false;
 #if HAVE(NSURLSESSION_WEBSOCKET)
-    if (RuntimeEnabledFeatures::sharedFeatures().isNSURLSessionWebSocketEnabled()) {
+    shouldProviderCreateSocketChannel = RuntimeEnabledFeatures::sharedFeatures().isNSURLSessionWebSocketEnabled();
+#endif
+#if USE(SOUP)
+    shouldProviderCreateSocketChannel = getenv("WEBKIT_USE_SOUP_WEBSOCKETS");
+#endif
+
+    if (shouldProviderCreateSocketChannel) {
         if (auto channel = provider.createWebSocketChannel(document, client))
             return channel.releaseNonNull();
     }
-#endif
+
     return WebSocketChannel::create(document, client, provider);
 }
 

Modified: trunk/Source/WebKit/ChangeLog (246876 => 246877)


--- trunk/Source/WebKit/ChangeLog	2019-06-27 08:25:04 UTC (rev 246876)
+++ trunk/Source/WebKit/ChangeLog	2019-06-27 08:52:38 UTC (rev 246877)
@@ -1,3 +1,50 @@
+2019-06-27  Carlos Garcia Campos  <[email protected]>
+
+        [SOUP] Use libsoup WebSockets API
+        https://bugs.webkit.org/show_bug.cgi?id=199151
+
+        Reviewed by Michael Catanzaro.
+
+        Use the new WebSockets code path that depends on platform specific WebSockets implementation using the libsoup
+        API. This is an initial implementation manually tested using the layout tests, which most of them fail due to
+        missing console messages, missing features in the new code path or differences in the platform
+        implementation. It will be disabled by default until it's feature complete compared to the internal WebKit
+        implementation.
+
+        * NetworkProcess/NetworkSocketChannel.cpp:
+        (WebKit::NetworkSocketChannel::NetworkSocketChannel): Null check m_socket before using it, because
+        createWebSocketTask() can return nullptr;
+        (WebKit::NetworkSocketChannel::didConnect): Receive the protocol accepted by the server.
+        (WebKit::NetworkSocketChannel::didReceiveMessageError): Something failed in the server side.
+        * NetworkProcess/NetworkSocketChannel.h:
+        * NetworkProcess/WebSocketTask.h:
+        * NetworkProcess/soup/NetworkSessionSoup.cpp:
+        (WebKit::NetworkSessionSoup::createWebSocketTask): Create a WebSocketTask.
+        * NetworkProcess/soup/NetworkSessionSoup.h:
+        * NetworkProcess/soup/WebSocketTaskSoup.cpp: Added.
+        (WebKit::WebSocketTask::WebSocketTask):
+        (WebKit::WebSocketTask::~WebSocketTask):
+        (WebKit::WebSocketTask::didConnect):
+        (WebKit::WebSocketTask::didReceiveMessageCallback):
+        (WebKit::WebSocketTask::didReceiveErrorCallback):
+        (WebKit::WebSocketTask::didFail):
+        (WebKit::WebSocketTask::didCloseCallback):
+        (WebKit::WebSocketTask::didClose):
+        (WebKit::WebSocketTask::sendString):
+        (WebKit::WebSocketTask::sendData):
+        (WebKit::WebSocketTask::close):
+        (WebKit::WebSocketTask::cancel):
+        (WebKit::WebSocketTask::resume):
+        * NetworkProcess/soup/WebSocketTaskSoup.h: Copied from Source/WebKit/NetworkProcess/WebSocketTask.h.
+        * SourcesGTK.txt:
+        * WebProcess/Network/WebSocketChannel.cpp:
+        (WebKit::WebSocketChannel::subprotocol): Return the protocol accepted by the server.
+        (WebKit::WebSocketChannel::didConnect): Set the protocol accepted by the server.
+        (WebKit::WebSocketChannel::didReceiveMessageError): It's now an IPC message handler and receives the reason as parameter.
+        (WebKit::WebSocketChannel::networkProcessCrashed): Pass empty reason.
+        * WebProcess/Network/WebSocketChannel.h:
+        * WebProcess/Network/WebSocketChannel.messages.in:
+
 2019-06-21  Konstantin Tokarev  <[email protected]>
 
         [cmake] Switch to built-in handling of C++ standard instead of hardcoding -std=c++17

Modified: trunk/Source/WebKit/NetworkProcess/NetworkSocketChannel.cpp (246876 => 246877)


--- trunk/Source/WebKit/NetworkProcess/NetworkSocketChannel.cpp	2019-06-27 08:25:04 UTC (rev 246876)
+++ trunk/Source/WebKit/NetworkProcess/NetworkSocketChannel.cpp	2019-06-27 08:52:38 UTC (rev 246877)
@@ -55,9 +55,10 @@
         return;
 
     m_socket = m_session->createWebSocketTask(*this, request, protocol);
-
-    m_session->addWebSocketTask(*m_socket);
-    m_socket->resume();
+    if (m_socket) {
+        m_session->addWebSocketTask(*m_socket);
+        m_socket->resume();
+    }
 }
 
 NetworkSocketChannel::~NetworkSocketChannel()
@@ -96,9 +97,9 @@
     finishClosingIfPossible();
 }
 
-void NetworkSocketChannel::didConnect()
+void NetworkSocketChannel::didConnect(const String& subprotocol)
 {
-    send(Messages::WebSocketChannel::DidConnect { });
+    send(Messages::WebSocketChannel::DidConnect { subprotocol });
 }
 
 void NetworkSocketChannel::didReceiveText(const String& text)
@@ -117,6 +118,11 @@
     finishClosingIfPossible();
 }
 
+void NetworkSocketChannel::didReceiveMessageError(const String& errorMessage)
+{
+    send(Messages::WebSocketChannel::DidReceiveMessageError { errorMessage });
+}
+
 IPC::Connection* NetworkSocketChannel::messageSenderConnection() const
 {
     return &m_connectionToWebProcess.connection();

Modified: trunk/Source/WebKit/NetworkProcess/NetworkSocketChannel.h (246876 => 246877)


--- trunk/Source/WebKit/NetworkProcess/NetworkSocketChannel.h	2019-06-27 08:25:04 UTC (rev 246876)
+++ trunk/Source/WebKit/NetworkProcess/NetworkSocketChannel.h	2019-06-27 08:52:38 UTC (rev 246877)
@@ -59,10 +59,11 @@
     friend class WebSocketTask;
 
 private:
-    void didConnect();
+    void didConnect(const String& subprotocol);
     void didReceiveText(const String&);
     void didReceiveBinaryData(const uint8_t* data, size_t length);
     void didClose(unsigned short code, const String& reason);
+    void didReceiveMessageError(const String&);
 
     void sendString(const String&, CompletionHandler<void()>&&);
     void sendData(const IPC::DataReference&, CompletionHandler<void()>&&);

Modified: trunk/Source/WebKit/NetworkProcess/WebSocketTask.h (246876 => 246877)


--- trunk/Source/WebKit/NetworkProcess/WebSocketTask.h	2019-06-27 08:25:04 UTC (rev 246876)
+++ trunk/Source/WebKit/NetworkProcess/WebSocketTask.h	2019-06-27 08:52:38 UTC (rev 246877)
@@ -27,6 +27,8 @@
 
 #if PLATFORM(COCOA) && HAVE(NSURLSESSION_WEBSOCKET)
 #include "WebSocketTaskCocoa.h"
+#elif USE(SOUP)
+#include "WebSocketTaskSoup.h"
 #else
 
 namespace WebKit {

Modified: trunk/Source/WebKit/NetworkProcess/soup/NetworkSessionSoup.cpp (246876 => 246877)


--- trunk/Source/WebKit/NetworkProcess/soup/NetworkSessionSoup.cpp	2019-06-27 08:25:04 UTC (rev 246876)
+++ trunk/Source/WebKit/NetworkProcess/soup/NetworkSessionSoup.cpp	2019-06-27 08:52:38 UTC (rev 246877)
@@ -29,7 +29,9 @@
 #include "NetworkProcess.h"
 #include "NetworkSessionCreationParameters.h"
 #include "WebCookieManager.h"
+#include "WebSocketTaskSoup.h"
 #include <WebCore/NetworkStorageSession.h>
+#include <WebCore/ResourceRequest.h>
 #include <WebCore/SoupNetworkSession.h>
 #include <libsoup/soup.h>
 
@@ -65,4 +67,15 @@
 #endif
 }
 
+std::unique_ptr<WebSocketTask> NetworkSessionSoup::createWebSocketTask(NetworkSocketChannel& channel, const ResourceRequest& request, const String& protocol)
+{
+    GUniquePtr<SoupURI> soupURI = request.createSoupURI();
+    if (!soupURI)
+        return nullptr;
+
+    GRefPtr<SoupMessage> soupMessage = adoptGRef(soup_message_new_from_uri(SOUP_METHOD_GET, soupURI.get()));
+    request.updateSoupMessage(soupMessage.get());
+    return std::make_unique<WebSocketTask>(channel, soupSession(), soupMessage.get(), protocol);
+}
+
 } // namespace WebKit

Modified: trunk/Source/WebKit/NetworkProcess/soup/NetworkSessionSoup.h (246876 => 246877)


--- trunk/Source/WebKit/NetworkProcess/soup/NetworkSessionSoup.h	2019-06-27 08:25:04 UTC (rev 246876)
+++ trunk/Source/WebKit/NetworkProcess/soup/NetworkSessionSoup.h	2019-06-27 08:52:38 UTC (rev 246877)
@@ -31,6 +31,8 @@
 
 namespace WebKit {
 
+class NetworkSocketChannel;
+class WebSocketTask;
 struct NetworkSessionCreationParameters;
 
 class NetworkSessionSoup final : public NetworkSession {
@@ -46,6 +48,8 @@
 private:
     NetworkSessionSoup(NetworkProcess&, NetworkSessionCreationParameters&&);
 
+    std::unique_ptr<WebSocketTask> createWebSocketTask(NetworkSocketChannel&, const WebCore::ResourceRequest&, const String& protocol) override;
+
     void clearCredentials() override;
 };
 

Added: trunk/Source/WebKit/NetworkProcess/soup/WebSocketTaskSoup.cpp (0 => 246877)


--- trunk/Source/WebKit/NetworkProcess/soup/WebSocketTaskSoup.cpp	                        (rev 0)
+++ trunk/Source/WebKit/NetworkProcess/soup/WebSocketTaskSoup.cpp	2019-06-27 08:52:38 UTC (rev 246877)
@@ -0,0 +1,181 @@
+/*
+ * Copyright (C) 2019 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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.
+ */
+
+#include "config.h"
+#include "WebSocketTaskSoup.h"
+
+#include "DataReference.h"
+#include "NetworkSocketChannel.h"
+#include <WebCore/HTTPParsers.h>
+#include <wtf/glib/GUniquePtr.h>
+
+namespace WebKit {
+
+WebSocketTask::WebSocketTask(NetworkSocketChannel& channel, SoupSession* session, SoupMessage* msg, const String& protocol)
+    : m_channel(channel)
+    , m_cancellable(adoptGRef(g_cancellable_new()))
+{
+    auto protocolList = protocol.split(',');
+    GUniquePtr<char*> protocols;
+    if (!protocolList.isEmpty()) {
+        protocols.reset(static_cast<char**>(g_new0(char*, protocolList.size() + 1)));
+        unsigned i = 0;
+        for (auto& subprotocol : protocolList)
+            protocols.get()[i++] = g_strdup(WebCore::stripLeadingAndTrailingHTTPSpaces(subprotocol).utf8().data());
+    }
+    soup_session_websocket_connect_async(session, msg, nullptr, protocols.get(), m_cancellable.get(),
+        [] (GObject* session, GAsyncResult* result, gpointer userData) {
+            GUniqueOutPtr<GError> error;
+            GRefPtr<SoupWebsocketConnection> connection = adoptGRef(soup_session_websocket_connect_finish(SOUP_SESSION(session), result, &error.outPtr()));
+            if (g_error_matches(error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED))
+                return;
+            auto* task = static_cast<WebSocketTask*>(userData);
+            if (connection)
+                task->didConnect(WTFMove(connection));
+            else
+                task->didFail(String::fromUTF8(error->message));
+        }, this);
+}
+
+WebSocketTask::~WebSocketTask()
+{
+    cancel();
+}
+
+void WebSocketTask::didConnect(GRefPtr<SoupWebsocketConnection>&& connection)
+{
+    m_connection = WTFMove(connection);
+
+#if SOUP_CHECK_VERSION(2, 56, 0)
+    // Use the same maximum payload length as WebKit internal implementation for backwards compatibility.
+    static const uint64_t maxPayloadLength = UINT64_C(0x7FFFFFFFFFFFFFFF);
+    soup_websocket_connection_set_max_incoming_payload_size(m_connection.get(), maxPayloadLength);
+#endif
+
+    g_signal_connect_swapped(m_connection.get(), "message", reinterpret_cast<GCallback>(didReceiveMessageCallback), this);
+    g_signal_connect_swapped(m_connection.get(), "error", reinterpret_cast<GCallback>(didReceiveErrorCallback), this);
+    g_signal_connect_swapped(m_connection.get(), "closed", reinterpret_cast<GCallback>(didCloseCallback), this);
+
+    m_channel.didConnect(soup_websocket_connection_get_protocol(m_connection.get()));
+}
+
+void WebSocketTask::didReceiveMessageCallback(WebSocketTask* task, SoupWebsocketDataType dataType, GBytes* message)
+{
+    if (g_cancellable_is_cancelled(task->m_cancellable.get()))
+        return;
+
+    switch (dataType) {
+    case SOUP_WEBSOCKET_DATA_TEXT:
+        task->m_channel.didReceiveText(String::fromUTF8(static_cast<const char*>(g_bytes_get_data(message, nullptr))));
+        break;
+    case SOUP_WEBSOCKET_DATA_BINARY: {
+        gsize dataSize;
+        auto data = "" &dataSize);
+        task->m_channel.didReceiveBinaryData(static_cast<const uint8_t*>(data), dataSize);
+        break;
+    }
+    }
+}
+
+void WebSocketTask::didReceiveErrorCallback(WebSocketTask* task, GError* error)
+{
+    if (g_cancellable_is_cancelled(task->m_cancellable.get()))
+        return;
+
+    task->didFail(String::fromUTF8(error->message));
+}
+
+void WebSocketTask::didFail(const String& errorMessage)
+{
+    if (m_receivedDidFail)
+        return;
+
+    m_receivedDidFail = true;
+    m_channel.didReceiveMessageError(errorMessage);
+    if (!m_connection) {
+        didClose(SOUP_WEBSOCKET_CLOSE_ABNORMAL, { });
+        return;
+    }
+
+    if (soup_websocket_connection_get_state(m_connection.get()) == SOUP_WEBSOCKET_STATE_OPEN)
+        didClose(0, { });
+}
+
+void WebSocketTask::didCloseCallback(WebSocketTask* task)
+{
+    task->didClose(soup_websocket_connection_get_close_code(task->m_connection.get()), String::fromUTF8(soup_websocket_connection_get_close_data(task->m_connection.get())));
+}
+
+void WebSocketTask::didClose(unsigned short code, const String& reason)
+{
+    if (m_receivedDidClose)
+        return;
+
+    m_receivedDidClose = true;
+    m_channel.didClose(code, reason);
+}
+
+void WebSocketTask::sendString(const String& text, CompletionHandler<void()>&& callback)
+{
+    if (m_connection && soup_websocket_connection_get_state(m_connection.get()) == SOUP_WEBSOCKET_STATE_OPEN)
+        soup_websocket_connection_send_text(m_connection.get(), text.utf8().data());
+    callback();
+}
+
+void WebSocketTask::sendData(const IPC::DataReference& data, CompletionHandler<void()>&& callback)
+{
+    if (m_connection && soup_websocket_connection_get_state(m_connection.get()) == SOUP_WEBSOCKET_STATE_OPEN)
+        soup_websocket_connection_send_binary(m_connection.get(), data.data(), data.size());
+    callback();
+}
+
+void WebSocketTask::close(int32_t code, const String& reason)
+{
+    if (m_receivedDidClose)
+        return;
+
+    if (m_connection)
+        soup_websocket_connection_close(m_connection.get(), code, reason.utf8().data());
+    else {
+        g_cancellable_cancel(m_cancellable.get());
+        didClose(code ? code : SOUP_WEBSOCKET_CLOSE_ABNORMAL, reason);
+    }
+}
+
+void WebSocketTask::cancel()
+{
+    g_cancellable_cancel(m_cancellable.get());
+
+    if (m_connection) {
+        g_signal_handlers_disconnect_matched(m_connection.get(), G_SIGNAL_MATCH_DATA, 0, 0, nullptr, nullptr, this);
+        m_connection = nullptr;
+    }
+}
+
+void WebSocketTask::resume()
+{
+}
+
+} // namespace WebKit

Copied: trunk/Source/WebKit/NetworkProcess/soup/WebSocketTaskSoup.h (from rev 246876, trunk/Source/WebKit/NetworkProcess/WebSocketTask.h) (0 => 246877)


--- trunk/Source/WebKit/NetworkProcess/soup/WebSocketTaskSoup.h	                        (rev 0)
+++ trunk/Source/WebKit/NetworkProcess/soup/WebSocketTaskSoup.h	2019-06-27 08:52:38 UTC (rev 246877)
@@ -0,0 +1,66 @@
+/*
+ * Copyright (C) 2019 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS 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 APPLE INC. OR ITS 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.
+ */
+
+#pragma once
+
+#include <libsoup/soup.h>
+#include <wtf/glib/GRefPtr.h>
+
+namespace IPC {
+class DataReference;
+}
+
+namespace WebKit {
+class NetworkSocketChannel;
+
+class WebSocketTask {
+public:
+    WebSocketTask(NetworkSocketChannel&, SoupSession*, SoupMessage*, const String& protocol);
+    ~WebSocketTask();
+
+    void sendString(const String&, CompletionHandler<void()>&&);
+    void sendData(const IPC::DataReference&, CompletionHandler<void()>&&);
+    void close(int32_t code, const String& reason);
+
+    void cancel();
+    void resume();
+
+private:
+    void didConnect(GRefPtr<SoupWebsocketConnection>&&);
+    void didFail(const String&);
+    void didClose(unsigned short code, const String& reason);
+
+    static void didReceiveMessageCallback(WebSocketTask*, SoupWebsocketDataType, GBytes*);
+    static void didReceiveErrorCallback(WebSocketTask*, GError*);
+    static void didCloseCallback(WebSocketTask*);
+
+    NetworkSocketChannel& m_channel;
+    GRefPtr<SoupWebsocketConnection> m_connection;
+    GRefPtr<GCancellable> m_cancellable;
+    bool m_receivedDidFail { false };
+    bool m_receivedDidClose { false };
+};
+
+} // namespace WebKit

Modified: trunk/Source/WebKit/SourcesGTK.txt (246876 => 246877)


--- trunk/Source/WebKit/SourcesGTK.txt	2019-06-27 08:25:04 UTC (rev 246876)
+++ trunk/Source/WebKit/SourcesGTK.txt	2019-06-27 08:52:38 UTC (rev 246877)
@@ -42,6 +42,7 @@
 NetworkProcess/soup/NetworkSessionSoup.cpp
 NetworkProcess/soup/RemoteNetworkingContextSoup.cpp
 NetworkProcess/soup/WebKitSoupRequestInputStream.cpp
+NetworkProcess/soup/WebSocketTaskSoup.cpp
 
 NetworkProcess/webrtc/LibWebRTCSocketClient.cpp
 NetworkProcess/webrtc/NetworkRTCMonitor.cpp

Modified: trunk/Source/WebKit/WebProcess/Network/WebSocketChannel.cpp (246876 => 246877)


--- trunk/Source/WebKit/WebProcess/Network/WebSocketChannel.cpp	2019-06-27 08:25:04 UTC (rev 246876)
+++ trunk/Source/WebKit/WebProcess/Network/WebSocketChannel.cpp	2019-06-27 08:52:38 UTC (rev 246877)
@@ -67,8 +67,7 @@
 
 String WebSocketChannel::subprotocol()
 {
-    // FIXME: support subprotocol.
-    return emptyString();
+    return m_subprotocol.isNull() ? emptyString() : m_subprotocol;
 }
 
 String WebSocketChannel::extensions()
@@ -162,7 +161,7 @@
     MessageSender::send(Messages::NetworkSocketChannel::Close { 0, { } });
 }
 
-void WebSocketChannel::didConnect()
+void WebSocketChannel::didConnect(const String& subprotocol)
 {
     if (m_isClosing)
         return;
@@ -171,12 +170,13 @@
         return;
 
     if (m_isSuspended) {
-        enqueueTask([this] {
-            didConnect();
+        enqueueTask([this, subprotocol] {
+            didConnect(subprotocol);
         });
         return;
     }
 
+    m_subprotocol = subprotocol;
     m_client->didConnect();
 }
 
@@ -234,24 +234,25 @@
     m_client->didClose(m_bufferedAmount, (m_isClosing || code == WebCore::WebSocketChannel::CloseEventCodeNormalClosure) ? WebCore::WebSocketChannelClient::ClosingHandshakeComplete : WebCore::WebSocketChannelClient::ClosingHandshakeIncomplete, code, reason);
 }
 
-void WebSocketChannel::didFail()
+void WebSocketChannel::didReceiveMessageError(const String& errorMessage)
 {
     if (!m_client)
         return;
 
     if (m_isSuspended) {
-        enqueueTask([this] {
-            didFail();
+        enqueueTask([this, errorMessage] {
+            didReceiveMessageError(errorMessage);
         });
         return;
     }
 
+    // FIXME: do something with errorMessage.
     m_client->didReceiveMessageError();
 }
 
 void WebSocketChannel::networkProcessCrashed()
 {
-    didFail();
+    didReceiveMessageError({ });
 }
 
 void WebSocketChannel::suspend()

Modified: trunk/Source/WebKit/WebProcess/Network/WebSocketChannel.h (246876 => 246877)


--- trunk/Source/WebKit/WebProcess/Network/WebSocketChannel.h	2019-06-27 08:25:04 UTC (rev 246876)
+++ trunk/Source/WebKit/WebProcess/Network/WebSocketChannel.h	2019-06-27 08:52:38 UTC (rev 246877)
@@ -49,7 +49,6 @@
     void didReceiveMessage(IPC::Connection&, IPC::Decoder&);
 
     void networkProcessCrashed();
-    void didFail();
 
     using RefCounted<WebSocketChannel>::ref;
     using RefCounted<WebSocketChannel>::deref;
@@ -74,10 +73,11 @@
     void derefThreadableWebSocketChannel() final { deref(); }
 
     // Message receivers
-    void didConnect();
+    void didConnect(const String&);
     void didReceiveText(const String&);
     void didReceiveBinaryData(const IPC::DataReference&);
     void didClose(unsigned short code, const String&);
+    void didReceiveMessageError(const String&);
 
     // MessageSender
     IPC::Connection* messageSenderConnection() const final;
@@ -87,6 +87,7 @@
 
     WeakPtr<WebCore::Document> m_document;
     WeakPtr<WebCore::WebSocketChannelClient> m_client;
+    String m_subprotocol;
     size_t m_bufferedAmount { 0 };
     bool m_isClosing { false };
     bool m_isSuspended { false };

Modified: trunk/Source/WebKit/WebProcess/Network/WebSocketChannel.messages.in (246876 => 246877)


--- trunk/Source/WebKit/WebProcess/Network/WebSocketChannel.messages.in	2019-06-27 08:25:04 UTC (rev 246876)
+++ trunk/Source/WebKit/WebProcess/Network/WebSocketChannel.messages.in	2019-06-27 08:52:38 UTC (rev 246877)
@@ -21,8 +21,9 @@
 # OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 
 messages -> WebSocketChannel {
-    DidConnect()
+    DidConnect(String subprotocol)
     DidClose(unsigned short code, String reason)
     DidReceiveText(String message)
     DidReceiveBinaryData(IPC::DataReference data)
+    DidReceiveMessageError(String errorMessage)
 }
_______________________________________________
webkit-changes mailing list
[email protected]
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to