WebSocket's MessageEvent.origin attribute is an empty string
authorcommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 23 Nov 2012 11:52:11 +0000 (11:52 +0000)
committercommit-queue@webkit.org <commit-queue@webkit.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 23 Nov 2012 11:52:11 +0000 (11:52 +0000)
https://bugs.webkit.org/show_bug.cgi?id=102889

Patch by Christophe Dumez <christophe.dumez@intel.com> on 2012-11-23
Reviewed by Kentaro Hara.

Source/WebCore:

Fix WebSocket implementation so that the message event's origin
attribute is properly set to the Unicode serialization of the
origin of the URL that was passed to the WebSocket object's
constructor, instead of an empty string.

The new behavior is according to the specification:
http://www.whatwg.org/specs/web-apps/current-work/multipage/network.html#feedback-from-the-protocol

It also matches the behavior of Firefox.

Tests: http/tests/websocket/tests/hybi/send-blob-onmessage-origin.html
       http/tests/websocket/tests/hybi/send-onmessage-origin.html

* Modules/websockets/WebSocket.cpp:
(WebCore::WebSocket::didReceiveMessage):
(WebCore::WebSocket::didReceiveBinaryData):
* dom/MessageEvent.cpp:
(WebCore::MessageEvent::MessageEvent):
* dom/MessageEvent.h:
(WebCore::MessageEvent::create):
(MessageEvent):

LayoutTests:

Add layout tests to check that the message event's origin attribute
is set to the Unicode serialization of the origin of the URL that
was passed to the WebSocket object's constructor, as per the
WebSocket specification.

* http/tests/websocket/tests/hybi/send-blob-onmessage-origin-expected.txt: Added.
* http/tests/websocket/tests/hybi/send-blob-onmessage-origin.html: Added.
* http/tests/websocket/tests/hybi/send-onmessage-origin-expected.txt: Added.
* http/tests/websocket/tests/hybi/send-onmessage-origin.html: Added.

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

LayoutTests/ChangeLog
LayoutTests/http/tests/websocket/tests/hybi/send-blob-onmessage-origin-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/websocket/tests/hybi/send-blob-onmessage-origin.html [new file with mode: 0644]
LayoutTests/http/tests/websocket/tests/hybi/send-onmessage-origin-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/websocket/tests/hybi/send-onmessage-origin.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/Modules/websockets/WebSocket.cpp
Source/WebCore/dom/MessageEvent.cpp
Source/WebCore/dom/MessageEvent.h

index 7a0b7d8..8f64bfe 100644 (file)
@@ -1,3 +1,20 @@
+2012-11-23  Christophe Dumez  <christophe.dumez@intel.com>
+
+        WebSocket's MessageEvent.origin attribute is an empty string
+        https://bugs.webkit.org/show_bug.cgi?id=102889
+
+        Reviewed by Kentaro Hara.
+
+        Add layout tests to check that the message event's origin attribute
+        is set to the Unicode serialization of the origin of the URL that
+        was passed to the WebSocket object's constructor, as per the
+        WebSocket specification.
+
+        * http/tests/websocket/tests/hybi/send-blob-onmessage-origin-expected.txt: Added.
+        * http/tests/websocket/tests/hybi/send-blob-onmessage-origin.html: Added.
+        * http/tests/websocket/tests/hybi/send-onmessage-origin-expected.txt: Added.
+        * http/tests/websocket/tests/hybi/send-onmessage-origin.html: Added.
+
 2012-11-22  Eugene Klyuchnikov  <eustas.bug@gmail.com>
 
         Web Inspector: No "Save Heap Snapshot" option after canceling save to file dialog.
diff --git a/LayoutTests/http/tests/websocket/tests/hybi/send-blob-onmessage-origin-expected.txt b/LayoutTests/http/tests/websocket/tests/hybi/send-blob-onmessage-origin-expected.txt
new file mode 100644 (file)
index 0000000..4fe2bca
--- /dev/null
@@ -0,0 +1,16 @@
+Web Socket message event origin attribute test (Blob message)
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+PASS PASS: Message #0.
+PASS origin is "ws://127.0.0.1:8880"
+PASS PASS: Message #1.
+PASS origin is "ws://127.0.0.1:8880"
+PASS PASS: Message #2.
+PASS origin is "ws://127.0.0.1:8880"
+PASS closeEvent.wasClean is true
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/http/tests/websocket/tests/hybi/send-blob-onmessage-origin.html b/LayoutTests/http/tests/websocket/tests/hybi/send-blob-onmessage-origin.html
new file mode 100644 (file)
index 0000000..c13a879
--- /dev/null
@@ -0,0 +1,69 @@
+<!DOCTYPE html>
+<html>
+<head>
+<script src="../../../../js-test-resources/js-test-pre.js"></script>
+</head>
+<body>
+<script>
+description("Web Socket message event origin attribute test (Blob message)");
+
+window.jsTestIsAsync = true;
+var data = "";
+var origin = "";
+
+function startsWith(target, prefix)
+{
+    return target.indexOf(prefix) === 0;
+}
+
+function createBlobContainingHelloWorld()
+{
+    return new Blob(["Hello, world!"]);
+}
+
+function createEmptyBlob()
+{
+    return new Blob([]);
+}
+
+function createBlobContainingAllDistinctBytes()
+{
+    var array = new Uint8Array(256);
+    for (var i = 0; i < 256; ++i)
+        array[i] = i;
+    return new Blob([array]);
+}
+
+var url = "ws://127.0.0.1:8880/websocket/tests/hybi/check-binary-messages";
+var ws = new WebSocket(url);
+var closeEvent;
+
+ws.onopen = function()
+{
+    ws.send(createBlobContainingHelloWorld());
+    ws.send(createEmptyBlob());
+    ws.send(createBlobContainingAllDistinctBytes());
+};
+
+ws.onmessage = function(event)
+{
+    var message = event.data;
+    if (startsWith(message, "PASS"))
+        testPassed(message);
+    else
+        testFailed(message);
+    origin = event.origin;
+    shouldBeEqualToString("origin", "ws://127.0.0.1:8880");
+};
+
+ws.onclose = function(event)
+{
+    closeEvent = event;
+    shouldBeTrue("closeEvent.wasClean");
+    finishJSTest();
+};
+
+</script>
+<script src="../../../../js-test-resources/js-test-post.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/http/tests/websocket/tests/hybi/send-onmessage-origin-expected.txt b/LayoutTests/http/tests/websocket/tests/hybi/send-onmessage-origin-expected.txt
new file mode 100644 (file)
index 0000000..f4baaf0
--- /dev/null
@@ -0,0 +1,15 @@
+Web Socket message event origin attribute test (String message)
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+
+Connected.
+PASS data is firstMessageToSend
+PASS origin is "ws://localhost:8880"
+PASS data is secondMessageToSend
+PASS origin is "ws://localhost:8880"
+Closed.
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/http/tests/websocket/tests/hybi/send-onmessage-origin.html b/LayoutTests/http/tests/websocket/tests/hybi/send-onmessage-origin.html
new file mode 100644 (file)
index 0000000..b871e91
--- /dev/null
@@ -0,0 +1,66 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<script src="../../../../js-test-resources/js-test-pre.js"></script>
+</head>
+<body>
+<script>
+description("Web Socket message event origin attribute test (String message)");
+
+window.jsTestIsAsync = true;
+
+function endTest()
+{
+    clearTimeout(timeoutID);
+    finishJSTest();
+}
+
+var ws = new WebSocket("ws://localhost:8880/websocket/tests/hybi/send");
+
+var firstMessageToSend = "This is the first message to send to the server.";
+var secondMessageToSend = "This is the second.";
+// needs to be global to be accessbile from shouldBe().
+var data = "";
+var origin = "";
+
+ws.onopen = function()
+{
+    debug("Connected.");
+    ws.send(firstMessageToSend);
+};
+
+ws.onmessage = function(messageEvent)
+{
+    // The server should echo back the first message.
+    data = messageEvent.data;
+    shouldBe("data", "firstMessageToSend");
+    origin = messageEvent.origin;
+    shouldBeEqualToString("origin", "ws://localhost:8880");
+    ws.onmessage = function(messageEvent) {
+        // The server should echo back the second message.
+        data = messageEvent.data;
+        shouldBe("data", "secondMessageToSend");
+        origin = messageEvent.origin;
+        shouldBeEqualToString("origin", "ws://localhost:8880");
+    };
+    ws.send(secondMessageToSend);
+};
+
+ws.onclose = function()
+{
+    debug("Closed.");
+    endTest();
+};
+
+function timeOutCallback()
+{
+    testFailed("Timed out in state: " + ws.readyState);
+    endTest();
+}
+
+var timeoutID = setTimeout(timeOutCallback, 3000);
+
+</script>
+<script src="../../../../js-test-resources/js-test-post.js"></script>
+</body>
+</html>
index 43f73c0..2ccd608 100644 (file)
@@ -1,3 +1,32 @@
+2012-11-23  Christophe Dumez  <christophe.dumez@intel.com>
+
+        WebSocket's MessageEvent.origin attribute is an empty string
+        https://bugs.webkit.org/show_bug.cgi?id=102889
+
+        Reviewed by Kentaro Hara.
+
+        Fix WebSocket implementation so that the message event's origin
+        attribute is properly set to the Unicode serialization of the
+        origin of the URL that was passed to the WebSocket object's
+        constructor, instead of an empty string.
+
+        The new behavior is according to the specification:
+        http://www.whatwg.org/specs/web-apps/current-work/multipage/network.html#feedback-from-the-protocol
+
+        It also matches the behavior of Firefox.
+
+        Tests: http/tests/websocket/tests/hybi/send-blob-onmessage-origin.html
+               http/tests/websocket/tests/hybi/send-onmessage-origin.html
+
+        * Modules/websockets/WebSocket.cpp:
+        (WebCore::WebSocket::didReceiveMessage):
+        (WebCore::WebSocket::didReceiveBinaryData):
+        * dom/MessageEvent.cpp:
+        (WebCore::MessageEvent::MessageEvent):
+        * dom/MessageEvent.h:
+        (WebCore::MessageEvent::create):
+        (MessageEvent):
+
 2012-11-22  Eugene Klyuchnikov  <eustas.bug@gmail.com>
 
         Web Inspector: No "Save Heap Snapshot" option after canceling save to file dialog.
index 7f30738..8cdc7da 100644 (file)
@@ -508,7 +508,7 @@ void WebSocket::didReceiveMessage(const String& msg)
     if (m_state != OPEN && m_state != CLOSING)
         return;
     ASSERT(scriptExecutionContext());
-    dispatchEvent(MessageEvent::create(msg));
+    dispatchEvent(MessageEvent::create(msg, SecurityOrigin::create(m_url)->toString()));
 }
 
 void WebSocket::didReceiveBinaryData(PassOwnPtr<Vector<char> > binaryData)
@@ -521,12 +521,12 @@ void WebSocket::didReceiveBinaryData(PassOwnPtr<Vector<char> > binaryData)
         OwnPtr<BlobData> blobData = BlobData::create();
         blobData->appendData(rawData.release(), 0, BlobDataItem::toEndOfFile);
         RefPtr<Blob> blob = Blob::create(blobData.release(), size);
-        dispatchEvent(MessageEvent::create(blob.release()));
+        dispatchEvent(MessageEvent::create(blob.release(), SecurityOrigin::create(m_url)->toString()));
         break;
     }
 
     case BinaryTypeArrayBuffer:
-        dispatchEvent(MessageEvent::create(ArrayBuffer::create(binaryData->data(), binaryData->size())));
+        dispatchEvent(MessageEvent::create(ArrayBuffer::create(binaryData->data(), binaryData->size()), SecurityOrigin::create(m_url)->toString()));
         break;
     }
 }
index 24b52dd..1282a25 100644 (file)
@@ -79,29 +79,29 @@ MessageEvent::MessageEvent(PassRefPtr<SerializedScriptValue> data, const String&
 #endif
 }
 
-MessageEvent::MessageEvent(const String& data)
+MessageEvent::MessageEvent(const String& data, const String& origin)
     : Event(eventNames().messageEvent, false, false)
     , m_dataType(DataTypeString)
     , m_dataAsString(data)
-    , m_origin("")
+    , m_origin(origin)
     , m_lastEventId("")
 {
 }
 
-MessageEvent::MessageEvent(PassRefPtr<Blob> data)
+MessageEvent::MessageEvent(PassRefPtr<Blob> data, const String& origin)
     : Event(eventNames().messageEvent, false, false)
     , m_dataType(DataTypeBlob)
     , m_dataAsBlob(data)
-    , m_origin("")
+    , m_origin(origin)
     , m_lastEventId("")
 {
 }
 
-MessageEvent::MessageEvent(PassRefPtr<ArrayBuffer> data)
+MessageEvent::MessageEvent(PassRefPtr<ArrayBuffer> data, const String& origin)
     : Event(eventNames().messageEvent, false, false)
     , m_dataType(DataTypeArrayBuffer)
     , m_dataAsArrayBuffer(data)
-    , m_origin("")
+    , m_origin(origin)
     , m_lastEventId("")
 {
 }
index 8a9d82c..0afc3f3 100644 (file)
@@ -64,17 +64,17 @@ public:
     {
         return adoptRef(new MessageEvent(data, origin, lastEventId, source, ports));
     }
-    static PassRefPtr<MessageEvent> create(const String& data)
+    static PassRefPtr<MessageEvent> create(const String& data, const String& origin = "")
     {
-        return adoptRef(new MessageEvent(data));
+        return adoptRef(new MessageEvent(data, origin));
     }
-    static PassRefPtr<MessageEvent> create(PassRefPtr<Blob> data)
+    static PassRefPtr<MessageEvent> create(PassRefPtr<Blob> data, const String& origin = "")
     {
-        return adoptRef(new MessageEvent(data));
+        return adoptRef(new MessageEvent(data, origin));
     }
-    static PassRefPtr<MessageEvent> create(PassRefPtr<ArrayBuffer> data)
+    static PassRefPtr<MessageEvent> create(PassRefPtr<ArrayBuffer> data, const String& origin = "")
     {
-        return adoptRef(new MessageEvent(data));
+        return adoptRef(new MessageEvent(data, origin));
     }
     static PassRefPtr<MessageEvent> create(const AtomicString& type, const MessageEventInit& initializer)
     {
@@ -119,9 +119,9 @@ private:
     MessageEvent(const ScriptValue& data, const String& origin, const String& lastEventId, PassRefPtr<DOMWindow> source, PassOwnPtr<MessagePortArray>);
     MessageEvent(PassRefPtr<SerializedScriptValue> data, const String& origin, const String& lastEventId, PassRefPtr<DOMWindow> source, PassOwnPtr<MessagePortArray>);
 
-    explicit MessageEvent(const String& data);
-    explicit MessageEvent(PassRefPtr<Blob> data);
-    explicit MessageEvent(PassRefPtr<ArrayBuffer> data);
+    explicit MessageEvent(const String& data, const String& origin);
+    explicit MessageEvent(PassRefPtr<Blob> data, const String& origin);
+    explicit MessageEvent(PassRefPtr<ArrayBuffer> data, const String& origin);
 
     DataType m_dataType;
     ScriptValue m_dataAsScriptValue;