2011-03-27 Fumitoshi Ukai <ukai@chromium.org>
authorukai@chromium.org <ukai@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 28 Mar 2011 06:46:23 +0000 (06:46 +0000)
committerukai@chromium.org <ukai@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Mon, 28 Mar 2011 06:46:23 +0000 (06:46 +0000)
        Reviewed by Alexey Proskuryakov.

        Don't call WebSocket::didClose() more than once.
        https://bugs.webkit.org/show_bug.cgi?id=57081

        If WebSocket close() is called, and connection is established, then
        it will call didClose() that resets m_channel to 0.
        After that, when connection is closed, WebSocketChannel will call
        didClose for the WebSocket instance.

        * http/tests/websocket/tests/close-unref-websocket-expected.txt: Added.
        * http/tests/websocket/tests/close-unref-websocket.html: Added.
        * http/tests/websocket/tests/hanging-handshake_wsh.py: Added.
2011-03-27  Fumitoshi Ukai  <ukai@chromium.org>

        Reviewed by Alexey Proskuryakov.

        Don't call WebSocket::didClose() more than once.
        https://bugs.webkit.org/show_bug.cgi?id=57081

        If WebSocket close() is called, and connection is established, then
        it will call didClose() that resets m_channel to 0.
        After that, when connection is closed, WebSocketChannel will call
        didClose for the WebSocket instance.

        Call WebSocketChannel::disconnect() before m_channel = 0 to make sure
        WebSocketChannel suppress the second didClose().

        Test: http/tests/websocket/tests/close-unref-websocket.html

        * websockets/WebSocket.cpp:
        (WebCore::WebSocket::didClose):

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

LayoutTests/ChangeLog
LayoutTests/http/tests/websocket/tests/close-unref-websocket-expected.txt [new file with mode: 0644]
LayoutTests/http/tests/websocket/tests/close-unref-websocket.html [new file with mode: 0644]
LayoutTests/http/tests/websocket/tests/hanging-handshake_wsh.py [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/websockets/WebSocket.cpp

index 95a1473..f30ca7e 100644 (file)
@@ -1,3 +1,19 @@
+2011-03-27  Fumitoshi Ukai  <ukai@chromium.org>
+
+        Reviewed by Alexey Proskuryakov.
+
+        Don't call WebSocket::didClose() more than once.
+        https://bugs.webkit.org/show_bug.cgi?id=57081
+
+        If WebSocket close() is called, and connection is established, then
+        it will call didClose() that resets m_channel to 0.
+        After that, when connection is closed, WebSocketChannel will call
+        didClose for the WebSocket instance.
+
+        * http/tests/websocket/tests/close-unref-websocket-expected.txt: Added.
+        * http/tests/websocket/tests/close-unref-websocket.html: Added.
+        * http/tests/websocket/tests/hanging-handshake_wsh.py: Added.
+
 2011-03-27  Yuta Kitamura  <yutak@chromium.org>
 
         Unreviewed, add Chromium test results for fast/blockflow/fallback-orientation.html.
diff --git a/LayoutTests/http/tests/websocket/tests/close-unref-websocket-expected.txt b/LayoutTests/http/tests/websocket/tests/close-unref-websocket-expected.txt
new file mode 100644 (file)
index 0000000..fc148b0
--- /dev/null
@@ -0,0 +1,9 @@
+Test if Web Socket is closed while handshaking and unreferenced, it should fire close event at most once.
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+PASS 1 is >= countCloseEvent
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/http/tests/websocket/tests/close-unref-websocket.html b/LayoutTests/http/tests/websocket/tests/close-unref-websocket.html
new file mode 100644 (file)
index 0000000..cc77003
--- /dev/null
@@ -0,0 +1,39 @@
+<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML//EN">
+<html>
+<head>
+<link rel="stylesheet" href="../../../js-test-resources/js-test-style.css">
+<script src="../../../js-test-resources/js-test-pre.js"></script>
+<script src="../../../js-test-resources/js-test-post-function.js"></script>
+</head>
+<body>
+<div id="description"></div>
+<div id="console"></div>
+<script type="text/javascript">
+description("Test if Web Socket is closed while handshaking and unreferenced, it should fire close event at most once.");
+
+if (window.layoutTestController)
+    layoutTestController.waitUntilDone();
+
+var countCloseEvent = 0;
+
+function endTest()
+{
+    shouldBeGreaterThanOrEqual("1", "countCloseEvent");
+    isSuccessfullyParsed();
+    if (window.layoutTestController)
+        layoutTestController.notifyDone();
+};
+
+var ws = new WebSocket("ws://127.0.0.1:8880/websocket/tests/hanging-handshake");
+ws.onclose = function() {
+    countCloseEvent += 1;
+};
+ws.close();
+ws = null;
+gc();
+setTimeout("endTest()", 100);
+var successfullyParsed = true;
+</script>
+
+</body>
+</html>
diff --git a/LayoutTests/http/tests/websocket/tests/hanging-handshake_wsh.py b/LayoutTests/http/tests/websocket/tests/hanging-handshake_wsh.py
new file mode 100644 (file)
index 0000000..8896f57
--- /dev/null
@@ -0,0 +1,6 @@
+def web_socket_do_extra_handshake(request):
+    request.connection.read()
+
+def web_socket_transfer_data(request):
+    pass
+
index 5f40451..7510fed 100644 (file)
@@ -1,3 +1,23 @@
+2011-03-27  Fumitoshi Ukai  <ukai@chromium.org>
+
+        Reviewed by Alexey Proskuryakov.
+
+        Don't call WebSocket::didClose() more than once.
+        https://bugs.webkit.org/show_bug.cgi?id=57081
+
+        If WebSocket close() is called, and connection is established, then
+        it will call didClose() that resets m_channel to 0.
+        After that, when connection is closed, WebSocketChannel will call
+        didClose for the WebSocket instance.
+
+        Call WebSocketChannel::disconnect() before m_channel = 0 to make sure
+        WebSocketChannel suppress the second didClose().
+
+        Test: http/tests/websocket/tests/close-unref-websocket.html
+
+        * websockets/WebSocket.cpp:
+        (WebCore::WebSocket::didClose):
+
 2011-03-27  Adam Barth  <abarth@webkit.org>
 
         Reviewed by Eric Seidel.
index e15d079..5dfd48b 100644 (file)
@@ -283,7 +283,10 @@ void WebSocket::didClose(unsigned long unhandledBufferedAmount)
     m_bufferedAmountAfterClose += unhandledBufferedAmount;
     ASSERT(scriptExecutionContext());
     dispatchEvent(Event::create(eventNames().closeEvent, false, false));
-    m_channel = 0;
+    if (m_channel) {
+        m_channel->disconnect();
+        m_channel = 0;
+    }
     if (hasPendingActivity())
         ActiveDOMObject::unsetPendingActivity(this);
 }