2010-03-05 Fumitoshi Ukai <ukai@chromium.org>
authorukai@chromium.org <ukai@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 5 Mar 2010 09:35:27 +0000 (09:35 +0000)
committerukai@chromium.org <ukai@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 5 Mar 2010 09:35:27 +0000 (09:35 +0000)
        Reviewed by Alexey Proskuryakov.

        WebSocket onmessageerror event handler
        https://bugs.webkit.org/show_bug.cgi?id=35570

        * websocket/tests/error-detect-expected.txt: Added.
        * websocket/tests/error-detect.html: Added.
        * websocket/tests/script-tests/error-detect.js: Added.
        * websocket/tests/unknown-frame-type_wsh.py: Added.
2010-03-05  Fumitoshi Ukai  <ukai@chromium.org>

        Reviewed by Alexey Proskuryakov.

        WebSocket onmessageerror event handler
        https://bugs.webkit.org/show_bug.cgi?id=35570

        Test: websocket/tests/error-detect.html

        * websockets/WebSocket.cpp:
        (WebCore::WebSocketChannel::didConnect): assert scriptExecutionContext.
        (WebCore::WebSocketChannel::didReceiveMessage): assert scriptExecutionContext.
        (WebCore::WebSocket::didReceiveMessageError):
        (WebCore::WebSocket::didClose): assert scriptExecutionContext.
        * websockets/WebSocket.h:
        * websockets/WebSocket.idl: Add onerror event listener
        * websockets/WebSocketChannel.cpp:
        (WebCore::WebSocketChannel::didReceiveData): call didReceiveMessageError if unknown frame tye is detected, or frame length overflowed.
        * websockets/WebSocketChannelClient.h:
        (WebCore::WebSocketChannelClient::didReceiveMessageError):

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

LayoutTests/ChangeLog
LayoutTests/websocket/tests/error-detect-expected.txt [new file with mode: 0644]
LayoutTests/websocket/tests/error-detect.html [new file with mode: 0644]
LayoutTests/websocket/tests/script-tests/error-detect.js [new file with mode: 0644]
LayoutTests/websocket/tests/unknown-frame-type_wsh.py [new file with mode: 0644]
WebCore/ChangeLog
WebCore/websockets/WebSocket.cpp
WebCore/websockets/WebSocket.h
WebCore/websockets/WebSocket.idl
WebCore/websockets/WebSocketChannel.cpp
WebCore/websockets/WebSocketChannelClient.h

index c223a51..7862a33 100644 (file)
@@ -1,3 +1,15 @@
+2010-03-05  Fumitoshi Ukai  <ukai@chromium.org>
+
+        Reviewed by Alexey Proskuryakov.
+
+        WebSocket onmessageerror event handler
+        https://bugs.webkit.org/show_bug.cgi?id=35570
+
+        * websocket/tests/error-detect-expected.txt: Added.
+        * websocket/tests/error-detect.html: Added.
+        * websocket/tests/script-tests/error-detect.js: Added.
+        * websocket/tests/unknown-frame-type_wsh.py: Added.
+
 2010-03-04  Fumitoshi Ukai  <ukai@chromium.org>
 
         Reviewed by Alexey Proskuryakov.
diff --git a/LayoutTests/websocket/tests/error-detect-expected.txt b/LayoutTests/websocket/tests/error-detect-expected.txt
new file mode 100644 (file)
index 0000000..6c69eed
--- /dev/null
@@ -0,0 +1,12 @@
+Make sure WebSocket correctly fire error event for unknown frame type.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+WebSocket is open
+received:done
+WebSocket is closed
+PASS errorCount is 255
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/websocket/tests/error-detect.html b/LayoutTests/websocket/tests/error-detect.html
new file mode 100644 (file)
index 0000000..0be1ae2
--- /dev/null
@@ -0,0 +1,13 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<link rel="stylesheet" href="../../fast/js/resources/js-test-style.css">
+<script src="../../fast/js/resources/js-test-pre.js"></script>
+<script src="../../fast/js/resources/js-test-post-function.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script src="script-tests/error-detect.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/websocket/tests/script-tests/error-detect.js b/LayoutTests/websocket/tests/script-tests/error-detect.js
new file mode 100644 (file)
index 0000000..5add102
--- /dev/null
@@ -0,0 +1,29 @@
+description("Make sure WebSocket correctly fire error event for unknown frame type.");
+if (window.layoutTestController)
+    layoutTestController.waitUntilDone();
+
+var errorCount = 0;
+
+function finish() {
+    shouldBe("errorCount", "255");
+    isSuccessfullyParsed();
+    if (window.layoutTestController)
+        layoutTestController.notifyDone();
+}
+
+var ws = new WebSocket("ws://127.0.0.1:8880/websocket/tests/unknown-frame-type");
+ws.onopen = function () {
+    debug("WebSocket is open");
+};
+ws.onmessage = function (evt) {
+    debug("received:" + evt.data);
+};
+ws.onerror = function () {
+    errorCount += 1;
+};
+ws.onclose = function () {
+    debug("WebSocket is closed");
+    finish();
+};
+
+var successfullyParsed = true;
diff --git a/LayoutTests/websocket/tests/unknown-frame-type_wsh.py b/LayoutTests/websocket/tests/unknown-frame-type_wsh.py
new file mode 100644 (file)
index 0000000..0ff339c
--- /dev/null
@@ -0,0 +1,12 @@
+from mod_pywebsocket import msgutil
+
+def web_socket_do_extra_handshake(request):
+    pass
+
+def web_socket_transfer_data(request):
+    for i in range(1, 128):
+        request.connection.write(chr(i) + str(i) + '\xff')
+    for i in range(128, 256):
+        msg = str(i)
+        request.connection.write(chr(i) + chr(len(msg)) + msg)
+    msgutil.send_message(request, 'done')
index 11f333c..c6e3bd5 100644 (file)
@@ -1,3 +1,24 @@
+2010-03-05  Fumitoshi Ukai  <ukai@chromium.org>
+
+        Reviewed by Alexey Proskuryakov.
+
+        WebSocket onmessageerror event handler
+        https://bugs.webkit.org/show_bug.cgi?id=35570
+
+        Test: websocket/tests/error-detect.html
+
+        * websockets/WebSocket.cpp:
+        (WebCore::WebSocketChannel::didConnect): assert scriptExecutionContext.
+        (WebCore::WebSocketChannel::didReceiveMessage): assert scriptExecutionContext.
+        (WebCore::WebSocket::didReceiveMessageError):
+        (WebCore::WebSocket::didClose): assert scriptExecutionContext.
+        * websockets/WebSocket.h:
+        * websockets/WebSocket.idl: Add onerror event listener
+        * websockets/WebSocketChannel.cpp:
+        (WebCore::WebSocketChannel::didReceiveData): call didReceiveMessageError if unknown frame tye is detected, or frame length overflowed.
+        * websockets/WebSocketChannelClient.h:
+        (WebCore::WebSocketChannelClient::didReceiveMessageError):
+
 2010-03-04  Garret Kelly  <gdk@chromium.org>
 
         Reviewed by Darin Fisher.
index cd5528b..f9d3052 100644 (file)
@@ -227,10 +227,11 @@ void WebSocket::stop()
 void WebSocket::didConnect()
 {
     LOG(Network, "WebSocket %p didConnect", this);
-    if (m_state != CONNECTING || !scriptExecutionContext()) {
+    if (m_state != CONNECTING) {
         didClose(0);
         return;
     }
+    ASSERT(scriptExecutionContext());
     m_state = OPEN;
     dispatchEvent(Event::create(eventNames().openEvent, false, false));
 }
@@ -238,18 +239,29 @@ void WebSocket::didConnect()
 void WebSocket::didReceiveMessage(const String& msg)
 {
     LOG(Network, "WebSocket %p didReceiveMessage %s", this, msg.utf8().data());
-    if (m_state != OPEN || !scriptExecutionContext())
+    if (m_state != OPEN)
         return;
+    ASSERT(scriptExecutionContext());
     RefPtr<MessageEvent> evt = MessageEvent::create();
     evt->initMessageEvent(eventNames().messageEvent, false, false, SerializedScriptValue::create(msg), "", "", 0, 0);
     dispatchEvent(evt);
 }
 
+void WebSocket::didReceiveMessageError()
+{
+    LOG(Network, "WebSocket %p didReceiveErrorMessage", this);
+    if (m_state != OPEN)
+        return;
+    ASSERT(scriptExecutionContext());
+    dispatchEvent(Event::create(eventNames().errorEvent, false, false));
+}
+
 void WebSocket::didClose(unsigned long unhandledBufferedAmount)
 {
     LOG(Network, "WebSocket %p didClose", this);
     m_state = CLOSED;
     m_bufferedAmountAfterClose += unhandledBufferedAmount;
+    ASSERT(scriptExecutionContext());
     dispatchEvent(Event::create(eventNames().closeEvent, false, false));
     m_channel = 0;
     if (hasPendingActivity())
index 8bda882..e91796f 100644 (file)
@@ -76,6 +76,7 @@ namespace WebCore {
 
         DEFINE_ATTRIBUTE_EVENT_LISTENER(open);
         DEFINE_ATTRIBUTE_EVENT_LISTENER(message);
+        DEFINE_ATTRIBUTE_EVENT_LISTENER(error);
         DEFINE_ATTRIBUTE_EVENT_LISTENER(close);
 
         // EventTarget
@@ -91,6 +92,7 @@ namespace WebCore {
         // WebSocketChannelClient
         virtual void didConnect();
         virtual void didReceiveMessage(const String& message);
+        virtual void didReceiveMessageError();
         virtual void didClose(unsigned long unhandledBufferedAmount);
 
     private:
@@ -101,10 +103,6 @@ namespace WebCore {
         virtual EventTargetData* eventTargetData();
         virtual EventTargetData* ensureEventTargetData();
 
-        void dispatchOpenEvent(Event*);
-        void dispatchMessageEvent(Event*);
-        void dispatchCloseEvent(Event*);
-
         RefPtr<ThreadableWebSocketChannel> m_channel;
 
         State m_state;
index ab163a9..1707478 100644 (file)
@@ -49,6 +49,7 @@ module websockets {
         // networking
         attribute EventListener onopen;
         attribute EventListener onmessage;
+        attribute EventListener onerror;
         attribute EventListener onclose;
 
         [Custom] boolean send(in DOMString data)
index d482885..3585cb7 100644 (file)
@@ -199,6 +199,9 @@ void WebSocketChannel::didReceiveData(SocketStreamHandle* handle, const char* da
             while (p < end) {
                 if (length > std::numeric_limits<int>::max() / 128) {
                     LOG(Network, "frame length overflow %d", length);
+                    m_client->didReceiveMessageError();
+                    if (!m_client)
+                        return;
                     handle->close();
                     return;
                 }
@@ -211,6 +214,9 @@ void WebSocketChannel::didReceiveData(SocketStreamHandle* handle, const char* da
             if (p + length < end) {
                 p += length;
                 nextFrame = p;
+                m_client->didReceiveMessageError();
+                if (!m_client)
+                    return;
             } else
                 break;
         } else {
@@ -220,6 +226,8 @@ void WebSocketChannel::didReceiveData(SocketStreamHandle* handle, const char* da
             if (p < end && *p == '\xff') {
                 if (frameByte == 0x00)
                     m_client->didReceiveMessage(String::fromUTF8(msgStart, p - msgStart));
+                else
+                    m_client->didReceiveMessageError();
                 if (!m_client)
                     return;
                 ++p;
index 5328eb7..1551073 100644 (file)
@@ -40,6 +40,7 @@ namespace WebCore {
         virtual ~WebSocketChannelClient() { }
         virtual void didConnect() { }
         virtual void didReceiveMessage(const String&) { }
+        virtual void didReceiveMessageError() { }
         virtual void didClose(unsigned long /* unhandledBufferedAmount */) { }
 
     protected: