Title: [291648] branches/safari-613-branch/Source
Revision
291648
Author
alanc...@apple.com
Date
2022-03-22 10:55:34 -0700 (Tue, 22 Mar 2022)

Log Message

Cherry-pick r290856. rdar://problem/89569036

    REGRESSION (r284472): [ Monterey ] http/tests/websocket/tests/hybi/inspector/send-and-recieve-debugger.html is failing
    https://bugs.webkit.org/show_bug.cgi?id=237280

    Reviewed by Devin Rousso.

    Source/WebCore:

    Covered by existing http/tests/websocket/tests/hybi/inspector/* test cases.

    On macOS Monterey we use NSURLSession-based WebSockets by default, unlike earlier versions of macOS. The channel
    for these sockets is implemented in `WebKit::WebSocketChannel`. The non-NSURLSession WebSockets channel (at
    least on Cocoa platforms) is implemented in `WebCore::WebSocketChannel`.

    As of r284472 the logic to delay the dispatch of received WebSocket message on platforms using
    NSURLSession-based WebSockets is handled by `WebCore::WebSocket`, not the `WebKit::WebSocketChannel`.
    `WebKit::WebSocketChannel` now immediately does the work it needs to, and only the delegated work to `WebSocket`
    is queued and taken care of when the socket has resumed. This resulted in some of the instrumentation in
    `WebKit::WebSocketChannel` being able to be called while the socket was suspended leading to events being logged
    in the frontend "in the future" (e.g. before the paused script would have been able to be aware of them). To
    correct this the `WebKit::WebSocketChannel` now provides a hook into its helper `WebSocketChannelInspector`
    object to allow the `WebCore::WebSocket` to notify Web Inspector of events at the same time it is being
    logically handled by the page.

    Other `ThreadableWebSocketChannel` implementations will instead provide `nullptr` in place of a pointer to a
    `WebInspectorChannelInspector`. `WebCore::WebSocketChannel` was not affected by the changes in r284472 as it has
    a different way to guarantee that the methods containing InspectorInstrumentation were not called while the
    channel was suspended (and enforced with numerous `ASSERT(!m_suspended)` checks).

    * Modules/websockets/ThreadableWebSocketChannel.h:
    (WebCore::ThreadableWebSocketChannel::channelInspector const):

    * Modules/websockets/WebSocketChannelClient.h:
    - Add `reason` for error messages so they can be sent to Web Inspector.

    * Modules/websockets/WebSocket.cpp:
    (WebCore::WebSocket::didReceiveMessage):
    (WebCore::WebSocket::didReceiveBinaryData):
    (WebCore::WebSocket::didReceiveMessageError):
    (WebCore::WebSocket::didClose):
    * Modules/websockets/WebSocket.h:
    - Move inspector instrumentation calls from `WebKit::WebSocketChannel` to here so that they are not called until
    the socket is resumed.
    - We also now wrap these instrumentation calls in an unlikely check for frontends to avoid allocating the
    simulated call frames when Web Inspector isn't even open.

    * Modules/websockets/WebSocketChannelInspector.cpp:
    (WebCore::WebSocketChannelInspector::WebSocketChannelInspector):
    (WebCore::WebSocketChannelInspector::didCreateWebSocket const):
    (WebCore::WebSocketChannelInspector::willSendWebSocketHandshakeRequest const):
    (WebCore::WebSocketChannelInspector::didReceiveWebSocketHandshakeResponse const):
    (WebCore::WebSocketChannelInspector::didCloseWebSocket const):
    (WebCore::WebSocketChannelInspector::didReceiveWebSocketFrame const):
    (WebCore::WebSocketChannelInspector::didSendWebSocketFrame const):
    (WebCore::WebSocketChannelInspector::didReceiveWebSocketFrameError const):
    (WebCore::WebSocketChannelInspector::createFrame):
    (WebCore::WebSocketChannelInspector::didCreateWebSocket): Deleted.
    (WebCore::WebSocketChannelInspector::willSendWebSocketHandshakeRequest): Deleted.
    (WebCore::WebSocketChannelInspector::didReceiveWebSocketHandshakeResponse): Deleted.
    (WebCore::WebSocketChannelInspector::didCloseWebSocket): Deleted.
    (WebCore::WebSocketChannelInspector::didReceiveWebSocketFrame): Deleted.
    (WebCore::WebSocketChannelInspector::didSendWebSocketFrame): Deleted.
    (WebCore::WebSocketChannelInspector::didReceiveWebSocketFrameError): Deleted.
    * Modules/websockets/WebSocketChannelInspector.h:
    - Update to keep a WeakRef to the `Document` to reduce the amount of plumbing necessary to call these methods
    from `WebSocket`.
    - Move static utility method `createFrame` here from `WebKit::WebSocketChannel` since it is only used for
    inspector instrumentation.

    * Modules/websockets/WorkerThreadableWebSocketChannel.cpp:
    (WebCore::WorkerThreadableWebSocketChannel::Peer::didReceiveMessageError):
    (WebCore::WorkerThreadableWebSocketChannel::Bridge::connect):
    * Modules/websockets/WorkerThreadableWebSocketChannel.h:
    * Modules/websockets/ThreadableWebSocketChannelClientWrapper.cpp:
    (WebCore::ThreadableWebSocketChannelClientWrapper::didReceiveMessageError):
    * Modules/websockets/ThreadableWebSocketChannelClientWrapper.h:
    * Modules/websockets/WebSocketChannel.cpp:
    (WebCore::WebSocketChannel::fail):
    (WebCore::WebSocketChannel::didFailSocketStream):
    * Modules/websockets/WebSocketChannel.h:
    - Update these classes to pass along a reason, if available, for errors.

    Source/WebKit:

    Move inspector instrumentation for things that should be delayed until the websocket has resumed (in general,
    these are instrumentation points for receiving messages) into WebCore::WebSocket so that they are sent at the
    expected time in the frontend, not "in the future" when script execution is suspended (e.g. while debugging).

    * WebProcess/Network/WebSocketChannel.cpp:
    (WebKit::WebSocketChannel::notifySendFrame):
    (WebKit::WebSocketChannel::connect):
    (WebKit::WebSocketChannel::close):
    (WebKit::WebSocketChannel::fail):
    (WebKit::WebSocketChannel::disconnect):
    (WebKit::WebSocketChannel::didReceiveText):
    (WebKit::WebSocketChannel::didReceiveBinaryData):
    (WebKit::WebSocketChannel::didClose):
    (WebKit::WebSocketChannel::didReceiveMessageError):
    (WebKit::WebSocketChannel::didSendHandshakeRequest):
    (WebKit::WebSocketChannel::didReceiveHandshakeResponse):
    (WebKit::createWebSocketFrameForWebInspector): Deleted.
    * WebProcess/Network/WebSocketChannel.h:

    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@290856 268f45cc-cd09-0410-ab3c-d52691b4dbfc

Modified Paths

Diff

Modified: branches/safari-613-branch/Source/WebCore/ChangeLog (291647 => 291648)


--- branches/safari-613-branch/Source/WebCore/ChangeLog	2022-03-22 17:55:27 UTC (rev 291647)
+++ branches/safari-613-branch/Source/WebCore/ChangeLog	2022-03-22 17:55:34 UTC (rev 291648)
@@ -1,5 +1,195 @@
 2022-03-21  Alan Coon  <alanc...@apple.com>
 
+        Cherry-pick r290856. rdar://problem/89569036
+
+    REGRESSION (r284472): [ Monterey ] http/tests/websocket/tests/hybi/inspector/send-and-recieve-debugger.html is failing
+    https://bugs.webkit.org/show_bug.cgi?id=237280
+    
+    Reviewed by Devin Rousso.
+    
+    Source/WebCore:
+    
+    Covered by existing http/tests/websocket/tests/hybi/inspector/* test cases.
+    
+    On macOS Monterey we use NSURLSession-based WebSockets by default, unlike earlier versions of macOS. The channel
+    for these sockets is implemented in `WebKit::WebSocketChannel`. The non-NSURLSession WebSockets channel (at
+    least on Cocoa platforms) is implemented in `WebCore::WebSocketChannel`.
+    
+    As of r284472 the logic to delay the dispatch of received WebSocket message on platforms using
+    NSURLSession-based WebSockets is handled by `WebCore::WebSocket`, not the `WebKit::WebSocketChannel`.
+    `WebKit::WebSocketChannel` now immediately does the work it needs to, and only the delegated work to `WebSocket`
+    is queued and taken care of when the socket has resumed. This resulted in some of the instrumentation in
+    `WebKit::WebSocketChannel` being able to be called while the socket was suspended leading to events being logged
+    in the frontend "in the future" (e.g. before the paused script would have been able to be aware of them). To
+    correct this the `WebKit::WebSocketChannel` now provides a hook into its helper `WebSocketChannelInspector`
+    object to allow the `WebCore::WebSocket` to notify Web Inspector of events at the same time it is being
+    logically handled by the page.
+    
+    Other `ThreadableWebSocketChannel` implementations will instead provide `nullptr` in place of a pointer to a
+    `WebInspectorChannelInspector`. `WebCore::WebSocketChannel` was not affected by the changes in r284472 as it has
+    a different way to guarantee that the methods containing InspectorInstrumentation were not called while the
+    channel was suspended (and enforced with numerous `ASSERT(!m_suspended)` checks).
+    
+    * Modules/websockets/ThreadableWebSocketChannel.h:
+    (WebCore::ThreadableWebSocketChannel::channelInspector const):
+    
+    * Modules/websockets/WebSocketChannelClient.h:
+    - Add `reason` for error messages so they can be sent to Web Inspector.
+    
+    * Modules/websockets/WebSocket.cpp:
+    (WebCore::WebSocket::didReceiveMessage):
+    (WebCore::WebSocket::didReceiveBinaryData):
+    (WebCore::WebSocket::didReceiveMessageError):
+    (WebCore::WebSocket::didClose):
+    * Modules/websockets/WebSocket.h:
+    - Move inspector instrumentation calls from `WebKit::WebSocketChannel` to here so that they are not called until
+    the socket is resumed.
+    - We also now wrap these instrumentation calls in an unlikely check for frontends to avoid allocating the
+    simulated call frames when Web Inspector isn't even open.
+    
+    * Modules/websockets/WebSocketChannelInspector.cpp:
+    (WebCore::WebSocketChannelInspector::WebSocketChannelInspector):
+    (WebCore::WebSocketChannelInspector::didCreateWebSocket const):
+    (WebCore::WebSocketChannelInspector::willSendWebSocketHandshakeRequest const):
+    (WebCore::WebSocketChannelInspector::didReceiveWebSocketHandshakeResponse const):
+    (WebCore::WebSocketChannelInspector::didCloseWebSocket const):
+    (WebCore::WebSocketChannelInspector::didReceiveWebSocketFrame const):
+    (WebCore::WebSocketChannelInspector::didSendWebSocketFrame const):
+    (WebCore::WebSocketChannelInspector::didReceiveWebSocketFrameError const):
+    (WebCore::WebSocketChannelInspector::createFrame):
+    (WebCore::WebSocketChannelInspector::didCreateWebSocket): Deleted.
+    (WebCore::WebSocketChannelInspector::willSendWebSocketHandshakeRequest): Deleted.
+    (WebCore::WebSocketChannelInspector::didReceiveWebSocketHandshakeResponse): Deleted.
+    (WebCore::WebSocketChannelInspector::didCloseWebSocket): Deleted.
+    (WebCore::WebSocketChannelInspector::didReceiveWebSocketFrame): Deleted.
+    (WebCore::WebSocketChannelInspector::didSendWebSocketFrame): Deleted.
+    (WebCore::WebSocketChannelInspector::didReceiveWebSocketFrameError): Deleted.
+    * Modules/websockets/WebSocketChannelInspector.h:
+    - Update to keep a WeakRef to the `Document` to reduce the amount of plumbing necessary to call these methods
+    from `WebSocket`.
+    - Move static utility method `createFrame` here from `WebKit::WebSocketChannel` since it is only used for
+    inspector instrumentation.
+    
+    * Modules/websockets/WorkerThreadableWebSocketChannel.cpp:
+    (WebCore::WorkerThreadableWebSocketChannel::Peer::didReceiveMessageError):
+    (WebCore::WorkerThreadableWebSocketChannel::Bridge::connect):
+    * Modules/websockets/WorkerThreadableWebSocketChannel.h:
+    * Modules/websockets/ThreadableWebSocketChannelClientWrapper.cpp:
+    (WebCore::ThreadableWebSocketChannelClientWrapper::didReceiveMessageError):
+    * Modules/websockets/ThreadableWebSocketChannelClientWrapper.h:
+    * Modules/websockets/WebSocketChannel.cpp:
+    (WebCore::WebSocketChannel::fail):
+    (WebCore::WebSocketChannel::didFailSocketStream):
+    * Modules/websockets/WebSocketChannel.h:
+    - Update these classes to pass along a reason, if available, for errors.
+    
+    Source/WebKit:
+    
+    Move inspector instrumentation for things that should be delayed until the websocket has resumed (in general,
+    these are instrumentation points for receiving messages) into WebCore::WebSocket so that they are sent at the
+    expected time in the frontend, not "in the future" when script execution is suspended (e.g. while debugging).
+    
+    * WebProcess/Network/WebSocketChannel.cpp:
+    (WebKit::WebSocketChannel::notifySendFrame):
+    (WebKit::WebSocketChannel::connect):
+    (WebKit::WebSocketChannel::close):
+    (WebKit::WebSocketChannel::fail):
+    (WebKit::WebSocketChannel::disconnect):
+    (WebKit::WebSocketChannel::didReceiveText):
+    (WebKit::WebSocketChannel::didReceiveBinaryData):
+    (WebKit::WebSocketChannel::didClose):
+    (WebKit::WebSocketChannel::didReceiveMessageError):
+    (WebKit::WebSocketChannel::didSendHandshakeRequest):
+    (WebKit::WebSocketChannel::didReceiveHandshakeResponse):
+    (WebKit::createWebSocketFrameForWebInspector): Deleted.
+    * WebProcess/Network/WebSocketChannel.h:
+    
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@290856 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2022-03-04  Patrick Angle  <pan...@apple.com>
+
+            REGRESSION (r284472): [ Monterey ] http/tests/websocket/tests/hybi/inspector/send-and-recieve-debugger.html is failing
+            https://bugs.webkit.org/show_bug.cgi?id=237280
+
+            Reviewed by Devin Rousso.
+
+            Covered by existing http/tests/websocket/tests/hybi/inspector/* test cases.
+
+            On macOS Monterey we use NSURLSession-based WebSockets by default, unlike earlier versions of macOS. The channel
+            for these sockets is implemented in `WebKit::WebSocketChannel`. The non-NSURLSession WebSockets channel (at
+            least on Cocoa platforms) is implemented in `WebCore::WebSocketChannel`.
+
+            As of r284472 the logic to delay the dispatch of received WebSocket message on platforms using
+            NSURLSession-based WebSockets is handled by `WebCore::WebSocket`, not the `WebKit::WebSocketChannel`.
+            `WebKit::WebSocketChannel` now immediately does the work it needs to, and only the delegated work to `WebSocket`
+            is queued and taken care of when the socket has resumed. This resulted in some of the instrumentation in
+            `WebKit::WebSocketChannel` being able to be called while the socket was suspended leading to events being logged
+            in the frontend "in the future" (e.g. before the paused script would have been able to be aware of them). To
+            correct this the `WebKit::WebSocketChannel` now provides a hook into its helper `WebSocketChannelInspector`
+            object to allow the `WebCore::WebSocket` to notify Web Inspector of events at the same time it is being
+            logically handled by the page.
+
+            Other `ThreadableWebSocketChannel` implementations will instead provide `nullptr` in place of a pointer to a
+            `WebInspectorChannelInspector`. `WebCore::WebSocketChannel` was not affected by the changes in r284472 as it has
+            a different way to guarantee that the methods containing InspectorInstrumentation were not called while the
+            channel was suspended (and enforced with numerous `ASSERT(!m_suspended)` checks).
+
+            * Modules/websockets/ThreadableWebSocketChannel.h:
+            (WebCore::ThreadableWebSocketChannel::channelInspector const):
+
+            * Modules/websockets/WebSocketChannelClient.h:
+            - Add `reason` for error messages so they can be sent to Web Inspector.
+
+            * Modules/websockets/WebSocket.cpp:
+            (WebCore::WebSocket::didReceiveMessage):
+            (WebCore::WebSocket::didReceiveBinaryData):
+            (WebCore::WebSocket::didReceiveMessageError):
+            (WebCore::WebSocket::didClose):
+            * Modules/websockets/WebSocket.h:
+            - Move inspector instrumentation calls from `WebKit::WebSocketChannel` to here so that they are not called until
+            the socket is resumed.
+            - We also now wrap these instrumentation calls in an unlikely check for frontends to avoid allocating the
+            simulated call frames when Web Inspector isn't even open.
+
+            * Modules/websockets/WebSocketChannelInspector.cpp:
+            (WebCore::WebSocketChannelInspector::WebSocketChannelInspector):
+            (WebCore::WebSocketChannelInspector::didCreateWebSocket const):
+            (WebCore::WebSocketChannelInspector::willSendWebSocketHandshakeRequest const):
+            (WebCore::WebSocketChannelInspector::didReceiveWebSocketHandshakeResponse const):
+            (WebCore::WebSocketChannelInspector::didCloseWebSocket const):
+            (WebCore::WebSocketChannelInspector::didReceiveWebSocketFrame const):
+            (WebCore::WebSocketChannelInspector::didSendWebSocketFrame const):
+            (WebCore::WebSocketChannelInspector::didReceiveWebSocketFrameError const):
+            (WebCore::WebSocketChannelInspector::createFrame):
+            (WebCore::WebSocketChannelInspector::didCreateWebSocket): Deleted.
+            (WebCore::WebSocketChannelInspector::willSendWebSocketHandshakeRequest): Deleted.
+            (WebCore::WebSocketChannelInspector::didReceiveWebSocketHandshakeResponse): Deleted.
+            (WebCore::WebSocketChannelInspector::didCloseWebSocket): Deleted.
+            (WebCore::WebSocketChannelInspector::didReceiveWebSocketFrame): Deleted.
+            (WebCore::WebSocketChannelInspector::didSendWebSocketFrame): Deleted.
+            (WebCore::WebSocketChannelInspector::didReceiveWebSocketFrameError): Deleted.
+            * Modules/websockets/WebSocketChannelInspector.h:
+            - Update to keep a WeakRef to the `Document` to reduce the amount of plumbing necessary to call these methods
+            from `WebSocket`.
+            - Move static utility method `createFrame` here from `WebKit::WebSocketChannel` since it is only used for
+            inspector instrumentation.
+
+            * Modules/websockets/WorkerThreadableWebSocketChannel.cpp:
+            (WebCore::WorkerThreadableWebSocketChannel::Peer::didReceiveMessageError):
+            (WebCore::WorkerThreadableWebSocketChannel::Bridge::connect):
+            * Modules/websockets/WorkerThreadableWebSocketChannel.h:
+            * Modules/websockets/ThreadableWebSocketChannelClientWrapper.cpp:
+            (WebCore::ThreadableWebSocketChannelClientWrapper::didReceiveMessageError):
+            * Modules/websockets/ThreadableWebSocketChannelClientWrapper.h:
+            * Modules/websockets/WebSocketChannel.cpp:
+            (WebCore::WebSocketChannel::fail):
+            (WebCore::WebSocketChannel::didFailSocketStream):
+            * Modules/websockets/WebSocketChannel.h:
+            - Update these classes to pass along a reason, if available, for errors.
+
+2022-03-21  Alan Coon  <alanc...@apple.com>
+
         Cherry-pick r290832. rdar://problem/89758344
 
     Top layers should not be moved

Modified: branches/safari-613-branch/Source/WebCore/Modules/websockets/ThreadableWebSocketChannel.h (291647 => 291648)


--- branches/safari-613-branch/Source/WebCore/Modules/websockets/ThreadableWebSocketChannel.h	2022-03-22 17:55:27 UTC (rev 291647)
+++ branches/safari-613-branch/Source/WebCore/Modules/websockets/ThreadableWebSocketChannel.h	2022-03-22 17:55:34 UTC (rev 291648)
@@ -49,6 +49,7 @@
 class ScriptExecutionContext;
 class SocketProvider;
 class WebSocketChannel;
+class WebSocketChannelInspector;
 class WebSocketChannelClient;
 
 using WebSocketChannelIdentifier = ObjectIdentifier<WebSocketChannel>;
@@ -84,6 +85,7 @@
     virtual void suspend() = 0;
     virtual void resume() = 0;
 
+    virtual const WebSocketChannelInspector* channelInspector() const { return nullptr; };
     virtual WebSocketChannelIdentifier progressIdentifier() const = 0;
     virtual bool hasCreatedHandshake() const = 0;
     virtual bool isConnected() const = 0;

Modified: branches/safari-613-branch/Source/WebCore/Modules/websockets/ThreadableWebSocketChannelClientWrapper.cpp (291647 => 291648)


--- branches/safari-613-branch/Source/WebCore/Modules/websockets/ThreadableWebSocketChannelClientWrapper.cpp	2022-03-22 17:55:27 UTC (rev 291647)
+++ branches/safari-613-branch/Source/WebCore/Modules/websockets/ThreadableWebSocketChannelClientWrapper.cpp	2022-03-22 17:55:34 UTC (rev 291648)
@@ -217,11 +217,11 @@
         processPendingTasks();
 }
 
-void ThreadableWebSocketChannelClientWrapper::didReceiveMessageError()
+void ThreadableWebSocketChannelClientWrapper::didReceiveMessageError(const String& reason)
 {
-    m_pendingTasks.append(makeUnique<ScriptExecutionContext::Task>([this, protectedThis = Ref { *this }] (ScriptExecutionContext&) {
+    m_pendingTasks.append(makeUnique<ScriptExecutionContext::Task>([this, protectedThis = Ref { *this }, reason = reason.isolatedCopy()] (ScriptExecutionContext&) {
         if (m_client)
-            m_client->didReceiveMessageError();
+            m_client->didReceiveMessageError(reason);
     }));
 
     if (!m_suspended)

Modified: branches/safari-613-branch/Source/WebCore/Modules/websockets/ThreadableWebSocketChannelClientWrapper.h (291647 => 291648)


--- branches/safari-613-branch/Source/WebCore/Modules/websockets/ThreadableWebSocketChannelClientWrapper.h	2022-03-22 17:55:27 UTC (rev 291647)
+++ branches/safari-613-branch/Source/WebCore/Modules/websockets/ThreadableWebSocketChannelClientWrapper.h	2022-03-22 17:55:34 UTC (rev 291648)
@@ -79,7 +79,7 @@
     void didUpdateBufferedAmount(unsigned bufferedAmount);
     void didStartClosingHandshake();
     void didClose(unsigned unhandledBufferedAmount, WebSocketChannelClient::ClosingHandshakeCompletionStatus, unsigned short code, const String& reason);
-    void didReceiveMessageError();
+    void didReceiveMessageError(const String& reason);
     void didUpgradeURL();
 
     void suspend();

Modified: branches/safari-613-branch/Source/WebCore/Modules/websockets/WebSocket.cpp (291647 => 291648)


--- branches/safari-613-branch/Source/WebCore/Modules/websockets/WebSocket.cpp	2022-03-22 17:55:27 UTC (rev 291647)
+++ branches/safari-613-branch/Source/WebCore/Modules/websockets/WebSocket.cpp	2022-03-22 17:55:34 UTC (rev 291648)
@@ -43,6 +43,7 @@
 #include "Frame.h"
 #include "FrameLoader.h"
 #include "FrameLoaderClient.h"
+#include "InspectorInstrumentation.h"
 #include "Logging.h"
 #include "MessageEvent.h"
 #include "MixedContentChecker.h"
@@ -565,6 +566,13 @@
     queueTaskKeepingObjectAlive(*this, TaskSource::WebSocket, [this, msg] {
         if (m_state != OPEN)
             return;
+
+        if (UNLIKELY(InspectorInstrumentation::hasFrontends())) {
+            if (auto* inspector = m_channel->channelInspector()) {
+                auto utf8Message = msg.utf8();
+                inspector->didReceiveWebSocketFrame(WebSocketChannelInspector::createFrame(utf8Message.dataAsUInt8Ptr(), utf8Message.length(), WebSocketFrame::OpCode::OpCodeText));
+            }
+        }
         ASSERT(scriptExecutionContext());
         dispatchEvent(MessageEvent::create(msg, SecurityOrigin::create(m_url)->toString()));
     });
@@ -576,6 +584,12 @@
     queueTaskKeepingObjectAlive(*this, TaskSource::WebSocket, [this, binaryData = WTFMove(binaryData)]() mutable {
         if (m_state != OPEN)
             return;
+
+        if (UNLIKELY(InspectorInstrumentation::hasFrontends())) {
+            if (auto* inspector = m_channel->channelInspector())
+                inspector->didReceiveWebSocketFrame(WebSocketChannelInspector::createFrame(binaryData.data(), binaryData.size(), WebSocketFrame::OpCode::OpCodeBinary));
+        }
+
         switch (m_binaryType) {
         case BinaryType::Blob:
             // FIXME: We just received the data from NetworkProcess, and are sending it back. This is inefficient.
@@ -588,14 +602,20 @@
     });
 }
 
-void WebSocket::didReceiveMessageError()
+void WebSocket::didReceiveMessageError(const String& reason)
 {
     LOG(Network, "WebSocket %p didReceiveErrorMessage()", this);
-    queueTaskKeepingObjectAlive(*this, TaskSource::WebSocket, [this] {
+    queueTaskKeepingObjectAlive(*this, TaskSource::WebSocket, [this, reason] {
         if (m_state == CLOSED)
             return;
         m_state = CLOSED;
         ASSERT(scriptExecutionContext());
+
+        if (UNLIKELY(InspectorInstrumentation::hasFrontends())) {
+            if (auto* inspector = m_channel->channelInspector())
+                inspector->didReceiveWebSocketFrameError(reason);
+        }
+
         // FIXME: As per https://html.spec.whatwg.org/multipage/web-sockets.html#feedback-from-the-protocol:concept-websocket-closed, we should synchronously fire a close event.
         dispatchErrorEventIfNeeded();
     });
@@ -626,6 +646,14 @@
         if (!m_channel)
             return;
 
+        if (UNLIKELY(InspectorInstrumentation::hasFrontends())) {
+            if (auto* inspector = m_channel->channelInspector()) {
+                WebSocketFrame closingFrame(WebSocketFrame::OpCodeClose, true, false, false);
+                inspector->didReceiveWebSocketFrame(closingFrame);
+                inspector->didCloseWebSocket();
+            }
+        }
+
         bool wasClean = m_state == CLOSING && !unhandledBufferedAmount && closingHandshakeCompletion == ClosingHandshakeComplete && code != WebSocketChannel::CloseEventCodeAbnormalClosure;
         m_state = CLOSED;
         m_bufferedAmount = unhandledBufferedAmount;

Modified: branches/safari-613-branch/Source/WebCore/Modules/websockets/WebSocket.h (291647 => 291648)


--- branches/safari-613-branch/Source/WebCore/Modules/websockets/WebSocket.h	2022-03-22 17:55:27 UTC (rev 291647)
+++ branches/safari-613-branch/Source/WebCore/Modules/websockets/WebSocket.h	2022-03-22 17:55:34 UTC (rev 291648)
@@ -115,7 +115,7 @@
     void didConnect() final;
     void didReceiveMessage(const String& message) final;
     void didReceiveBinaryData(Vector<uint8_t>&&) final;
-    void didReceiveMessageError() final;
+    void didReceiveMessageError(const String& reason) final;
     void didUpdateBufferedAmount(unsigned bufferedAmount) final;
     void didStartClosingHandshake() final;
     void didClose(unsigned unhandledBufferedAmount, ClosingHandshakeCompletionStatus, unsigned short code, const String& reason) final;

Modified: branches/safari-613-branch/Source/WebCore/Modules/websockets/WebSocketChannel.cpp (291647 => 291648)


--- branches/safari-613-branch/Source/WebCore/Modules/websockets/WebSocketChannel.cpp	2022-03-22 17:55:27 UTC (rev 291647)
+++ branches/safari-613-branch/Source/WebCore/Modules/websockets/WebSocketChannel.cpp	2022-03-22 17:55:34 UTC (rev 291648)
@@ -239,7 +239,7 @@
     m_hasContinuousFrame = false;
     m_continuousFrameData.clear();
     if (m_client)
-        m_client->didReceiveMessageError();
+        m_client->didReceiveMessageError(reason);
 
     if (m_handle && !m_closed)
         m_handle->disconnect(); // Will call didCloseSocketStream() but maybe not synchronously.
@@ -365,14 +365,16 @@
 {
     LOG(Network, "WebSocketChannel %p didFailSocketStream()", this);
     ASSERT(&handle == m_handle || !m_handle);
+
+    String message;
+    if (error.isNull())
+        message = "WebSocket network error"_s;
+    else if (error.localizedDescription().isNull())
+        message = makeString("WebSocket network error: error code ", error.errorCode());
+    else
+        message = "WebSocket network error: " + error.localizedDescription();
+
     if (m_document) {
-        String message;
-        if (error.isNull())
-            message = "WebSocket network error"_s;
-        else if (error.localizedDescription().isNull())
-            message = makeString("WebSocket network error: error code ", error.errorCode());
-        else
-            message = "WebSocket network error: " + error.localizedDescription();
         InspectorInstrumentation::didReceiveWebSocketFrameError(m_document.get(), m_progressIdentifier, message);
         m_document->addConsoleMessage(MessageSource::Network, MessageLevel::Error, message);
         LOG_ERROR("%s", message.utf8().data());
@@ -379,7 +381,7 @@
     }
     m_shouldDiscardReceivedData = true;
     if (m_client)
-        m_client->didReceiveMessageError();
+        m_client->didReceiveMessageError(message);
     handle.disconnect();
 }
 

Modified: branches/safari-613-branch/Source/WebCore/Modules/websockets/WebSocketChannel.h (291647 => 291648)


--- branches/safari-613-branch/Source/WebCore/Modules/websockets/WebSocketChannel.h	2022-03-22 17:55:27 UTC (rev 291647)
+++ branches/safari-613-branch/Source/WebCore/Modules/websockets/WebSocketChannel.h	2022-03-22 17:55:34 UTC (rev 291648)
@@ -35,6 +35,7 @@
 #include "SocketStreamHandleClient.h"
 #include "ThreadableWebSocketChannel.h"
 #include "Timer.h"
+#include "WebSocketChannelInspector.h"
 #include "WebSocketDeflateFramer.h"
 #include "WebSocketFrame.h"
 #include "WebSocketHandshake.h"

Modified: branches/safari-613-branch/Source/WebCore/Modules/websockets/WebSocketChannelClient.h (291647 => 291648)


--- branches/safari-613-branch/Source/WebCore/Modules/websockets/WebSocketChannelClient.h	2022-03-22 17:55:27 UTC (rev 291647)
+++ branches/safari-613-branch/Source/WebCore/Modules/websockets/WebSocketChannelClient.h	2022-03-22 17:55:34 UTC (rev 291648)
@@ -41,7 +41,7 @@
     virtual void didConnect() = 0;
     virtual void didReceiveMessage(const String&) = 0;
     virtual void didReceiveBinaryData(Vector<uint8_t>&&) = 0;
-    virtual void didReceiveMessageError() = 0;
+    virtual void didReceiveMessageError(const String&) = 0;
     virtual void didUpdateBufferedAmount(unsigned bufferedAmount) = 0;
     virtual void didStartClosingHandshake() = 0;
     enum ClosingHandshakeCompletionStatus {

Modified: branches/safari-613-branch/Source/WebCore/Modules/websockets/WebSocketChannelInspector.cpp (291647 => 291648)


--- branches/safari-613-branch/Source/WebCore/Modules/websockets/WebSocketChannelInspector.cpp	2022-03-22 17:55:27 UTC (rev 291647)
+++ branches/safari-613-branch/Source/WebCore/Modules/websockets/WebSocketChannelInspector.cpp	2022-03-22 17:55:34 UTC (rev 291648)
@@ -30,66 +30,70 @@
 #include "InspectorInstrumentation.h"
 #include "Page.h"
 #include "ProgressTracker.h"
+#include "WebSocketFrame.h"
 
 namespace WebCore {
 
-WebSocketChannelInspector::WebSocketChannelInspector(Document&)
-    : m_progressIdentifier(WebSocketChannelIdentifier::generateThreadSafe()) { }
+WebSocketChannelInspector::WebSocketChannelInspector(Document& document)
+    : m_document(document)
+    , m_progressIdentifier(WebSocketChannelIdentifier::generateThreadSafe())
+{
+}
 
-void WebSocketChannelInspector::didCreateWebSocket(Document* document, const URL& url)
+void WebSocketChannelInspector::didCreateWebSocket(const URL& url) const
 {
-    if (!m_progressIdentifier || !document)
+    if (!m_progressIdentifier || !m_document)
         return;
 
-    InspectorInstrumentation::didCreateWebSocket(document, m_progressIdentifier, url);
+    InspectorInstrumentation::didCreateWebSocket(m_document.get(), m_progressIdentifier, url);
 }
 
-void WebSocketChannelInspector::willSendWebSocketHandshakeRequest(Document* document, const ResourceRequest& request)
+void WebSocketChannelInspector::willSendWebSocketHandshakeRequest(const ResourceRequest& request) const
 {
-    if (!m_progressIdentifier || !document)
+    if (!m_progressIdentifier || !m_document)
         return;
 
-    InspectorInstrumentation::willSendWebSocketHandshakeRequest(document, m_progressIdentifier, request);
+    InspectorInstrumentation::willSendWebSocketHandshakeRequest(m_document.get(), m_progressIdentifier, request);
 }
 
-void WebSocketChannelInspector::didReceiveWebSocketHandshakeResponse(Document* document, const ResourceResponse& response)
+void WebSocketChannelInspector::didReceiveWebSocketHandshakeResponse(const ResourceResponse& response) const
 {
-    if (!m_progressIdentifier || !document)
+    if (!m_progressIdentifier || !m_document)
         return;
 
-    InspectorInstrumentation::didReceiveWebSocketHandshakeResponse(document, m_progressIdentifier, response);
+    InspectorInstrumentation::didReceiveWebSocketHandshakeResponse(m_document.get(), m_progressIdentifier, response);
 }
 
-void WebSocketChannelInspector::didCloseWebSocket(Document* document)
+void WebSocketChannelInspector::didCloseWebSocket() const
 {
-    if (!m_progressIdentifier || !document)
+    if (!m_progressIdentifier || !m_document)
         return;
 
-    InspectorInstrumentation::didCloseWebSocket(document, m_progressIdentifier);
+    InspectorInstrumentation::didCloseWebSocket(m_document.get(), m_progressIdentifier);
 }
 
-void WebSocketChannelInspector::didReceiveWebSocketFrame(Document* document, const WebSocketFrame& frame)
+void WebSocketChannelInspector::didReceiveWebSocketFrame(const WebSocketFrame& frame) const
 {
-    if (!m_progressIdentifier || !document)
+    if (!m_progressIdentifier || !m_document)
         return;
 
-    InspectorInstrumentation::didReceiveWebSocketFrame(document, m_progressIdentifier, frame);
+    InspectorInstrumentation::didReceiveWebSocketFrame(m_document.get(), m_progressIdentifier, frame);
 }
 
-void WebSocketChannelInspector::didSendWebSocketFrame(Document* document, const WebSocketFrame& frame)
+void WebSocketChannelInspector::didSendWebSocketFrame(const WebSocketFrame& frame) const
 {
-    if (!m_progressIdentifier || !document)
+    if (!m_progressIdentifier || !m_document)
         return;
 
-    InspectorInstrumentation::didSendWebSocketFrame(document, m_progressIdentifier, frame);
+    InspectorInstrumentation::didSendWebSocketFrame(m_document.get(), m_progressIdentifier, frame);
 }
 
-void WebSocketChannelInspector::didReceiveWebSocketFrameError(Document* document, const String& errorMessage)
+void WebSocketChannelInspector::didReceiveWebSocketFrameError(const String& errorMessage) const
 {
-    if (!m_progressIdentifier || !document)
+    if (!m_progressIdentifier || !m_document)
         return;
 
-    InspectorInstrumentation::didReceiveWebSocketFrameError(document, m_progressIdentifier, errorMessage);
+    InspectorInstrumentation::didReceiveWebSocketFrameError(m_document.get(), m_progressIdentifier, errorMessage);
 }
 
 WebSocketChannelIdentifier WebSocketChannelInspector::progressIdentifier() const
@@ -97,4 +101,22 @@
     return m_progressIdentifier;
 }
 
+WebSocketFrame WebSocketChannelInspector::createFrame(const uint8_t* data, size_t length, WebSocketFrame::OpCode opCode)
+{
+    // This is an approximation since frames can be merged on a single message.
+    WebSocketFrame frame;
+    frame.opCode = opCode;
+    frame.masked = false;
+    frame.payload = data;
+    frame.payloadLength = length;
+
+    // WebInspector does not use them.
+    frame.final = false;
+    frame.compress = false;
+    frame.reserved2 = false;
+    frame.reserved3 = false;
+
+    return frame;
+}
+
 } // namespace WebCore

Modified: branches/safari-613-branch/Source/WebCore/Modules/websockets/WebSocketChannelInspector.h (291647 => 291648)


--- branches/safari-613-branch/Source/WebCore/Modules/websockets/WebSocketChannelInspector.h	2022-03-22 17:55:27 UTC (rev 291647)
+++ branches/safari-613-branch/Source/WebCore/Modules/websockets/WebSocketChannelInspector.h	2022-03-22 17:55:34 UTC (rev 291648)
@@ -25,6 +25,7 @@
 
 #pragma once
 
+#include "WebSocketFrame.h"
 #include <wtf/Forward.h>
 #include <wtf/ObjectIdentifier.h>
 
@@ -35,7 +36,6 @@
 class ResourceResponse;
 class WebSocketChannel;
 class WebSocketChannelInspector;
-struct WebSocketFrame;
 
 using WebSocketChannelIdentifier = ObjectIdentifier<WebSocketChannel>;
 
@@ -43,17 +43,20 @@
 public:
     explicit WebSocketChannelInspector(Document&);
 
-    void didCreateWebSocket(Document*, const URL&);
-    void willSendWebSocketHandshakeRequest(Document*, const ResourceRequest&);
-    void didReceiveWebSocketHandshakeResponse(Document*, const ResourceResponse&);
-    void didCloseWebSocket(Document*);
-    void didReceiveWebSocketFrame(Document*, const WebSocketFrame&);
-    void didSendWebSocketFrame(Document*, const WebSocketFrame&);
-    void didReceiveWebSocketFrameError(Document*, const String& errorMessage);
+    void didCreateWebSocket(const URL&) const;
+    void willSendWebSocketHandshakeRequest(const ResourceRequest&) const;
+    void didReceiveWebSocketHandshakeResponse(const ResourceResponse&) const;
+    void didCloseWebSocket() const;
+    void didReceiveWebSocketFrame(const WebSocketFrame&) const;
+    void didSendWebSocketFrame(const WebSocketFrame&) const;
+    void didReceiveWebSocketFrameError(const String& errorMessage) const;
     
     WebSocketChannelIdentifier progressIdentifier() const;
 
+    static WebSocketFrame createFrame(const uint8_t* data, size_t length, WebSocketFrame::OpCode);
+
 private:
+    WeakPtr<Document> m_document;
     WebSocketChannelIdentifier m_progressIdentifier;
 };
 

Modified: branches/safari-613-branch/Source/WebCore/Modules/websockets/WorkerThreadableWebSocketChannel.cpp (291647 => 291648)


--- branches/safari-613-branch/Source/WebCore/Modules/websockets/WorkerThreadableWebSocketChannel.cpp	2022-03-22 17:55:27 UTC (rev 291647)
+++ branches/safari-613-branch/Source/WebCore/Modules/websockets/WorkerThreadableWebSocketChannel.cpp	2022-03-22 17:55:34 UTC (rev 291648)
@@ -323,13 +323,13 @@
     }, m_taskMode);
 }
 
-void WorkerThreadableWebSocketChannel::Peer::didReceiveMessageError()
+void WorkerThreadableWebSocketChannel::Peer::didReceiveMessageError(const String& reason)
 {
     ASSERT(isMainThread());
 
-    m_loaderProxy.postTaskForModeToWorkerOrWorkletGlobalScope([workerClientWrapper = m_workerClientWrapper](ScriptExecutionContext& context) mutable {
+    m_loaderProxy.postTaskForModeToWorkerOrWorkletGlobalScope([workerClientWrapper = m_workerClientWrapper, reason = reason.isolatedCopy()](ScriptExecutionContext& context) mutable {
         ASSERT_UNUSED(context, context.isWorkerGlobalScope() || context.isWorkletGlobalScope());
-        workerClientWrapper->didReceiveMessageError();
+        workerClientWrapper->didReceiveMessageError(reason);
     }, m_taskMode);
 }
 
@@ -420,7 +420,7 @@
         }
 
         if (peer->connect(url, protocol) == ThreadableWebSocketChannel::ConnectStatus::KO)
-            peer->didReceiveMessageError();
+            peer->didReceiveMessageError(nullString());
     });
 }
 

Modified: branches/safari-613-branch/Source/WebCore/Modules/websockets/WorkerThreadableWebSocketChannel.h (291647 => 291648)


--- branches/safari-613-branch/Source/WebCore/Modules/websockets/WorkerThreadableWebSocketChannel.h	2022-03-22 17:55:27 UTC (rev 291647)
+++ branches/safari-613-branch/Source/WebCore/Modules/websockets/WorkerThreadableWebSocketChannel.h	2022-03-22 17:55:34 UTC (rev 291648)
@@ -94,7 +94,7 @@
         void didUpdateBufferedAmount(unsigned bufferedAmount) final;
         void didStartClosingHandshake() final;
         void didClose(unsigned unhandledBufferedAmount, ClosingHandshakeCompletionStatus, unsigned short code, const String& reason) final;
-        void didReceiveMessageError() final;
+        void didReceiveMessageError(const String& reason) final;
         void didUpgradeURL() final;
 
     private:

Modified: branches/safari-613-branch/Source/WebKit/ChangeLog (291647 => 291648)


--- branches/safari-613-branch/Source/WebKit/ChangeLog	2022-03-22 17:55:27 UTC (rev 291647)
+++ branches/safari-613-branch/Source/WebKit/ChangeLog	2022-03-22 17:55:34 UTC (rev 291648)
@@ -1,5 +1,140 @@
 2022-03-21  Alan Coon  <alanc...@apple.com>
 
+        Cherry-pick r290856. rdar://problem/89569036
+
+    REGRESSION (r284472): [ Monterey ] http/tests/websocket/tests/hybi/inspector/send-and-recieve-debugger.html is failing
+    https://bugs.webkit.org/show_bug.cgi?id=237280
+    
+    Reviewed by Devin Rousso.
+    
+    Source/WebCore:
+    
+    Covered by existing http/tests/websocket/tests/hybi/inspector/* test cases.
+    
+    On macOS Monterey we use NSURLSession-based WebSockets by default, unlike earlier versions of macOS. The channel
+    for these sockets is implemented in `WebKit::WebSocketChannel`. The non-NSURLSession WebSockets channel (at
+    least on Cocoa platforms) is implemented in `WebCore::WebSocketChannel`.
+    
+    As of r284472 the logic to delay the dispatch of received WebSocket message on platforms using
+    NSURLSession-based WebSockets is handled by `WebCore::WebSocket`, not the `WebKit::WebSocketChannel`.
+    `WebKit::WebSocketChannel` now immediately does the work it needs to, and only the delegated work to `WebSocket`
+    is queued and taken care of when the socket has resumed. This resulted in some of the instrumentation in
+    `WebKit::WebSocketChannel` being able to be called while the socket was suspended leading to events being logged
+    in the frontend "in the future" (e.g. before the paused script would have been able to be aware of them). To
+    correct this the `WebKit::WebSocketChannel` now provides a hook into its helper `WebSocketChannelInspector`
+    object to allow the `WebCore::WebSocket` to notify Web Inspector of events at the same time it is being
+    logically handled by the page.
+    
+    Other `ThreadableWebSocketChannel` implementations will instead provide `nullptr` in place of a pointer to a
+    `WebInspectorChannelInspector`. `WebCore::WebSocketChannel` was not affected by the changes in r284472 as it has
+    a different way to guarantee that the methods containing InspectorInstrumentation were not called while the
+    channel was suspended (and enforced with numerous `ASSERT(!m_suspended)` checks).
+    
+    * Modules/websockets/ThreadableWebSocketChannel.h:
+    (WebCore::ThreadableWebSocketChannel::channelInspector const):
+    
+    * Modules/websockets/WebSocketChannelClient.h:
+    - Add `reason` for error messages so they can be sent to Web Inspector.
+    
+    * Modules/websockets/WebSocket.cpp:
+    (WebCore::WebSocket::didReceiveMessage):
+    (WebCore::WebSocket::didReceiveBinaryData):
+    (WebCore::WebSocket::didReceiveMessageError):
+    (WebCore::WebSocket::didClose):
+    * Modules/websockets/WebSocket.h:
+    - Move inspector instrumentation calls from `WebKit::WebSocketChannel` to here so that they are not called until
+    the socket is resumed.
+    - We also now wrap these instrumentation calls in an unlikely check for frontends to avoid allocating the
+    simulated call frames when Web Inspector isn't even open.
+    
+    * Modules/websockets/WebSocketChannelInspector.cpp:
+    (WebCore::WebSocketChannelInspector::WebSocketChannelInspector):
+    (WebCore::WebSocketChannelInspector::didCreateWebSocket const):
+    (WebCore::WebSocketChannelInspector::willSendWebSocketHandshakeRequest const):
+    (WebCore::WebSocketChannelInspector::didReceiveWebSocketHandshakeResponse const):
+    (WebCore::WebSocketChannelInspector::didCloseWebSocket const):
+    (WebCore::WebSocketChannelInspector::didReceiveWebSocketFrame const):
+    (WebCore::WebSocketChannelInspector::didSendWebSocketFrame const):
+    (WebCore::WebSocketChannelInspector::didReceiveWebSocketFrameError const):
+    (WebCore::WebSocketChannelInspector::createFrame):
+    (WebCore::WebSocketChannelInspector::didCreateWebSocket): Deleted.
+    (WebCore::WebSocketChannelInspector::willSendWebSocketHandshakeRequest): Deleted.
+    (WebCore::WebSocketChannelInspector::didReceiveWebSocketHandshakeResponse): Deleted.
+    (WebCore::WebSocketChannelInspector::didCloseWebSocket): Deleted.
+    (WebCore::WebSocketChannelInspector::didReceiveWebSocketFrame): Deleted.
+    (WebCore::WebSocketChannelInspector::didSendWebSocketFrame): Deleted.
+    (WebCore::WebSocketChannelInspector::didReceiveWebSocketFrameError): Deleted.
+    * Modules/websockets/WebSocketChannelInspector.h:
+    - Update to keep a WeakRef to the `Document` to reduce the amount of plumbing necessary to call these methods
+    from `WebSocket`.
+    - Move static utility method `createFrame` here from `WebKit::WebSocketChannel` since it is only used for
+    inspector instrumentation.
+    
+    * Modules/websockets/WorkerThreadableWebSocketChannel.cpp:
+    (WebCore::WorkerThreadableWebSocketChannel::Peer::didReceiveMessageError):
+    (WebCore::WorkerThreadableWebSocketChannel::Bridge::connect):
+    * Modules/websockets/WorkerThreadableWebSocketChannel.h:
+    * Modules/websockets/ThreadableWebSocketChannelClientWrapper.cpp:
+    (WebCore::ThreadableWebSocketChannelClientWrapper::didReceiveMessageError):
+    * Modules/websockets/ThreadableWebSocketChannelClientWrapper.h:
+    * Modules/websockets/WebSocketChannel.cpp:
+    (WebCore::WebSocketChannel::fail):
+    (WebCore::WebSocketChannel::didFailSocketStream):
+    * Modules/websockets/WebSocketChannel.h:
+    - Update these classes to pass along a reason, if available, for errors.
+    
+    Source/WebKit:
+    
+    Move inspector instrumentation for things that should be delayed until the websocket has resumed (in general,
+    these are instrumentation points for receiving messages) into WebCore::WebSocket so that they are sent at the
+    expected time in the frontend, not "in the future" when script execution is suspended (e.g. while debugging).
+    
+    * WebProcess/Network/WebSocketChannel.cpp:
+    (WebKit::WebSocketChannel::notifySendFrame):
+    (WebKit::WebSocketChannel::connect):
+    (WebKit::WebSocketChannel::close):
+    (WebKit::WebSocketChannel::fail):
+    (WebKit::WebSocketChannel::disconnect):
+    (WebKit::WebSocketChannel::didReceiveText):
+    (WebKit::WebSocketChannel::didReceiveBinaryData):
+    (WebKit::WebSocketChannel::didClose):
+    (WebKit::WebSocketChannel::didReceiveMessageError):
+    (WebKit::WebSocketChannel::didSendHandshakeRequest):
+    (WebKit::WebSocketChannel::didReceiveHandshakeResponse):
+    (WebKit::createWebSocketFrameForWebInspector): Deleted.
+    * WebProcess/Network/WebSocketChannel.h:
+    
+    
+    git-svn-id: https://svn.webkit.org/repository/webkit/trunk@290856 268f45cc-cd09-0410-ab3c-d52691b4dbfc
+
+    2022-03-04  Patrick Angle  <pan...@apple.com>
+
+            REGRESSION (r284472): [ Monterey ] http/tests/websocket/tests/hybi/inspector/send-and-recieve-debugger.html is failing
+            https://bugs.webkit.org/show_bug.cgi?id=237280
+
+            Reviewed by Devin Rousso.
+
+            Move inspector instrumentation for things that should be delayed until the websocket has resumed (in general,
+            these are instrumentation points for receiving messages) into WebCore::WebSocket so that they are sent at the
+            expected time in the frontend, not "in the future" when script execution is suspended (e.g. while debugging).
+
+            * WebProcess/Network/WebSocketChannel.cpp:
+            (WebKit::WebSocketChannel::notifySendFrame):
+            (WebKit::WebSocketChannel::connect):
+            (WebKit::WebSocketChannel::close):
+            (WebKit::WebSocketChannel::fail):
+            (WebKit::WebSocketChannel::disconnect):
+            (WebKit::WebSocketChannel::didReceiveText):
+            (WebKit::WebSocketChannel::didReceiveBinaryData):
+            (WebKit::WebSocketChannel::didClose):
+            (WebKit::WebSocketChannel::didReceiveMessageError):
+            (WebKit::WebSocketChannel::didSendHandshakeRequest):
+            (WebKit::WebSocketChannel::didReceiveHandshakeResponse):
+            (WebKit::createWebSocketFrameForWebInspector): Deleted.
+            * WebProcess/Network/WebSocketChannel.h:
+
+2022-03-21  Alan Coon  <alanc...@apple.com>
+
         Cherry-pick r290855. rdar://problem/82814846
 
     Web Inspector: [Cocoa] Continually opening and closing Web Inspector sometimes crashes

Modified: branches/safari-613-branch/Source/WebKit/WebProcess/Network/WebSocketChannel.cpp (291647 => 291648)


--- branches/safari-613-branch/Source/WebKit/WebProcess/Network/WebSocketChannel.cpp	2022-03-22 17:55:27 UTC (rev 291647)
+++ branches/safari-613-branch/Source/WebKit/WebProcess/Network/WebSocketChannel.cpp	2022-03-22 17:55:34 UTC (rev 291648)
@@ -51,7 +51,7 @@
 void WebSocketChannel::notifySendFrame(WebSocketFrame::OpCode opCode, const uint8_t* data, size_t length)
 {
     WebSocketFrame frame(opCode, true, false, true, data, length);
-    m_inspector.didSendWebSocketFrame(m_document.get(), frame);
+    m_inspector.didSendWebSocketFrame(frame);
 }
 
 NetworkSendQueue WebSocketChannel::createMessageQueue(Document& document, WebSocketChannel& channel)
@@ -116,7 +116,7 @@
     if (request->url() != url && m_client)
         m_client->didUpgradeURL();
 
-    m_inspector.didCreateWebSocket(m_document.get(), url);
+    m_inspector.didCreateWebSocket(url);
     m_url = request->url();
     MessageSender::send(Messages::NetworkConnectionToWebProcess::CreateSocketChannel { *request, protocol, m_identifier, m_webPageProxyID, m_document->clientOrigin() });
     return ConnectStatus::OK;
@@ -208,7 +208,7 @@
     ASSERT(code >= 0 || code == WebCore::WebSocketChannel::CloseEventCodeNotSpecified);
 
     WebSocketFrame closingFrame(WebSocketFrame::OpCodeClose, true, false, true);
-    m_inspector.didSendWebSocketFrame(m_document.get(), closingFrame);
+    m_inspector.didSendWebSocketFrame(closingFrame);
 
     MessageSender::send(Messages::NetworkSocketChannel::Close { code, reason });
 }
@@ -220,7 +220,7 @@
 
     logErrorMessage(reason);
     if (m_client)
-        m_client->didReceiveMessageError();
+        m_client->didReceiveMessageError(reason);
 
     if (m_isClosing)
         return;
@@ -235,7 +235,7 @@
     m_document = nullptr;
     m_messageQueue.clear();
 
-    m_inspector.didCloseWebSocket(m_document.get());
+    m_inspector.didCloseWebSocket();
 
     MessageSender::send(Messages::NetworkSocketChannel::Close { WebCore::WebSocketChannel::CloseEventCodeGoingAway, { } });
 }
@@ -253,24 +253,6 @@
     m_client->didConnect();
 }
 
-static inline WebSocketFrame createWebSocketFrameForWebInspector(const uint8_t* data, size_t length, WebSocketFrame::OpCode opCode)
-{
-    // This is an approximation since frames can be merged on a single message.
-    WebSocketFrame frame;
-    frame.opCode = opCode;
-    frame.masked = false;
-    frame.payload = data;
-    frame.payloadLength = length;
-
-    // WebInspector does not use them.
-    frame.final = false;
-    frame.compress = false;
-    frame.reserved2 = false;
-    frame.reserved3 = false;
-
-    return frame;
-}
-
 void WebSocketChannel::didReceiveText(String&& message)
 {
     if (m_isClosing)
@@ -279,9 +261,6 @@
     if (!m_client)
         return;
 
-    auto utf8Message = message.utf8();
-    m_inspector.didReceiveWebSocketFrame(m_document.get(), createWebSocketFrameForWebInspector(utf8Message.dataAsUInt8Ptr(), utf8Message.length(), WebSocketFrame::OpCode::OpCodeText));
-
     m_client->didReceiveMessage(message);
 }
 
@@ -293,8 +272,6 @@
     if (!m_client)
         return;
 
-    m_inspector.didReceiveWebSocketFrame(m_document.get(), createWebSocketFrameForWebInspector(data.data(), data.size(), WebSocketFrame::OpCode::OpCodeBinary));
-
     m_client->didReceiveBinaryData({ data });
 }
 
@@ -303,10 +280,6 @@
     if (!m_client)
         return;
 
-    WebSocketFrame closingFrame(WebSocketFrame::OpCodeClose, true, false, false);
-    m_inspector.didReceiveWebSocketFrame(m_document.get(), closingFrame);
-    m_inspector.didCloseWebSocket(m_document.get());
-
     // An attempt to send closing handshake may fail, which will get the channel closed and dereferenced.
     Ref protectedThis { *this };
 
@@ -336,7 +309,7 @@
         return;
 
     logErrorMessage(errorMessage);
-    m_client->didReceiveMessageError();
+    m_client->didReceiveMessageError(errorMessage);
 }
 
 void WebSocketChannel::networkProcessCrashed()
@@ -354,13 +327,13 @@
 
 void WebSocketChannel::didSendHandshakeRequest(ResourceRequest&& request)
 {
-    m_inspector.willSendWebSocketHandshakeRequest(m_document.get(), request);
+    m_inspector.willSendWebSocketHandshakeRequest(request);
     m_handshakeRequest = WTFMove(request);
 }
 
 void WebSocketChannel::didReceiveHandshakeResponse(ResourceResponse&& response)
 {
-    m_inspector.didReceiveWebSocketHandshakeResponse(m_document.get(), response);
+    m_inspector.didReceiveWebSocketHandshakeResponse(response);
     m_handshakeResponse = WTFMove(response);
 }
 

Modified: branches/safari-613-branch/Source/WebKit/WebProcess/Network/WebSocketChannel.h (291647 => 291648)


--- branches/safari-613-branch/Source/WebKit/WebProcess/Network/WebSocketChannel.h	2022-03-22 17:55:27 UTC (rev 291647)
+++ branches/safari-613-branch/Source/WebKit/WebProcess/Network/WebSocketChannel.h	2022-03-22 17:55:34 UTC (rev 291648)
@@ -97,6 +97,7 @@
     void decreaseBufferedAmount(size_t);
     template<typename T> void sendMessage(T&&, size_t byteLength);
 
+    const WebCore::WebSocketChannelInspector* channelInspector() const final { return &m_inspector; }
     WebCore::WebSocketChannelIdentifier progressIdentifier() const final { return m_inspector.progressIdentifier(); }
     bool hasCreatedHandshake() const final { return !m_url.isNull(); }
     bool isConnected() const final { return !m_handshakeResponse.isNull(); }
_______________________________________________
webkit-changes mailing list
webkit-changes@lists.webkit.org
https://lists.webkit.org/mailman/listinfo/webkit-changes

Reply via email to