2010-02-11 Fumitoshi Ukai <ukai@chromium.org>
authorukai@chromium.org <ukai@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 12 Feb 2010 02:12:59 +0000 (02:12 +0000)
committerukai@chromium.org <ukai@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 12 Feb 2010 02:12:59 +0000 (02:12 +0000)
        Reviewed by Alexey Proskuryakov.

        WebSocket bufferedAmount should not be 0 when send after close.
        https://bugs.webkit.org/show_bug.cgi?id=34633

        * websocket/tests/bufferedAmount-after-close-expected.txt: Added.
        * websocket/tests/bufferedAmount-after-close.html: Added.
        * websocket/tests/script-tests/bufferedAmount-after-close.js: Added.
2010-02-11  Fumitoshi Ukai  <ukai@chromium.org>

        Reviewed by Alexey Proskuryakov.

        WebSocket bufferedAmount should not be 0 when send after close.
        https://bugs.webkit.org/show_bug.cgi?id=34633

        Test: websocket/tests/bufferedAmount-after-close.html

        * websockets/ThreadableWebSocketChannelClientWrapper.h:
        (WebCore::ThreadableWebSocketChannelClientWrapper::didClose):
        * websockets/WebSocket.cpp:
        (WebCore::WebSocket::WebSocket):
        (WebCore::WebSocket::send):
        (WebCore::WebSocket::close):
        (WebCore::WebSocket::bufferedAmount):
        (WebCore::WebSocket::didConnect):
        (WebCore::WebSocket::didClose):
        * websockets/WebSocket.h:
        * websockets/WebSocketChannel.cpp:
        (WebCore::WebSocketChannel::WebSocketChannel):
        (WebCore::WebSocketChannel::send):
        (WebCore::WebSocketChannel::bufferedAmount):
        (WebCore::WebSocketChannel::didClose):
        * websockets/WebSocketChannel.h:
        * websockets/WebSocketChannelClient.h:
        (WebCore::WebSocketChannelClient::didClose):
        * websockets/WorkerThreadableWebSocketChannel.cpp:
        (WebCore::workerContextDidClose):
        (WebCore::WorkerThreadableWebSocketChannel::Peer::didClose):
        * websockets/WorkerThreadableWebSocketChannel.h:

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

13 files changed:
LayoutTests/ChangeLog
LayoutTests/websocket/tests/bufferedAmount-after-close-expected.txt [new file with mode: 0644]
LayoutTests/websocket/tests/bufferedAmount-after-close.html [new file with mode: 0644]
LayoutTests/websocket/tests/script-tests/bufferedAmount-after-close.js [new file with mode: 0644]
WebCore/ChangeLog
WebCore/websockets/ThreadableWebSocketChannelClientWrapper.h
WebCore/websockets/WebSocket.cpp
WebCore/websockets/WebSocket.h
WebCore/websockets/WebSocketChannel.cpp
WebCore/websockets/WebSocketChannel.h
WebCore/websockets/WebSocketChannelClient.h
WebCore/websockets/WorkerThreadableWebSocketChannel.cpp
WebCore/websockets/WorkerThreadableWebSocketChannel.h

index aeaba99..0157994 100644 (file)
@@ -2,6 +2,17 @@
 
         Reviewed by Alexey Proskuryakov.
 
+        WebSocket bufferedAmount should not be 0 when send after close.
+        https://bugs.webkit.org/show_bug.cgi?id=34633
+
+        * websocket/tests/bufferedAmount-after-close-expected.txt: Added.
+        * websocket/tests/bufferedAmount-after-close.html: Added.
+        * websocket/tests/script-tests/bufferedAmount-after-close.js: Added.
+
+2010-02-11  Fumitoshi Ukai  <ukai@chromium.org>
+
+        Reviewed by Alexey Proskuryakov.
+
         WebSocket in Worker failed to close
         https://bugs.webkit.org/show_bug.cgi?id=34785
 
diff --git a/LayoutTests/websocket/tests/bufferedAmount-after-close-expected.txt b/LayoutTests/websocket/tests/bufferedAmount-after-close-expected.txt
new file mode 100644 (file)
index 0000000..19e600d
--- /dev/null
@@ -0,0 +1,14 @@
+Web Socket bufferedAmount after closed
+
+On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
+
+Connected.
+Closed.
+PASS ws.readyState is 2
+PASS ws.bufferedAmount is 0
+PASS ws.send('send to closed socket') is false
+PASS ws.bufferedAmount is 23
+PASS successfullyParsed is true
+
+TEST COMPLETE
+
diff --git a/LayoutTests/websocket/tests/bufferedAmount-after-close.html b/LayoutTests/websocket/tests/bufferedAmount-after-close.html
new file mode 100644 (file)
index 0000000..f9a60ab
--- /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/bufferedAmount-after-close.js"></script>
+</body>
+</html>
diff --git a/LayoutTests/websocket/tests/script-tests/bufferedAmount-after-close.js b/LayoutTests/websocket/tests/script-tests/bufferedAmount-after-close.js
new file mode 100644 (file)
index 0000000..a79d3d7
--- /dev/null
@@ -0,0 +1,34 @@
+description("Web Socket bufferedAmount after closed");
+
+if (window.layoutTestController)
+    layoutTestController.waitUntilDone();
+
+function endTest()
+{
+    isSuccessfullyParsed();
+    if (window.layoutTestController)
+        layoutTestController.notifyDone();
+}
+
+var ws = new WebSocket("ws://localhost:8880/websocket/tests/simple");
+
+ws.onopen = function()
+{
+    debug("Connected.");
+    ws.close();
+};
+
+ws.onclose = function()
+{
+    debug("Closed.");
+    shouldBe("ws.readyState", "2");
+    shouldBe("ws.bufferedAmount", "0");
+    shouldBeFalse("ws.send('send to closed socket')");
+    // If the connection is closed, bufferedAmount attribute's value will only
+    // increase with each call to the send() method.
+    // (the number does not reset to zero once the connection closes).
+    shouldBe("ws.bufferedAmount", "23");
+    endTest();
+};
+
+var successfullyParsed = true;
index 5aee487..10c443e 100644 (file)
@@ -2,6 +2,38 @@
 
         Reviewed by Alexey Proskuryakov.
 
+        WebSocket bufferedAmount should not be 0 when send after close.
+        https://bugs.webkit.org/show_bug.cgi?id=34633
+
+        Test: websocket/tests/bufferedAmount-after-close.html
+
+        * websockets/ThreadableWebSocketChannelClientWrapper.h:
+        (WebCore::ThreadableWebSocketChannelClientWrapper::didClose):
+        * websockets/WebSocket.cpp:
+        (WebCore::WebSocket::WebSocket):
+        (WebCore::WebSocket::send):
+        (WebCore::WebSocket::close):
+        (WebCore::WebSocket::bufferedAmount):
+        (WebCore::WebSocket::didConnect):
+        (WebCore::WebSocket::didClose):
+        * websockets/WebSocket.h:
+        * websockets/WebSocketChannel.cpp:
+        (WebCore::WebSocketChannel::WebSocketChannel):
+        (WebCore::WebSocketChannel::send):
+        (WebCore::WebSocketChannel::bufferedAmount):
+        (WebCore::WebSocketChannel::didClose):
+        * websockets/WebSocketChannel.h:
+        * websockets/WebSocketChannelClient.h:
+        (WebCore::WebSocketChannelClient::didClose):
+        * websockets/WorkerThreadableWebSocketChannel.cpp:
+        (WebCore::workerContextDidClose):
+        (WebCore::WorkerThreadableWebSocketChannel::Peer::didClose):
+        * websockets/WorkerThreadableWebSocketChannel.h:
+
+2010-02-11  Fumitoshi Ukai  <ukai@chromium.org>
+
+        Reviewed by Alexey Proskuryakov.
+
         WebSocket in Worker failed to close
         https://bugs.webkit.org/show_bug.cgi?id=34785
 
index 8bf51fa..28d6129 100644 (file)
@@ -99,10 +99,10 @@ public:
             m_client->didReceiveMessage(msg);
     }
 
-    void didClose()
+    void didClose(unsigned long unhandledBufferedAmount)
     {
         if (m_client)
-            m_client->didClose();
+            m_client->didClose(unhandledBufferedAmount);
     }
 
 protected:
index f50dc5c..5a64b71 100644 (file)
@@ -97,6 +97,7 @@ bool WebSocket::isAvailable()
 WebSocket::WebSocket(ScriptExecutionContext* context)
     : ActiveDOMObject(context, this)
     , m_state(CONNECTING)
+    , m_bufferedAmountAfterClose(0)
 {
 }
 
@@ -162,9 +163,12 @@ bool WebSocket::send(const String& message, ExceptionCode& ec)
         return false;
     }
     // No exception is raised if the connection was once established but has subsequently been closed.
-    if (m_state == CLOSED)
+    if (m_state == CLOSED) {
+        m_bufferedAmountAfterClose += message.utf8().length() + 2; // 2 for framing
         return false;
+    }
     // FIXME: check message is valid utf8.
+    ASSERT(m_channel);
     return m_channel->send(message);
 }
 
@@ -174,6 +178,7 @@ void WebSocket::close()
     if (m_state == CLOSED)
         return;
     m_state = CLOSED;
+    m_bufferedAmountAfterClose = m_channel->bufferedAmount();
     m_channel->close();
 }
 
@@ -191,7 +196,7 @@ unsigned long WebSocket::bufferedAmount() const
 {
     if (m_state == OPEN)
         return m_channel->bufferedAmount();
-    return 0;
+    return m_bufferedAmountAfterClose;
 }
 
 ScriptExecutionContext* WebSocket::scriptExecutionContext() const
@@ -223,7 +228,7 @@ void WebSocket::didConnect()
 {
     LOG(Network, "WebSocket %p didConnect", this);
     if (m_state != CONNECTING || !scriptExecutionContext()) {
-        didClose();
+        didClose(0);
         return;
     }
     m_state = OPEN;
@@ -240,10 +245,11 @@ void WebSocket::didReceiveMessage(const String& msg)
     dispatchEvent(evt);
 }
 
-void WebSocket::didClose()
+void WebSocket::didClose(unsigned long unhandledBufferedAmount)
 {
     LOG(Network, "WebSocket %p didClose", this);
     m_state = CLOSED;
+    m_bufferedAmountAfterClose += unhandledBufferedAmount;
     dispatchEvent(Event::create(eventNames().closeEvent, false, false));
     m_channel = 0;
     if (hasPendingActivity())
index c72dbbd..8bda882 100644 (file)
@@ -91,7 +91,7 @@ namespace WebCore {
         // WebSocketChannelClient
         virtual void didConnect();
         virtual void didReceiveMessage(const String& message);
-        virtual void didClose();
+        virtual void didClose(unsigned long unhandledBufferedAmount);
 
     private:
         WebSocket(ScriptExecutionContext*);
@@ -111,6 +111,7 @@ namespace WebCore {
         KURL m_url;
         String m_protocol;
         EventTargetData m_eventTargetData;
+        unsigned long m_bufferedAmountAfterClose;
     };
 
 } // namespace WebCore
index df66c14..2ab133c 100644 (file)
@@ -57,7 +57,6 @@ WebSocketChannel::WebSocketChannel(ScriptExecutionContext* context, WebSocketCha
     , m_handshake(url, protocol, context)
     , m_buffer(0)
     , m_bufferSize(0)
-    , m_unhandledBufferSize(0)
 {
 }
 
@@ -78,22 +77,18 @@ void WebSocketChannel::connect()
 bool WebSocketChannel::send(const String& msg)
 {
     LOG(Network, "WebSocketChannel %p send %s", this, msg.utf8().data());
+    ASSERT(m_handle);
     Vector<char> buf;
     buf.append('\0');  // frame type
     buf.append(msg.utf8().data(), msg.utf8().length());
     buf.append('\xff');  // frame end
-    if (!m_handle) {
-        m_unhandledBufferSize += buf.size();
-        return false;
-    }
     return m_handle->send(buf.data(), buf.size());
 }
 
 unsigned long WebSocketChannel::bufferedAmount() const
 {
     LOG(Network, "WebSocketChannel %p bufferedAmount", this);
-    if (!m_handle)
-        return m_unhandledBufferSize;
+    ASSERT(m_handle);
     return m_handle->bufferedAmount();
 }
 
@@ -126,14 +121,14 @@ void WebSocketChannel::didOpen(SocketStreamHandle* handle)
 void WebSocketChannel::didClose(SocketStreamHandle* handle)
 {
     LOG(Network, "WebSocketChannel %p didClose", this);
-    ASSERT(handle == m_handle || !m_handle);
+    ASSERT_UNUSED(handle, handle == m_handle || !m_handle);
     if (m_handle) {
-        m_unhandledBufferSize = handle->bufferedAmount();
+        unsigned long unhandledBufferedAmount = m_handle->bufferedAmount();
         WebSocketChannelClient* client = m_client;
         m_client = 0;
         m_handle = 0;
         if (client)
-            client->didClose();
+            client->didClose(unhandledBufferedAmount);
     }
     deref();
 }
index 7ec826c..41a03ab 100644 (file)
@@ -83,7 +83,6 @@ namespace WebCore {
         RefPtr<SocketStreamHandle> m_handle;
         char* m_buffer;
         int m_bufferSize;
-        unsigned long m_unhandledBufferSize;
     };
 
 } // namespace WebCore
index 163070f..5328eb7 100644 (file)
@@ -40,7 +40,7 @@ namespace WebCore {
         virtual ~WebSocketChannelClient() { }
         virtual void didConnect() { }
         virtual void didReceiveMessage(const String&) { }
-        virtual void didClose() { }
+        virtual void didClose(unsigned long /* unhandledBufferedAmount */) { }
 
     protected:
         WebSocketChannelClient() { }
index dac1f19..3dda104 100644 (file)
@@ -190,17 +190,17 @@ void WorkerThreadableWebSocketChannel::Peer::didReceiveMessage(const String& mes
     m_loaderProxy.postTaskForModeToWorkerContext(createCallbackTask(&workerContextDidReceiveMessage, m_workerClientWrapper, message), m_taskMode);
 }
 
-static void workerContextDidClose(ScriptExecutionContext* context, RefPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper)
+static void workerContextDidClose(ScriptExecutionContext* context, RefPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper, unsigned long unhandledBufferedAmount)
 {
     ASSERT_UNUSED(context, context->isWorkerContext());
-    workerClientWrapper->didClose();
+    workerClientWrapper->didClose(unhandledBufferedAmount);
 }
 
-void WorkerThreadableWebSocketChannel::Peer::didClose()
+void WorkerThreadableWebSocketChannel::Peer::didClose(unsigned long unhandledBufferedAmount)
 {
     ASSERT(isMainThread());
     m_mainWebSocketChannel = 0;
-    m_loaderProxy.postTaskForModeToWorkerContext(createCallbackTask(&workerContextDidClose, m_workerClientWrapper), m_taskMode);
+    m_loaderProxy.postTaskForModeToWorkerContext(createCallbackTask(&workerContextDidClose, m_workerClientWrapper, unhandledBufferedAmount), m_taskMode);
 }
 
 void WorkerThreadableWebSocketChannel::Bridge::setWebSocketChannel(ScriptExecutionContext* context, Bridge* thisPtr, Peer* peer, RefPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper)
index 1106f43..a6a1680 100644 (file)
@@ -91,7 +91,7 @@ private:
 
         virtual void didConnect();
         virtual void didReceiveMessage(const String& message);
-        virtual void didClose();
+        virtual void didClose(unsigned long unhandledBufferedAmount);
 
     private:
         Peer(RefPtr<ThreadableWebSocketChannelClientWrapper>, WorkerLoaderProxy&, ScriptExecutionContext*, const String& taskMode, const KURL&, const String& protocol);