Diff
Modified: trunk/LayoutTests/ChangeLog (217720 => 217721)
--- trunk/LayoutTests/ChangeLog 2017-06-02 17:01:36 UTC (rev 217720)
+++ trunk/LayoutTests/ChangeLog 2017-06-02 17:54:47 UTC (rev 217721)
@@ -1,3 +1,18 @@
+2017-06-02 Devin Rousso <drou...@apple.com>
+
+ Web Inspector: Should see active Web Sockets when opening Web Inspector
+ https://bugs.webkit.org/show_bug.cgi?id=172312
+
+ Reviewed by Joseph Pecoraro.
+
+ Test that WebSockets created before the inspector loads are also tracked.
+
+ * http/tests/websocket/tests/hybi/inspector/before-load-expected.txt: Added.
+ * http/tests/websocket/tests/hybi/inspector/before-load.html: Added.
+ * http/tests/websocket/tests/hybi/inspector/before-load_wsh.py: Added.
+ (web_socket_do_extra_handshake):
+ (web_socket_transfer_data):
+
2017-06-02 Matt Lewis <jlew...@apple.com>
Marked fast/images/slower-decoding-than-animation-image.html as flaky.
Added: trunk/LayoutTests/http/tests/websocket/tests/hybi/inspector/before-load-expected.txt (0 => 217721)
--- trunk/LayoutTests/http/tests/websocket/tests/hybi/inspector/before-load-expected.txt (rev 0)
+++ trunk/LayoutTests/http/tests/websocket/tests/hybi/inspector/before-load-expected.txt 2017-06-02 17:54:47 UTC (rev 217721)
@@ -0,0 +1,12 @@
+Tests that WebSockets created before the inspector loads are also tracked.
+
+
+== Running test suite: WebSocket.BeforeLoad
+-- Running test case: WebSocket.BeforeLoad
+PASS: Should have 1 WebSocketResource
+PASS: Resource should be a WebSocket.
+PASS: Resource URL should be "ws://127.0.0.1:8880/websocket/tests/hybi/inspector/before-load".
+PASS: Resource should have request headers.
+PASS: Resource should have response headers.
+Resource readyState should be Symbol(open).
+
Added: trunk/LayoutTests/http/tests/websocket/tests/hybi/inspector/before-load.html (0 => 217721)
--- trunk/LayoutTests/http/tests/websocket/tests/hybi/inspector/before-load.html (rev 0)
+++ trunk/LayoutTests/http/tests/websocket/tests/hybi/inspector/before-load.html 2017-06-02 17:54:47 UTC (rev 217721)
@@ -0,0 +1,74 @@
+<!doctype html>
+<html>
+<head>
+<script src=""
+<script>
+function load()
+{
+ testRunner.waitUntilDone();
+
+ const url = ""
+ let webSocket = new WebSocket(url);
+ webSocket.addEventListener("open", (event) => {
+ // Only run the tests once the websocket has connected.
+ runTest();
+ });
+}
+
+function test()
+{
+ let suite = InspectorTest.createAsyncSuite("WebSocket.BeforeLoad");
+
+ function logReadyState(readyState) {
+ let readyStateString = "";
+
+ switch (readyState) {
+ case WebInspector.WebSocketResource.ReadyState.Closed:
+ readyStateString = "closed";
+ break;
+
+ case WebInspector.WebSocketResource.ReadyState.Connecting:
+ readyStateString = "connecting";
+ break;
+
+ case WebInspector.WebSocketResource.ReadyState.Open:
+ readyStateString = "open";
+ break;
+
+ }
+
+ InspectorTest.log(`Resource has readyState "${readyStateString}"`);
+ }
+
+ suite.addTestCase({
+ name: "WebSocket.BeforeLoad",
+ description: "Test that the existing websocket is sent to the frontend when it is first opened.",
+ test(resolve, reject) {
+ const url = ""
+ let webSocketResources = WebInspector.frameResourceManager.mainFrame.resourceCollectionForType(WebInspector.Resource.Type.WebSocket);
+ InspectorTest.expectEqual(webSocketResources.items.size, 1, "Should have 1 WebSocketResource");
+
+ let webSocketResource = webSocketResources.toArray()[0];
+ if (!webSocketResource) {
+ reject("Missing WebSocket resource.");
+ return;
+ }
+
+ InspectorTest.expectThat(webSocketResource instanceof WebInspector.WebSocketResource, "Resource should be a WebSocket.");
+ InspectorTest.expectEqual(webSocketResource.url, url, `Resource URL should be "${url}".`);
+ InspectorTest.expectThat(!isEmptyObject(webSocketResource.requestHeaders), "Resource should have request headers.");
+ InspectorTest.expectThat(!isEmptyObject(webSocketResource.responseHeaders), "Resource should have response headers.");
+ InspectorTest.log(`Resource readyState should be ${String(webSocketResource.readyState)}.`);
+
+ resolve();
+ }
+ });
+
+ suite.runTestCasesAndFinish();
+}
+</script>
+</head>
+<body _onload_="load()">
+<p>Tests that WebSockets created before the inspector loads are also tracked.</p>
+</body>
+</html>
Added: trunk/LayoutTests/http/tests/websocket/tests/hybi/inspector/before-load_wsh.py (0 => 217721)
--- trunk/LayoutTests/http/tests/websocket/tests/hybi/inspector/before-load_wsh.py (rev 0)
+++ trunk/LayoutTests/http/tests/websocket/tests/hybi/inspector/before-load_wsh.py 2017-06-02 17:54:47 UTC (rev 217721)
@@ -0,0 +1,11 @@
+from mod_pywebsocket import msgutil
+
+
+def web_socket_do_extra_handshake(request):
+ pass # Always accept.
+
+
+def web_socket_transfer_data(request):
+ # Echo message back
+ message = msgutil.receive_message(request)
+ msgutil.send_message(request, message)
Modified: trunk/Source/WebCore/ChangeLog (217720 => 217721)
--- trunk/Source/WebCore/ChangeLog 2017-06-02 17:01:36 UTC (rev 217720)
+++ trunk/Source/WebCore/ChangeLog 2017-06-02 17:54:47 UTC (rev 217721)
@@ -1,3 +1,38 @@
+2017-06-02 Devin Rousso <drou...@apple.com>
+
+ Web Inspector: Should see active Web Sockets when opening Web Inspector
+ https://bugs.webkit.org/show_bug.cgi?id=172312
+
+ Reviewed by Joseph Pecoraro.
+
+ Test: http/tests/websocket/tests/hybi/inspector/before-load.html
+
+ * Modules/websockets/WebSocket.h:
+ * Modules/websockets/WebSocket.cpp:
+ (WebCore::WebSocket::WebSocket):
+ (WebCore::WebSocket::~WebSocket):
+ (WebCore::WebSocket::allActiveWebSockets):
+ (WebCore::WebSocket::allActiveWebSocketsMutex):
+ (WebCore::WebSocket::channel):
+ (WebCore::WebSocket::eventTargetInterface):
+ Add a static set of all WebSocket objects and provide getters to access web socket metadata.
+
+ * Modules/websockets/ThreadableWebSocketChannel.h:
+ (WebCore::ThreadableWebSocketChannel::isWebSocketChannel):
+ * Modules/websockets/WebSocketChannel.h:
+ * Modules/websockets/WebSocketChannel.cpp:
+ (WebCore::WebSocketChannel::isWebSocketChannel):
+ (WebCore::WebSocketChannel::identifier):
+ (WebCore::WebSocketChannel::clientHandshakeRequest):
+ (WebCore::WebSocketChannel::serverHandshakeResponse):
+ (WebCore::WebSocketChannel::handshakeMode):
+ (WebCore::WebSocketChannel::isType):
+ Provide getters to access web socket metadata.
+
+ * inspector/InspectorNetworkAgent.cpp:
+ (WebCore::InspectorNetworkAgent::enable):
+ Loops over the static set of all WebSocket objects and sends events for each to the frontend.
+
2017-06-02 Chris Dumez <cdu...@apple.com>
Unreviewed, fix linking errors on iOS after r217712.
Modified: trunk/Source/WebCore/Modules/websockets/ThreadableWebSocketChannel.h (217720 => 217721)
--- trunk/Source/WebCore/Modules/websockets/ThreadableWebSocketChannel.h 2017-06-02 17:01:36 UTC (rev 217720)
+++ trunk/Source/WebCore/Modules/websockets/ThreadableWebSocketChannel.h 2017-06-02 17:54:47 UTC (rev 217721)
@@ -53,6 +53,8 @@
static Ref<ThreadableWebSocketChannel> create(ScriptExecutionContext&, WebSocketChannelClient&, SocketProvider&);
ThreadableWebSocketChannel() { }
+ virtual bool isWebSocketChannel() const { return false; }
+
enum SendResult {
SendSuccess,
SendFail
Modified: trunk/Source/WebCore/Modules/websockets/WebSocket.cpp (217720 => 217721)
--- trunk/Source/WebCore/Modules/websockets/WebSocket.cpp 2017-06-02 17:01:36 UTC (rev 217720)
+++ trunk/Source/WebCore/Modules/websockets/WebSocket.cpp 2017-06-02 17:54:47 UTC (rev 217721)
@@ -58,6 +58,7 @@
#include <runtime/ArrayBuffer.h>
#include <runtime/ArrayBufferView.h>
#include <wtf/HashSet.h>
+#include <wtf/NeverDestroyed.h>
#include <wtf/RunLoop.h>
#include <wtf/StdLibExtras.h>
#include <wtf/text/CString.h>
@@ -151,10 +152,19 @@
, m_extensions(emptyString())
, m_resumeTimer(*this, &WebSocket::resumeTimerFired)
{
+ LockHolder lock(allActiveWebSocketsMutex());
+
+ allActiveWebSockets(lock).add(this);
}
WebSocket::~WebSocket()
{
+ {
+ LockHolder lock(allActiveWebSocketsMutex());
+
+ allActiveWebSockets(lock).remove(this);
+ }
+
if (m_channel)
m_channel->disconnect();
}
@@ -184,6 +194,18 @@
return create(context, url, Vector<String> { 1, protocol });
}
+HashSet<WebSocket*>& WebSocket::allActiveWebSockets(const LockHolder&)
+{
+ static NeverDestroyed<HashSet<WebSocket*>> activeWebSockets;
+ return activeWebSockets;
+}
+
+StaticLock& WebSocket::allActiveWebSocketsMutex()
+{
+ static StaticLock mutex;
+ return mutex;
+}
+
ExceptionOr<void> WebSocket::connect(const String& url)
{
return connect(url, Vector<String> { });
@@ -407,6 +429,11 @@
return { };
}
+RefPtr<ThreadableWebSocketChannel> WebSocket::channel() const
+{
+ return m_channel;
+}
+
const URL& WebSocket::url() const
{
return m_url;
Modified: trunk/Source/WebCore/Modules/websockets/WebSocket.h (217720 => 217721)
--- trunk/Source/WebCore/Modules/websockets/WebSocket.h 2017-06-02 17:01:36 UTC (rev 217720)
+++ trunk/Source/WebCore/Modules/websockets/WebSocket.h 2017-06-02 17:54:47 UTC (rev 217721)
@@ -39,6 +39,8 @@
#include "URL.h"
#include "WebSocketChannelClient.h"
#include <wtf/Deque.h>
+#include <wtf/HashSet.h>
+#include <wtf/Lock.h>
namespace JSC {
class ArrayBuffer;
@@ -62,6 +64,9 @@
static ExceptionOr<Ref<WebSocket>> create(ScriptExecutionContext&, const String& url, const Vector<String>& protocols);
virtual ~WebSocket();
+ static HashSet<WebSocket*>& allActiveWebSockets(const LockHolder&);
+ static StaticLock& allActiveWebSocketsMutex();
+
enum State {
CONNECTING = 0,
OPEN = 1,
@@ -80,6 +85,8 @@
ExceptionOr<void> close(std::optional<unsigned short> code, const String& reason);
+ RefPtr<ThreadableWebSocketChannel> channel() const;
+
const URL& url() const;
State readyState() const;
unsigned bufferedAmount() const;
@@ -90,6 +97,8 @@
String binaryType() const;
ExceptionOr<void> setBinaryType(const String&);
+ ScriptExecutionContext* scriptExecutionContext() const final;
+
using RefCounted::ref;
using RefCounted::deref;
@@ -108,7 +117,6 @@
const char* activeDOMObjectName() const final;
EventTargetInterface eventTargetInterface() const final;
- ScriptExecutionContext* scriptExecutionContext() const final;
void refEventTarget() final { ref(); }
void derefEventTarget() final { deref(); }
Modified: trunk/Source/WebCore/Modules/websockets/WebSocketChannel.cpp (217720 => 217721)
--- trunk/Source/WebCore/Modules/websockets/WebSocketChannel.cpp 2017-06-02 17:01:36 UTC (rev 217720)
+++ trunk/Source/WebCore/Modules/websockets/WebSocketChannel.cpp 2017-06-02 17:54:47 UTC (rev 217721)
@@ -831,6 +831,21 @@
m_handle->sendData(frameData.data(), frameData.size(), WTFMove(completionHandler));
}
+ResourceRequest WebSocketChannel::clientHandshakeRequest() const
+{
+ return m_handshake->clientHandshakeRequest();
+}
+
+const ResourceResponse& WebSocketChannel::serverHandshakeResponse() const
+{
+ return m_handshake->serverHandshakeResponse();
+}
+
+WebSocketHandshake::Mode WebSocketChannel::handshakeMode() const
+{
+ return m_handshake->mode();
+}
+
} // namespace WebCore
#endif // ENABLE(WEB_SOCKETS)
Modified: trunk/Source/WebCore/Modules/websockets/WebSocketChannel.h (217720 => 217721)
--- trunk/Source/WebCore/Modules/websockets/WebSocketChannel.h 2017-06-02 17:01:36 UTC (rev 217720)
+++ trunk/Source/WebCore/Modules/websockets/WebSocketChannel.h 2017-06-02 17:54:47 UTC (rev 217721)
@@ -38,9 +38,11 @@
#include "Timer.h"
#include "WebSocketDeflateFramer.h"
#include "WebSocketFrame.h"
+#include "WebSocketHandshake.h"
#include <wtf/Deque.h>
#include <wtf/Forward.h>
#include <wtf/RefCounted.h>
+#include <wtf/TypeCasts.h>
#include <wtf/Vector.h>
#include <wtf/text/CString.h>
@@ -49,11 +51,12 @@
class Blob;
class Document;
class FileReaderLoader;
+class ResourceRequest;
+class ResourceResponse;
class SocketProvider;
class SocketStreamHandle;
class SocketStreamError;
class WebSocketChannelClient;
-class WebSocketHandshake;
class WebSocketChannel : public RefCounted<WebSocketChannel>, public SocketStreamHandleClient, public ThreadableWebSocketChannel, public FileReaderLoaderClient
{
@@ -62,6 +65,8 @@
static Ref<WebSocketChannel> create(Document& document, WebSocketChannelClient& client, SocketProvider& provider) { return adoptRef(*new WebSocketChannel(document, client, provider)); }
virtual ~WebSocketChannel();
+ bool isWebSocketChannel() const final { return true; }
+
bool send(const char* data, int length);
// ThreadableWebSocketChannel functions.
@@ -112,6 +117,11 @@
void didFinishLoading() override;
void didFail(int errorCode) override;
+ unsigned identifier() const { return m_identifier; }
+ ResourceRequest clientHandshakeRequest() const;
+ const ResourceResponse& serverHandshakeResponse() const;
+ WebSocketHandshake::Mode handshakeMode() const;
+
using RefCounted<WebSocketChannel>::ref;
using RefCounted<WebSocketChannel>::deref;
@@ -219,4 +229,8 @@
} // namespace WebCore
+SPECIALIZE_TYPE_TRAITS_BEGIN(WebCore::WebSocketChannel)
+ static bool isType(const WebCore::ThreadableWebSocketChannel& threadableWebSocketChannel) { return threadableWebSocketChannel.isWebSocketChannel(); }
+SPECIALIZE_TYPE_TRAITS_END()
+
#endif // ENABLE(WEB_SOCKETS)
Modified: trunk/Source/WebCore/inspector/InspectorNetworkAgent.cpp (217720 => 217721)
--- trunk/Source/WebCore/inspector/InspectorNetworkAgent.cpp 2017-06-02 17:01:36 UTC (rev 217720)
+++ trunk/Source/WebCore/inspector/InspectorNetworkAgent.cpp 2017-06-02 17:54:47 UTC (rev 217721)
@@ -60,6 +60,8 @@
#include "SubresourceLoader.h"
#include "ThreadableLoaderClient.h"
#include "URL.h"
+#include "WebSocket.h"
+#include "WebSocketChannel.h"
#include "WebSocketFrame.h"
#include <inspector/ContentSearchUtilities.h>
#include <inspector/IdentifiersFactory.h>
@@ -67,6 +69,7 @@
#include <inspector/InspectorValues.h>
#include <inspector/ScriptCallStack.h>
#include <inspector/ScriptCallStackFactory.h>
+#include <wtf/Lock.h>
#include <wtf/RefPtr.h>
#include <wtf/Stopwatch.h>
#include <wtf/text/StringBuilder.h>
@@ -655,6 +658,31 @@
{
m_enabled = true;
m_instrumentingAgents.setInspectorNetworkAgent(this);
+
+ LockHolder lock(WebSocket::allActiveWebSocketsMutex());
+
+ for (WebSocket* webSocket : WebSocket::allActiveWebSockets(lock)) {
+ if (!is<Document>(webSocket->scriptExecutionContext()) || !is<WebSocketChannel>(webSocket->channel().get()))
+ continue;
+
+ Document* document = downcast<Document>(webSocket->scriptExecutionContext());
+ if (document->page() != &m_pageAgent->page())
+ continue;
+
+ WebSocketChannel* channel = downcast<WebSocketChannel>(webSocket->channel().get());
+ if (!channel)
+ continue;
+
+ unsigned identifier = channel->identifier();
+ didCreateWebSocket(identifier, webSocket->url());
+ willSendWebSocketHandshakeRequest(identifier, channel->clientHandshakeRequest());
+
+ if (channel->handshakeMode() == WebSocketHandshake::Connected)
+ didReceiveWebSocketHandshakeResponse(identifier, channel->serverHandshakeResponse());
+
+ if (webSocket->readyState() == WebSocket::CLOSED)
+ didCloseWebSocket(identifier);
+ }
}
void InspectorNetworkAgent::disable(ErrorString&)
Modified: trunk/Source/WebInspectorUI/ChangeLog (217720 => 217721)
--- trunk/Source/WebInspectorUI/ChangeLog 2017-06-02 17:01:36 UTC (rev 217720)
+++ trunk/Source/WebInspectorUI/ChangeLog 2017-06-02 17:54:47 UTC (rev 217721)
@@ -1,3 +1,20 @@
+2017-06-02 Devin Rousso <drou...@apple.com>
+
+ Web Inspector: Should see active Web Sockets when opening Web Inspector
+ https://bugs.webkit.org/show_bug.cgi?id=172312
+
+ Reviewed by Joseph Pecoraro.
+
+ * UserInterface/Controllers/FrameResourceManager.js:
+ (WebInspector.FrameResourceManager.prototype.webSocketHandshakeResponseReceived):
+ (WebInspector.FrameResourceManager.prototype.initialize): Removed.
+ Rework order of agent enable calls to ensure that the main frame is initialized before any
+ websocket events are dispatched.
+
+ * UserInterface/Models/WebSocketResource.js:
+ (WebInspector.WebSocketResource.ReadyState):
+ Change symbol strings in enum for better printing in tests.
+
2017-06-01 Ryan Haddad <ryanhad...@apple.com>
Unreviewed, rolling out r217691.
Modified: trunk/Source/WebInspectorUI/UserInterface/Controllers/FrameResourceManager.js (217720 => 217721)
--- trunk/Source/WebInspectorUI/UserInterface/Controllers/FrameResourceManager.js 2017-06-02 17:01:36 UTC (rev 217720)
+++ trunk/Source/WebInspectorUI/UserInterface/Controllers/FrameResourceManager.js 2017-06-02 17:54:47 UTC (rev 217721)
@@ -29,22 +29,6 @@
{
super();
- if (window.PageAgent)
- PageAgent.enable();
- if (window.NetworkAgent)
- NetworkAgent.enable();
-
- WebInspector.notifications.addEventListener(WebInspector.Notification.ExtraDomainsActivated, this._extraDomainsActivated, this);
-
- this.initialize();
- }
-
- // Public
-
- initialize()
- {
- var oldMainFrame = this._mainFrame;
-
this._frameIdentifierMap = new Map;
this._mainFrame = null;
this._resourceRequestIdentifierMap = new Map;
@@ -51,14 +35,21 @@
this._orphanedResources = new Map;
this._webSocketIdentifierToURL = new Map;
- if (this._mainFrame !== oldMainFrame)
- this._mainFrameDidChange(oldMainFrame);
+ this._waitingForMainFrameResourceTreePayload = true;
- this._waitingForMainFrameResourceTreePayload = true;
- if (window.PageAgent)
+ if (window.PageAgent) {
+ PageAgent.enable();
PageAgent.getResourceTree(this._processMainFrameResourceTreePayload.bind(this));
+ }
+
+ if (window.NetworkAgent)
+ NetworkAgent.enable();
+
+ WebInspector.notifications.addEventListener(WebInspector.Notification.ExtraDomainsActivated, this._extraDomainsActivated, this);
}
+ // Public
+
get mainFrame()
{
return this._mainFrame;
@@ -246,12 +237,13 @@
resource.readyState = WebInspector.WebSocketResource.ReadyState.Open;
let elapsedTime = WebInspector.timelineManager.computeElapsedTime(timestamp);
- resource.markAsFinished(elapsedTime);
// FIXME: <webkit.org/b/169166> Web Inspector: WebSockets: Implement timing information
let responseTiming = response.timing || null;
resource.updateForResponse(resource.url, resource.mimeType, resource.type, response.headers, response.status, response.statusText, elapsedTime, responseTiming);
+
+ resource.markAsFinished(elapsedTime);
}
webSocketFrameReceived(requestId, timestamp, response)
Modified: trunk/Source/WebInspectorUI/UserInterface/Models/WebSocketResource.js (217720 => 217721)
--- trunk/Source/WebInspectorUI/UserInterface/Models/WebSocketResource.js 2017-06-02 17:01:36 UTC (rev 217720)
+++ trunk/Source/WebInspectorUI/UserInterface/Models/WebSocketResource.js 2017-06-02 17:54:47 UTC (rev 217721)
@@ -95,9 +95,9 @@
};
WebInspector.WebSocketResource.ReadyState = {
- Closed: Symbol("web-socket-ready-state-closed"),
- Connecting: Symbol("web-socket-ready-state-connecting"),
- Open: Symbol("web-socket-ready-state-open"),
+ Closed: Symbol("closed"),
+ Connecting: Symbol("connecting"),
+ Open: Symbol("open"),
};
WebInspector.WebSocketResource.OpCodes = {