From 17e360f5e5db65bee5453365abdec901b2068fd4 Mon Sep 17 00:00:00 2001 From: Andrea Marchesini Date: Wed, 28 Oct 2015 11:42:53 +0000 Subject: [PATCH] Bug 1215092 - WebSocketEventService and WebSocket discovering - part 4 - MessageAvailable event, r=michal --- dom/base/WebSocket.cpp | 10 +++++ dom/base/test/test_websocket_frame.html | 21 +++++++--- .../websocket/PWebSocketEventListener.ipdl | 4 ++ .../websocket/WebSocketEventListenerChild.cpp | 13 ++++++ .../websocket/WebSocketEventListenerChild.h | 4 ++ .../WebSocketEventListenerParent.cpp | 10 +++++ .../websocket/WebSocketEventService.cpp | 42 +++++++++++++++++++ .../websocket/WebSocketEventService.h | 5 +++ .../websocket/nsIWebSocketEventService.idl | 24 +++++++---- 9 files changed, 120 insertions(+), 13 deletions(-) diff --git a/dom/base/WebSocket.cpp b/dom/base/WebSocket.cpp index 56f5a39cc2bf..0b233615a2f7 100644 --- a/dom/base/WebSocket.cpp +++ b/dom/base/WebSocket.cpp @@ -1852,14 +1852,20 @@ WebSocket::CreateAndDispatchMessageEvent(JSContext* aCx, return NS_OK; } + uint16_t messageType = nsIWebSocketEventListener::TYPE_STRING; + // Create appropriate JS object for message JS::Rooted jsData(aCx); if (aIsBinary) { if (mBinaryType == dom::BinaryType::Blob) { + messageType = nsIWebSocketEventListener::TYPE_BLOB; + nsresult rv = nsContentUtils::CreateBlobBuffer(aCx, GetOwner(), aData, &jsData); NS_ENSURE_SUCCESS(rv, rv); } else if (mBinaryType == dom::BinaryType::Arraybuffer) { + messageType = nsIWebSocketEventListener::TYPE_ARRAYBUFFER; + JS::Rooted arrayBuf(aCx); nsresult rv = nsContentUtils::CreateArrayBuffer(aCx, aData, arrayBuf.address()); @@ -1879,6 +1885,10 @@ WebSocket::CreateAndDispatchMessageEvent(JSContext* aCx, jsData.setString(jsString); } + mImpl->mService->WebSocketMessageAvailable(mImpl->mChannel->Serial(), + mImpl->mInnerWindowID, + aData, messageType); + // create an event that uses the MessageEvent interface, // which does not bubble, is not cancelable, and has no default action diff --git a/dom/base/test/test_websocket_frame.html b/dom/base/test/test_websocket_frame.html index 78c12bd236f5..f12ed14d34bb 100644 --- a/dom/base/test/test_websocket_frame.html +++ b/dom/base/test/test_websocket_frame.html @@ -18,6 +18,7 @@ var frameReceivedCounter = 0; var frameSentCounter = 0; var webSocketCreatedCounter = 0; var webSocketOpenedCounter = 0; +var webSocketMessageAvailableCounter = 0; var webSocketClosedCounter = 0; Cu.import("resource://gre/modules/XPCOMUtils.jsm"); @@ -59,6 +60,20 @@ var listener = { webSocketOpenedCounter++; }, + webSocketMessageAvailable: function(aWebSocketSerialID, aData, aMessageType) { + info("WebSocketMessageAvailable"); + + is(aData, tests[0].payload, "Message matches!"); + is(aMessageType, Ci.nsIWebSocketEventListener.TYPE_STRING, "The type is 'string'"); + + webSocketMessageAvailableCounter++; + + tests.shift(); + if (tests.length) { + ws.send(tests[0].payload); + } + }, + webSocketClosed: function(aWebSocketSerialID, aWasClean, aCode, aReason) { info("WebSocketClosed"); @@ -136,6 +151,7 @@ function checkListener() { ok(frameSentCounter, "We sent some frames!"); ok(webSocketCreatedCounter, "We have a create notification"); ok(webSocketOpenedCounter, "We have a open notification"); + ok(webSocketMessageAvailableCounter, "We have a messageAvailable notification"); ok(webSocketClosedCounter, "We have a close notification"); SimpleTest.finish(); } @@ -153,12 +169,7 @@ ws.onclose = function(e) { ws.onmessage = function(e) { info("onmessage"); - is(e.data, tests[0].payload, "Wrong data"); - tests.shift(); - if (tests.length) { - ws.send(tests[0].payload); - } } SimpleTest.waitForExplicitFinish(); diff --git a/netwerk/protocol/websocket/PWebSocketEventListener.ipdl b/netwerk/protocol/websocket/PWebSocketEventListener.ipdl index 20e16fa9fd36..ef0310d7cb7a 100644 --- a/netwerk/protocol/websocket/PWebSocketEventListener.ipdl +++ b/netwerk/protocol/websocket/PWebSocketEventListener.ipdl @@ -26,6 +26,10 @@ child: nsCString aProtocols, nsCString aExtensions); + WebSocketMessageAvailable(uint32_t awebSocketSerialID, + nsCString aData, + uint16_t aMessageType); + WebSocketClosed(uint32_t awebSocketSerialID, bool aWasClean, uint16_t aCode, diff --git a/netwerk/protocol/websocket/WebSocketEventListenerChild.cpp b/netwerk/protocol/websocket/WebSocketEventListenerChild.cpp index 691d0fb1dd38..08a57b817b8c 100644 --- a/netwerk/protocol/websocket/WebSocketEventListenerChild.cpp +++ b/netwerk/protocol/websocket/WebSocketEventListenerChild.cpp @@ -49,6 +49,19 @@ WebSocketEventListenerChild::RecvWebSocketOpened(const uint32_t& aWebSocketSeria return true; } +bool +WebSocketEventListenerChild::RecvWebSocketMessageAvailable(const uint32_t& aWebSocketSerialID, + const nsCString& aData, + const uint16_t& aMessageType) +{ + if (mService) { + mService->WebSocketMessageAvailable(aWebSocketSerialID, mInnerWindowID, + aData, aMessageType); + } + + return true; +} + bool WebSocketEventListenerChild::RecvWebSocketClosed(const uint32_t& aWebSocketSerialID, const bool& aWasClean, diff --git a/netwerk/protocol/websocket/WebSocketEventListenerChild.h b/netwerk/protocol/websocket/WebSocketEventListenerChild.h index c8b5ecd3cfe7..8a42abac2bd3 100644 --- a/netwerk/protocol/websocket/WebSocketEventListenerChild.h +++ b/netwerk/protocol/websocket/WebSocketEventListenerChild.h @@ -30,6 +30,10 @@ public: const nsCString& aProtocols, const nsCString& aExtensions) override; + bool RecvWebSocketMessageAvailable(const uint32_t& aWebSocketSerialID, + const nsCString& aData, + const uint16_t& aMessageType) override; + bool RecvWebSocketClosed(const uint32_t& aWebSocketSerialID, const bool& aWasClean, const uint16_t& aCode, diff --git a/netwerk/protocol/websocket/WebSocketEventListenerParent.cpp b/netwerk/protocol/websocket/WebSocketEventListenerParent.cpp index 79647ef28efe..ef1d57188ee7 100644 --- a/netwerk/protocol/websocket/WebSocketEventListenerParent.cpp +++ b/netwerk/protocol/websocket/WebSocketEventListenerParent.cpp @@ -88,6 +88,16 @@ WebSocketEventListenerParent::WebSocketClosed(uint32_t aWebSocketSerialID, return NS_OK; } +NS_IMETHODIMP +WebSocketEventListenerParent::WebSocketMessageAvailable(uint32_t aWebSocketSerialID, + const nsACString& aData, + uint16_t aMessageType) +{ + unused << SendWebSocketMessageAvailable(aWebSocketSerialID, nsCString(aData), + aMessageType); + return NS_OK; +} + NS_IMETHODIMP WebSocketEventListenerParent::FrameReceived(uint32_t aWebSocketSerialID, nsIWebSocketFrame* aFrame) diff --git a/netwerk/protocol/websocket/WebSocketEventService.cpp b/netwerk/protocol/websocket/WebSocketEventService.cpp index 8eb55c7872bb..06984e75ef32 100644 --- a/netwerk/protocol/websocket/WebSocketEventService.cpp +++ b/netwerk/protocol/websocket/WebSocketEventService.cpp @@ -149,6 +149,30 @@ private: const nsCString mExtensions; }; +class WebSocketMessageAvailableRunnable final : public WebSocketBaseRunnable +{ +public: + WebSocketMessageAvailableRunnable(uint32_t aWebSocketSerialID, + uint64_t aInnerWindowID, + const nsACString& aData, + uint16_t aMessageType) + : WebSocketBaseRunnable(aWebSocketSerialID, aInnerWindowID) + , mData(aData) + , mMessageType(aMessageType) + {} + +private: + virtual void DoWork(nsIWebSocketEventListener* aListener) override + { + nsresult rv = aListener->WebSocketMessageAvailable(mWebSocketSerialID, + mData, mMessageType); + NS_WARN_IF(NS_FAILED(rv)); + } + + const nsCString mData; + uint16_t mMessageType; +}; + class WebSocketClosedRunnable final : public WebSocketBaseRunnable { public: @@ -252,6 +276,24 @@ WebSocketEventService::WebSocketOpened(uint32_t aWebSocketSerialID, NS_WARN_IF(NS_FAILED(rv)); } +void +WebSocketEventService::WebSocketMessageAvailable(uint32_t aWebSocketSerialID, + uint64_t aInnerWindowID, + const nsACString& aData, + uint16_t aMessageType) +{ + // Let's continue only if we have some listeners. + if (!HasListeners()) { + return; + } + + RefPtr runnable = + new WebSocketMessageAvailableRunnable(aWebSocketSerialID, aInnerWindowID, + aData, aMessageType); + nsresult rv = NS_DispatchToMainThread(runnable); + NS_WARN_IF(NS_FAILED(rv)); +} + void WebSocketEventService::WebSocketClosed(uint32_t aWebSocketSerialID, uint64_t aInnerWindowID, diff --git a/netwerk/protocol/websocket/WebSocketEventService.h b/netwerk/protocol/websocket/WebSocketEventService.h index 571da96614d5..2515c05ebf3e 100644 --- a/netwerk/protocol/websocket/WebSocketEventService.h +++ b/netwerk/protocol/websocket/WebSocketEventService.h @@ -46,6 +46,11 @@ public: const nsACString& aProtocols, const nsACString& aExtensions); + void WebSocketMessageAvailable(uint32_t aWebSocketSerialID, + uint64_t aInnerWindowID, + const nsACString& aData, + uint16_t aMessageType); + void WebSocketClosed(uint32_t aWebSocketSerialID, uint64_t aInnerWindowID, bool aWasClean, diff --git a/netwerk/protocol/websocket/nsIWebSocketEventService.idl b/netwerk/protocol/websocket/nsIWebSocketEventService.idl index f9f074026044..c2986dc2f059 100644 --- a/netwerk/protocol/websocket/nsIWebSocketEventService.idl +++ b/netwerk/protocol/websocket/nsIWebSocketEventService.idl @@ -6,7 +6,7 @@ #include "domstubs.idl" #include "nsISupports.idl" -[scriptable, builtinclass, uuid(470133f3-a04f-48a9-82bd-8d1bc7eb6f9c)] +[scriptable, builtinclass, uuid(6714a6be-2265-4f73-a988-d78a12416037)] interface nsIWebSocketFrame : nsISupports { readonly attribute DOMHighResTimeStamp timeStamp; @@ -26,17 +26,17 @@ interface nsIWebSocketFrame : nsISupports readonly attribute ACString payload; // Non-Control opCode values: - const long OPCODE_CONTINUATION = 0x0; - const long OPCODE_TEXT = 0x1; - const long OPCODE_BINARY = 0x2; + const unsigned short OPCODE_CONTINUATION = 0x0; + const unsigned short OPCODE_TEXT = 0x1; + const unsigned short OPCODE_BINARY = 0x2; // Control opCode values: - const long OPCODE_CLOSE = 0x8; - const long OPCODE_PING = 0x9; - const long OPCODE_PONG = 0xA; + const unsigned short OPCODE_CLOSE = 0x8; + const unsigned short OPCODE_PING = 0x9; + const unsigned short OPCODE_PONG = 0xA; }; -[scriptable, uuid(ccbd96ae-2b7d-42fc-9ee5-116fa8e1723a)] +[scriptable, uuid(e7c005ab-e694-489b-b741-96db43ffb16f)] interface nsIWebSocketEventListener : nsISupports { void webSocketCreated(in unsigned long aWebSocketSerialID, @@ -48,6 +48,14 @@ interface nsIWebSocketEventListener : nsISupports in ACString aProtocols, in ACString aExtensions); + const unsigned short TYPE_STRING = 0x0; + const unsigned short TYPE_BLOB = 0x1; + const unsigned short TYPE_ARRAYBUFFER = 0x2; + + void webSocketMessageAvailable(in unsigned long aWebSocketSerialID, + in ACString aMessage, + in unsigned short aType); + void webSocketClosed(in unsigned long aWebSocketSerialID, in boolean aWasClean, in unsigned short aCode,