Commit 936d8bf9 authored by bashi@chromium.org's avatar bashi@chromium.org

[WebSocket] Introduce ThreadableWebSocketChannel::SendResult

https://bugs.webkit.org/show_bug.cgi?id=80356

Reviewed by Kent Tamura.

Introduced ThreadableWebSocketChannel::SendResult type so that
WebSocketChannel can pass the validation result.

No new test. No changes in behavior.

* Modules/websockets/ThreadableWebSocketChannel.h: Added SendResult.
* Modules/websockets/ThreadableWebSocketChannelClientWrapper.cpp:
(WebCore::ThreadableWebSocketChannelClientWrapper::ThreadableWebSocketChannelClientWrapper):
(WebCore::ThreadableWebSocketChannelClientWrapper::sendRequestResult): Use ThreadableWebSocketChannel::SendResult instead of bool.
(WebCore::ThreadableWebSocketChannelClientWrapper::setSendRequestResult): Ditto.
* Modules/websockets/ThreadableWebSocketChannelClientWrapper.h:
(ThreadableWebSocketChannelClientWrapper):
* Modules/websockets/WebSocketChannel.cpp:
(WebCore::WebSocketChannel::send): Use ThreadableWebSocketChannel::SendResult instead of bool. Pass Cstring to enqueTextFrame instead of String.
(WebCore::WebSocketChannel::enqueueTextFrame): Ditto.
(WebCore::WebSocketChannel::processOutgoingFrameQueue): Ditto.
* Modules/websockets/WebSocketChannel.h:
(WebSocketChannel):
(QueuedFrame): Changed the type of stringData from String to CString.
* Modules/websockets/WorkerThreadableWebSocketChannel.cpp:
(WebCore::WorkerThreadableWebSocketChannel::send): Use ThreadableWebSocketChannel::SendResult instead of bool.
(WebCore::workerContextDidSend): Ditto.
(WebCore::WorkerThreadableWebSocketChannel::Peer::send): Ditto.
(WebCore::WorkerThreadableWebSocketChannel::Bridge::send): Ditto.
* Modules/websockets/WorkerThreadableWebSocketChannel.h:
(WorkerThreadableWebSocketChannel): ditto.
(Bridge): Ditto.


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@109832 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 05df421b
2012-03-05 Kenichi Ishibashi <bashi@chromium.org>
[WebSocket] Introduce ThreadableWebSocketChannel::SendResult
https://bugs.webkit.org/show_bug.cgi?id=80356
Reviewed by Kent Tamura.
Introduced ThreadableWebSocketChannel::SendResult type so that
WebSocketChannel can pass the validation result.
No new test. No changes in behavior.
* Modules/websockets/ThreadableWebSocketChannel.h: Added SendResult.
* Modules/websockets/ThreadableWebSocketChannelClientWrapper.cpp:
(WebCore::ThreadableWebSocketChannelClientWrapper::ThreadableWebSocketChannelClientWrapper):
(WebCore::ThreadableWebSocketChannelClientWrapper::sendRequestResult): Use ThreadableWebSocketChannel::SendResult instead of bool.
(WebCore::ThreadableWebSocketChannelClientWrapper::setSendRequestResult): Ditto.
* Modules/websockets/ThreadableWebSocketChannelClientWrapper.h:
(ThreadableWebSocketChannelClientWrapper):
* Modules/websockets/WebSocketChannel.cpp:
(WebCore::WebSocketChannel::send): Use ThreadableWebSocketChannel::SendResult instead of bool. Pass Cstring to enqueTextFrame instead of String.
(WebCore::WebSocketChannel::enqueueTextFrame): Ditto.
(WebCore::WebSocketChannel::processOutgoingFrameQueue): Ditto.
* Modules/websockets/WebSocketChannel.h:
(WebSocketChannel):
(QueuedFrame): Changed the type of stringData from String to CString.
* Modules/websockets/WorkerThreadableWebSocketChannel.cpp:
(WebCore::WorkerThreadableWebSocketChannel::send): Use ThreadableWebSocketChannel::SendResult instead of bool.
(WebCore::workerContextDidSend): Ditto.
(WebCore::WorkerThreadableWebSocketChannel::Peer::send): Ditto.
(WebCore::WorkerThreadableWebSocketChannel::Bridge::send): Ditto.
* Modules/websockets/WorkerThreadableWebSocketChannel.h:
(WorkerThreadableWebSocketChannel): ditto.
(Bridge): Ditto.
2012-03-05 Kentaro Hara <haraken@chromium.org>
[JSC] Cache the CSSPropertyID in JSCSSStyleDeclaration
......@@ -50,13 +50,19 @@ public:
ThreadableWebSocketChannel() { }
static PassRefPtr<ThreadableWebSocketChannel> create(ScriptExecutionContext*, WebSocketChannelClient*);
enum SendResult {
SendSuccess,
SendFail,
InvalidMessage
};
virtual bool useHixie76Protocol() = 0;
virtual void connect(const KURL&, const String& protocol) = 0;
virtual String subprotocol() = 0; // Will be available after didConnect() callback is invoked.
virtual String extensions() = 0; // Will be available after didConnect() callback is invoked.
virtual bool send(const String& message) = 0;
virtual bool send(const ArrayBuffer&) = 0;
virtual bool send(const Blob&) = 0;
virtual SendResult send(const String& message) = 0;
virtual SendResult send(const ArrayBuffer&) = 0;
virtual SendResult send(const Blob&) = 0;
virtual unsigned long bufferedAmount() const = 0;
virtual void close(int code, const String& reason) = 0;
// Log the reason text and close the connection. Will call didClose().
......
......@@ -46,7 +46,7 @@ ThreadableWebSocketChannelClientWrapper::ThreadableWebSocketChannelClientWrapper
, m_client(client)
, m_syncMethodDone(true)
, m_useHixie76Protocol(true)
, m_sendRequestResult(false)
, m_sendRequestResult(ThreadableWebSocketChannel::SendFail)
, m_bufferedAmount(0)
, m_suspended(false)
{
......@@ -112,12 +112,12 @@ void ThreadableWebSocketChannelClientWrapper::setExtensions(const String& extens
memcpy(m_extensions.data(), extensions.characters(), sizeof(UChar) * length);
}
bool ThreadableWebSocketChannelClientWrapper::sendRequestResult() const
ThreadableWebSocketChannel::SendResult ThreadableWebSocketChannelClientWrapper::sendRequestResult() const
{
return m_sendRequestResult;
}
void ThreadableWebSocketChannelClientWrapper::setSendRequestResult(bool sendRequestResult)
void ThreadableWebSocketChannelClientWrapper::setSendRequestResult(ThreadableWebSocketChannel::SendResult sendRequestResult)
{
m_sendRequestResult = sendRequestResult;
m_syncMethodDone = true;
......
......@@ -35,6 +35,7 @@
#include "PlatformString.h"
#include "ScriptExecutionContext.h"
#include "ThreadableWebSocketChannel.h"
#include "WebSocketChannelClient.h"
#include <wtf/Forward.h>
#include <wtf/OwnPtr.h>
......@@ -66,8 +67,8 @@ public:
String extensions() const;
void setExtensions(const String&);
bool sendRequestResult() const;
void setSendRequestResult(bool);
ThreadableWebSocketChannel::SendResult sendRequestResult() const;
void setSendRequestResult(ThreadableWebSocketChannel::SendResult);
unsigned long bufferedAmount() const;
void setBufferedAmount(unsigned long);
......@@ -104,7 +105,7 @@ private:
// ThreadSafeRefCounted must not have String member variables.
Vector<UChar> m_subprotocol;
Vector<UChar> m_extensions;
bool m_sendRequestResult;
ThreadableWebSocketChannel::SendResult m_sendRequestResult;
unsigned long m_bufferedAmount;
bool m_suspended;
Vector<OwnPtr<ScriptExecutionContext::Task> > m_pendingTasks;
......
......@@ -290,7 +290,7 @@ bool WebSocket::send(const String& message, ExceptionCode& ec)
}
// FIXME: check message is valid utf8.
ASSERT(m_channel);
return m_channel->send(message);
return m_channel->send(message) == ThreadableWebSocketChannel::SendSuccess;
}
bool WebSocket::send(ArrayBuffer* binaryData, ExceptionCode& ec)
......@@ -310,7 +310,7 @@ bool WebSocket::send(ArrayBuffer* binaryData, ExceptionCode& ec)
return false;
}
ASSERT(m_channel);
return m_channel->send(*binaryData);
return m_channel->send(*binaryData) == ThreadableWebSocketChannel::SendSuccess;
}
bool WebSocket::send(Blob* binaryData, ExceptionCode& ec)
......@@ -330,7 +330,7 @@ bool WebSocket::send(Blob* binaryData, ExceptionCode& ec)
return false;
}
ASSERT(m_channel);
return m_channel->send(*binaryData);
return m_channel->send(*binaryData) == ThreadableWebSocketChannel::SendSuccess;
}
void WebSocket::close(int code, const String& reason, ExceptionCode& ec)
......
......@@ -157,37 +157,37 @@ String WebSocketChannel::extensions()
return extensions;
}
bool WebSocketChannel::send(const String& message)
ThreadableWebSocketChannel::SendResult WebSocketChannel::send(const String& message)
{
LOG(Network, "WebSocketChannel %p send %s", this, message.utf8().data());
CString utf8 = message.utf8();
if (m_useHixie76Protocol) {
CString utf8 = message.utf8();
return sendFrameHixie76(utf8.data(), utf8.length());
return sendFrameHixie76(utf8.data(), utf8.length()) ? ThreadableWebSocketChannel::SendSuccess : ThreadableWebSocketChannel::SendFail;
}
enqueueTextFrame(message);
enqueueTextFrame(utf8);
// According to WebSocket API specification, WebSocket.send() should return void instead
// of boolean. However, our implementation still returns boolean due to compatibility
// concern (see bug 65850).
// m_channel->send() may happen later, thus it's not always possible to know whether
// the message has been sent to the socket successfully. In this case, we have no choice
// but to return true.
return true;
return ThreadableWebSocketChannel::SendSuccess;
}
bool WebSocketChannel::send(const ArrayBuffer& binaryData)
ThreadableWebSocketChannel::SendResult WebSocketChannel::send(const ArrayBuffer& binaryData)
{
LOG(Network, "WebSocketChannel %p send arraybuffer %p", this, &binaryData);
ASSERT(!m_useHixie76Protocol);
enqueueRawFrame(WebSocketFrame::OpCodeBinary, static_cast<const char*>(binaryData.data()), binaryData.byteLength());
return true;
return ThreadableWebSocketChannel::SendSuccess;
}
bool WebSocketChannel::send(const Blob& binaryData)
ThreadableWebSocketChannel::SendResult WebSocketChannel::send(const Blob& binaryData)
{
LOG(Network, "WebSocketChannel %p send blob %s", this, binaryData.url().string().utf8().data());
ASSERT(!m_useHixie76Protocol);
enqueueBlobFrame(WebSocketFrame::OpCodeBinary, binaryData);
return true;
return ThreadableWebSocketChannel::SendSuccess;
}
bool WebSocketChannel::send(const char* data, int length)
......@@ -856,7 +856,7 @@ bool WebSocketChannel::processFrameHixie76()
return false;
}
void WebSocketChannel::enqueueTextFrame(const String& string)
void WebSocketChannel::enqueueTextFrame(const CString& string)
{
ASSERT(!m_useHixie76Protocol);
ASSERT(m_outgoingFrameQueueStatus == OutgoingFrameQueueOpen);
......@@ -904,8 +904,7 @@ void WebSocketChannel::processOutgoingFrameQueue()
OwnPtr<QueuedFrame> frame = m_outgoingFrameQueue.takeFirst();
switch (frame->frameType) {
case QueuedFrameTypeString: {
CString utf8 = frame->stringData.utf8();
if (!sendFrame(frame->opCode, utf8.data(), utf8.length()))
if (!sendFrame(frame->opCode, frame->stringData.data(), frame->stringData.length()))
fail("Failed to send WebSocket frame.");
break;
}
......
......@@ -44,6 +44,7 @@
#include <wtf/Forward.h>
#include <wtf/RefCounted.h>
#include <wtf/Vector.h>
#include <wtf/text/CString.h>
namespace WebCore {
......@@ -71,9 +72,9 @@ public:
virtual void connect(const KURL&, const String& protocol) OVERRIDE;
virtual String subprotocol() OVERRIDE;
virtual String extensions() OVERRIDE;
virtual bool send(const String& message) OVERRIDE;
virtual bool send(const ArrayBuffer&) OVERRIDE;
virtual bool send(const Blob&) OVERRIDE;
virtual ThreadableWebSocketChannel::SendResult send(const String& message) OVERRIDE;
virtual ThreadableWebSocketChannel::SendResult send(const ArrayBuffer&) OVERRIDE;
virtual ThreadableWebSocketChannel::SendResult send(const Blob&) OVERRIDE;
virtual unsigned long bufferedAmount() const OVERRIDE;
virtual void close(int code, const String& reason) OVERRIDE; // Start closing handshake.
virtual void fail(const String& reason) OVERRIDE;
......@@ -160,11 +161,11 @@ private:
WebSocketFrame::OpCode opCode;
QueuedFrameType frameType;
// Only one of the following items is used, according to the value of frameType.
String stringData;
CString stringData;
Vector<char> vectorData;
RefPtr<Blob> blobData;
};
void enqueueTextFrame(const String&);
void enqueueTextFrame(const CString&);
void enqueueRawFrame(WebSocketFrame::OpCode, const char* data, size_t dataLength);
void enqueueBlobFrame(WebSocketFrame::OpCode, const Blob&);
......
......@@ -89,24 +89,24 @@ String WorkerThreadableWebSocketChannel::extensions()
return m_workerClientWrapper->extensions();
}
bool WorkerThreadableWebSocketChannel::send(const String& message)
ThreadableWebSocketChannel::SendResult WorkerThreadableWebSocketChannel::send(const String& message)
{
if (!m_bridge)
return false;
return ThreadableWebSocketChannel::SendFail;
return m_bridge->send(message);
}
bool WorkerThreadableWebSocketChannel::send(const ArrayBuffer& binaryData)
ThreadableWebSocketChannel::SendResult WorkerThreadableWebSocketChannel::send(const ArrayBuffer& binaryData)
{
if (!m_bridge)
return false;
return ThreadableWebSocketChannel::SendFail;
return m_bridge->send(binaryData);
}
bool WorkerThreadableWebSocketChannel::send(const Blob& binaryData)
ThreadableWebSocketChannel::SendResult WorkerThreadableWebSocketChannel::send(const Blob& binaryData)
{
if (!m_bridge)
return false;
return ThreadableWebSocketChannel::SendFail;
return m_bridge->send(binaryData);
}
......@@ -180,7 +180,7 @@ void WorkerThreadableWebSocketChannel::Peer::connect(const KURL& url, const Stri
m_mainWebSocketChannel->connect(url, protocol);
}
static void workerContextDidSend(ScriptExecutionContext* context, PassRefPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper, bool sendRequestResult)
static void workerContextDidSend(ScriptExecutionContext* context, PassRefPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper, ThreadableWebSocketChannel::SendResult sendRequestResult)
{
ASSERT_UNUSED(context, context->isWorkerContext());
workerClientWrapper->setSendRequestResult(sendRequestResult);
......@@ -191,7 +191,7 @@ void WorkerThreadableWebSocketChannel::Peer::send(const String& message)
ASSERT(isMainThread());
if (!m_mainWebSocketChannel || !m_workerClientWrapper)
return;
bool sendRequestResult = m_mainWebSocketChannel->send(message);
ThreadableWebSocketChannel::SendResult sendRequestResult = m_mainWebSocketChannel->send(message);
m_loaderProxy.postTaskForModeToWorkerContext(createCallbackTask(&workerContextDidSend, m_workerClientWrapper, sendRequestResult), m_taskMode);
}
......@@ -200,7 +200,7 @@ void WorkerThreadableWebSocketChannel::Peer::send(const ArrayBuffer& binaryData)
ASSERT(isMainThread());
if (!m_mainWebSocketChannel || !m_workerClientWrapper)
return;
bool sendRequestResult = m_mainWebSocketChannel->send(binaryData);
ThreadableWebSocketChannel::SendResult sendRequestResult = m_mainWebSocketChannel->send(binaryData);
m_loaderProxy.postTaskForModeToWorkerContext(createCallbackTask(&workerContextDidSend, m_workerClientWrapper, sendRequestResult), m_taskMode);
}
......@@ -209,7 +209,7 @@ void WorkerThreadableWebSocketChannel::Peer::send(const Blob& binaryData)
ASSERT(isMainThread());
if (!m_mainWebSocketChannel || !m_workerClientWrapper)
return;
bool sendRequestResult = m_mainWebSocketChannel->send(binaryData);
ThreadableWebSocketChannel::SendResult sendRequestResult = m_mainWebSocketChannel->send(binaryData);
m_loaderProxy.postTaskForModeToWorkerContext(createCallbackTask(&workerContextDidSend, m_workerClientWrapper, sendRequestResult), m_taskMode);
}
......@@ -432,23 +432,25 @@ void WorkerThreadableWebSocketChannel::mainThreadSendBlob(ScriptExecutionContext
peer->send(*blob);
}
bool WorkerThreadableWebSocketChannel::Bridge::send(const String& message)
ThreadableWebSocketChannel::SendResult WorkerThreadableWebSocketChannel::Bridge::send(const String& message)
{
if (!m_workerClientWrapper)
return false;
return ThreadableWebSocketChannel::SendFail;
ASSERT(m_peer);
setMethodNotCompleted();
m_loaderProxy.postTaskToLoader(createCallbackTask(&WorkerThreadableWebSocketChannel::mainThreadSend, AllowCrossThreadAccess(m_peer), message));
RefPtr<Bridge> protect(this);
waitForMethodCompletion();
ThreadableWebSocketChannelClientWrapper* clientWrapper = m_workerClientWrapper.get();
return clientWrapper && clientWrapper->sendRequestResult();
if (!clientWrapper)
return ThreadableWebSocketChannel::SendFail;
return clientWrapper->sendRequestResult();
}
bool WorkerThreadableWebSocketChannel::Bridge::send(const ArrayBuffer& binaryData)
ThreadableWebSocketChannel::SendResult WorkerThreadableWebSocketChannel::Bridge::send(const ArrayBuffer& binaryData)
{
if (!m_workerClientWrapper)
return false;
return ThreadableWebSocketChannel::SendFail;
ASSERT(m_peer);
// ArrayBuffer isn't thread-safe, hence the content of ArrayBuffer is copied into Vector<char>.
OwnPtr<Vector<char> > data = adoptPtr(new Vector<char>(binaryData.byteLength()));
......@@ -459,20 +461,24 @@ bool WorkerThreadableWebSocketChannel::Bridge::send(const ArrayBuffer& binaryDat
RefPtr<Bridge> protect(this);
waitForMethodCompletion();
ThreadableWebSocketChannelClientWrapper* clientWrapper = m_workerClientWrapper.get();
return clientWrapper && clientWrapper->sendRequestResult();
if (!clientWrapper)
return ThreadableWebSocketChannel::SendFail;
return clientWrapper->sendRequestResult();
}
bool WorkerThreadableWebSocketChannel::Bridge::send(const Blob& binaryData)
ThreadableWebSocketChannel::SendResult WorkerThreadableWebSocketChannel::Bridge::send(const Blob& binaryData)
{
if (!m_workerClientWrapper)
return false;
return ThreadableWebSocketChannel::SendFail;
ASSERT(m_peer);
setMethodNotCompleted();
m_loaderProxy.postTaskToLoader(createCallbackTask(&WorkerThreadableWebSocketChannel::mainThreadSendBlob, AllowCrossThreadAccess(m_peer), binaryData.url(), binaryData.type(), binaryData.size()));
RefPtr<Bridge> protect(this);
waitForMethodCompletion();
ThreadableWebSocketChannelClientWrapper* clientWrapper = m_workerClientWrapper.get();
return clientWrapper && clientWrapper->sendRequestResult();
if (!clientWrapper)
return ThreadableWebSocketChannel::SendFail;
return clientWrapper->sendRequestResult();
}
void WorkerThreadableWebSocketChannel::mainThreadBufferedAmount(ScriptExecutionContext* context, Peer* peer)
......
......@@ -65,9 +65,9 @@ public:
virtual void connect(const KURL&, const String& protocol) OVERRIDE;
virtual String subprotocol() OVERRIDE;
virtual String extensions() OVERRIDE;
virtual bool send(const String& message) OVERRIDE;
virtual bool send(const ArrayBuffer&) OVERRIDE;
virtual bool send(const Blob&) OVERRIDE;
virtual ThreadableWebSocketChannel::SendResult send(const String& message) OVERRIDE;
virtual ThreadableWebSocketChannel::SendResult send(const ArrayBuffer&) OVERRIDE;
virtual ThreadableWebSocketChannel::SendResult send(const Blob&) OVERRIDE;
virtual unsigned long bufferedAmount() const OVERRIDE;
virtual void close(int code, const String& reason) OVERRIDE;
virtual void fail(const String& reason) OVERRIDE;
......@@ -132,9 +132,9 @@ private:
}
~Bridge();
void connect(const KURL&, const String& protocol);
bool send(const String& message);
bool send(const ArrayBuffer&);
bool send(const Blob&);
ThreadableWebSocketChannel::SendResult send(const String& message);
ThreadableWebSocketChannel::SendResult send(const ArrayBuffer&);
ThreadableWebSocketChannel::SendResult send(const Blob&);
unsigned long bufferedAmount();
void close(int code, const String& reason);
void fail(const String& reason);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment