Commit 891dca6b authored by yutak@chromium.org's avatar yutak@chromium.org

WebSocket: Receive URL and subprotocol in WebSocketChannel::connect()

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

Reviewed by Kent Tamura.

To implement multiple subprotocols support (bug 65247), WebSocket::connect() will need to validate
the value of subprotocols after constructing WebSocketChannel, because the result depends on which
WebSocket protocol is used, which is obtained from WebSocketChannel::useHixie76Protocol(). This
means the subprotocol value will not be available at the time of WebSocketChannel construction.

This change moves URL and subprotocol arguments in WebSocketChannel constructor to
WebSocketChannel::connect(), which allows WebSocket::connect() function to check the subprotocol
value before the actual connection is established.

Relocating URL argument is technically not necessary, but seemed legitimate in terms of functional
correspondence between WebSocket and WebSocketChannel (constructor versus connect()).

No change in behavior, thus no new tests.

* websockets/ThreadableWebSocketChannel.cpp:
Remove "url" and "protocol" arguments from constructor and add them in connect().
(WebCore::ThreadableWebSocketChannel::create):
* websockets/ThreadableWebSocketChannel.h:
* websockets/WebSocket.cpp:
(WebCore::WebSocket::connect):
* websockets/WebSocketChannel.cpp: Same as ThreadableWebSocketChannel.
(WebCore::WebSocketChannel::WebSocketChannel):
(WebCore::WebSocketChannel::connect):
InspectorInstrumentation::didCreateWebSocket() call was moved to connect() because it needs URL.
This does not change behavior, because connect() is guaranteed to be called immediately after
WebSocketChannel is constructed.
* websockets/WebSocketChannel.h:
(WebCore::WebSocketChannel::create):
* websockets/WorkerThreadableWebSocketChannel.cpp: Same as ThreadableWebSocketChannel.
(WebCore::WorkerThreadableWebSocketChannel::WorkerThreadableWebSocketChannel):
(WebCore::WorkerThreadableWebSocketChannel::connect):
(WebCore::WorkerThreadableWebSocketChannel::Peer::Peer):
(WebCore::WorkerThreadableWebSocketChannel::Peer::connect):
(WebCore::WorkerThreadableWebSocketChannel::Bridge::mainThreadCreateWebSocketChannel):
(WebCore::WorkerThreadableWebSocketChannel::Bridge::Bridge):
(WebCore::WorkerThreadableWebSocketChannel::mainThreadConnect):
(WebCore::WorkerThreadableWebSocketChannel::Bridge::connect):
* websockets/WorkerThreadableWebSocketChannel.h:
(WebCore::WorkerThreadableWebSocketChannel::create):
(WebCore::WorkerThreadableWebSocketChannel::Peer::create):
(WebCore::WorkerThreadableWebSocketChannel::Bridge::create):


git-svn-id: http://svn.webkit.org/repository/webkit/trunk@92116 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent a3349129
2011-08-01 Yuta Kitamura <yutak@chromium.org>
WebSocket: Receive URL and subprotocol in WebSocketChannel::connect()
https://bugs.webkit.org/show_bug.cgi?id=65367
Reviewed by Kent Tamura.
To implement multiple subprotocols support (bug 65247), WebSocket::connect() will need to validate
the value of subprotocols after constructing WebSocketChannel, because the result depends on which
WebSocket protocol is used, which is obtained from WebSocketChannel::useHixie76Protocol(). This
means the subprotocol value will not be available at the time of WebSocketChannel construction.
This change moves URL and subprotocol arguments in WebSocketChannel constructor to
WebSocketChannel::connect(), which allows WebSocket::connect() function to check the subprotocol
value before the actual connection is established.
Relocating URL argument is technically not necessary, but seemed legitimate in terms of functional
correspondence between WebSocket and WebSocketChannel (constructor versus connect()).
No change in behavior, thus no new tests.
* websockets/ThreadableWebSocketChannel.cpp:
Remove "url" and "protocol" arguments from constructor and add them in connect().
(WebCore::ThreadableWebSocketChannel::create):
* websockets/ThreadableWebSocketChannel.h:
* websockets/WebSocket.cpp:
(WebCore::WebSocket::connect):
* websockets/WebSocketChannel.cpp: Same as ThreadableWebSocketChannel.
(WebCore::WebSocketChannel::WebSocketChannel):
(WebCore::WebSocketChannel::connect):
InspectorInstrumentation::didCreateWebSocket() call was moved to connect() because it needs URL.
This does not change behavior, because connect() is guaranteed to be called immediately after
WebSocketChannel is constructed.
* websockets/WebSocketChannel.h:
(WebCore::WebSocketChannel::create):
* websockets/WorkerThreadableWebSocketChannel.cpp: Same as ThreadableWebSocketChannel.
(WebCore::WorkerThreadableWebSocketChannel::WorkerThreadableWebSocketChannel):
(WebCore::WorkerThreadableWebSocketChannel::connect):
(WebCore::WorkerThreadableWebSocketChannel::Peer::Peer):
(WebCore::WorkerThreadableWebSocketChannel::Peer::connect):
(WebCore::WorkerThreadableWebSocketChannel::Bridge::mainThreadCreateWebSocketChannel):
(WebCore::WorkerThreadableWebSocketChannel::Bridge::Bridge):
(WebCore::WorkerThreadableWebSocketChannel::mainThreadConnect):
(WebCore::WorkerThreadableWebSocketChannel::Bridge::connect):
* websockets/WorkerThreadableWebSocketChannel.h:
(WebCore::WorkerThreadableWebSocketChannel::create):
(WebCore::WorkerThreadableWebSocketChannel::Peer::create):
(WebCore::WorkerThreadableWebSocketChannel::Bridge::create):
2011-08-01 Luke Macpherson <macpherson@chromium.org>
Add iterator to CSSValueList
......@@ -50,7 +50,7 @@ namespace WebCore {
static const char webSocketChannelMode[] = "webSocketChannelMode";
PassRefPtr<ThreadableWebSocketChannel> ThreadableWebSocketChannel::create(ScriptExecutionContext* context, WebSocketChannelClient* client, const KURL& url, const String& protocol)
PassRefPtr<ThreadableWebSocketChannel> ThreadableWebSocketChannel::create(ScriptExecutionContext* context, WebSocketChannelClient* client)
{
ASSERT(context);
ASSERT(client);
......@@ -61,12 +61,12 @@ PassRefPtr<ThreadableWebSocketChannel> ThreadableWebSocketChannel::create(Script
WorkerRunLoop& runLoop = workerContext->thread()->runLoop();
String mode = webSocketChannelMode;
mode.append(String::number(runLoop.createUniqueId()));
return WorkerThreadableWebSocketChannel::create(workerContext, client, mode, url, protocol);
return WorkerThreadableWebSocketChannel::create(workerContext, client, mode);
}
#endif // ENABLE(WORKERS)
ASSERT(context->isDocument());
return WebSocketChannel::create(context, client, url, protocol);
return WebSocketChannel::create(context, client);
}
} // namespace WebCore
......
......@@ -47,10 +47,10 @@ class ThreadableWebSocketChannel {
WTF_MAKE_NONCOPYABLE(ThreadableWebSocketChannel);
public:
ThreadableWebSocketChannel() { }
static PassRefPtr<ThreadableWebSocketChannel> create(ScriptExecutionContext*, WebSocketChannelClient*, const KURL&, const String& protocol);
static PassRefPtr<ThreadableWebSocketChannel> create(ScriptExecutionContext*, WebSocketChannelClient*);
virtual bool useHixie76Protocol() = 0;
virtual void connect() = 0;
virtual void connect(const KURL&, const String& protocol) = 0;
virtual bool send(const String& message) = 0;
virtual unsigned long bufferedAmount() const = 0;
virtual void close() = 0;
......
......@@ -151,8 +151,10 @@ void WebSocket::connect(const String& url, const String& protocol, ExceptionCode
return;
}
m_channel = ThreadableWebSocketChannel::create(scriptExecutionContext(), this, m_url, m_protocol);
m_channel->connect();
m_channel = ThreadableWebSocketChannel::create(scriptExecutionContext(), this);
// FIXME: Get the value of m_channel->useHixie76Protocol() and validate the value of subprotocol
// if hybi-10 protocol is used.
m_channel->connect(m_url, m_protocol);
ActiveDOMObject::setPendingActivity(this);
}
......
......@@ -82,7 +82,7 @@ const WebSocketChannel::OpCode WebSocketChannel::OpCodeClose = 0x8;
const WebSocketChannel::OpCode WebSocketChannel::OpCodePing = 0x9;
const WebSocketChannel::OpCode WebSocketChannel::OpCodePong = 0xA;
WebSocketChannel::WebSocketChannel(ScriptExecutionContext* context, WebSocketChannelClient* client, const KURL& url, const String& protocol)
WebSocketChannel::WebSocketChannel(ScriptExecutionContext* context, WebSocketChannelClient* client)
: m_context(context)
, m_client(client)
, m_buffer(0)
......@@ -103,12 +103,9 @@ WebSocketChannel::WebSocketChannel(ScriptExecutionContext* context, WebSocketCha
Document* document = static_cast<Document*>(m_context);
if (Settings* settings = document->settings())
m_useHixie76Protocol = settings->useHixie76WebSocketProtocol();
m_handshake = adoptPtr(new WebSocketHandshake(url, protocol, context, m_useHixie76Protocol));
if (Page* page = document->page())
m_identifier = page->progress()->createUniqueIdentifier();
if (m_identifier)
InspectorInstrumentation::didCreateWebSocket(m_context, m_identifier, url, m_context->url());
}
WebSocketChannel::~WebSocketChannel()
......@@ -121,12 +118,15 @@ bool WebSocketChannel::useHixie76Protocol()
return m_useHixie76Protocol;
}
void WebSocketChannel::connect()
void WebSocketChannel::connect(const KURL& url, const String& protocol)
{
LOG(Network, "WebSocketChannel %p connect", this);
ASSERT(!m_handle);
ASSERT(!m_suspended);
m_handshake = adoptPtr(new WebSocketHandshake(url, protocol, m_context, m_useHixie76Protocol));
m_handshake->reset();
if (m_identifier)
InspectorInstrumentation::didCreateWebSocket(m_context, m_identifier, url, m_context->url());
ref();
m_handle = SocketStreamHandle::create(m_handshake->url(), this);
}
......
......@@ -51,11 +51,11 @@ namespace WebCore {
class WebSocketChannel : public RefCounted<WebSocketChannel>, public SocketStreamHandleClient, public ThreadableWebSocketChannel {
WTF_MAKE_FAST_ALLOCATED;
public:
static PassRefPtr<WebSocketChannel> create(ScriptExecutionContext* context, WebSocketChannelClient* client, const KURL& url, const String& protocol) { return adoptRef(new WebSocketChannel(context, client, url, protocol)); }
static PassRefPtr<WebSocketChannel> create(ScriptExecutionContext* context, WebSocketChannelClient* client) { return adoptRef(new WebSocketChannel(context, client)); }
virtual ~WebSocketChannel();
virtual bool useHixie76Protocol();
virtual void connect();
virtual void connect(const KURL&, const String& protocol);
virtual bool send(const String& message);
virtual unsigned long bufferedAmount() const;
virtual void close(); // Start closing handshake.
......@@ -81,7 +81,7 @@ namespace WebCore {
virtual void derefThreadableWebSocketChannel() { deref(); }
private:
WebSocketChannel(ScriptExecutionContext*, WebSocketChannelClient*, const KURL&, const String& protocol);
WebSocketChannel(ScriptExecutionContext*, WebSocketChannelClient*);
bool appendToBuffer(const char* data, size_t len);
void skipBuffer(size_t len);
......
......@@ -49,10 +49,10 @@
namespace WebCore {
WorkerThreadableWebSocketChannel::WorkerThreadableWebSocketChannel(WorkerContext* context, WebSocketChannelClient* client, const String& taskMode, const KURL& url, const String& protocol)
WorkerThreadableWebSocketChannel::WorkerThreadableWebSocketChannel(WorkerContext* context, WebSocketChannelClient* client, const String& taskMode)
: m_workerContext(context)
, m_workerClientWrapper(ThreadableWebSocketChannelClientWrapper::create(client))
, m_bridge(Bridge::create(m_workerClientWrapper, m_workerContext, taskMode, url, protocol))
, m_bridge(Bridge::create(m_workerClientWrapper, m_workerContext, taskMode))
{
}
......@@ -68,10 +68,10 @@ bool WorkerThreadableWebSocketChannel::useHixie76Protocol()
return m_workerClientWrapper->useHixie76Protocol();
}
void WorkerThreadableWebSocketChannel::connect()
void WorkerThreadableWebSocketChannel::connect(const KURL& url, const String& protocol)
{
if (m_bridge)
m_bridge->connect();
m_bridge->connect(url, protocol);
}
bool WorkerThreadableWebSocketChannel::send(const String& message)
......@@ -120,10 +120,10 @@ void WorkerThreadableWebSocketChannel::resume()
m_bridge->resume();
}
WorkerThreadableWebSocketChannel::Peer::Peer(PassRefPtr<ThreadableWebSocketChannelClientWrapper> clientWrapper, WorkerLoaderProxy& loaderProxy, ScriptExecutionContext* context, const String& taskMode, const KURL& url, const String& protocol)
WorkerThreadableWebSocketChannel::Peer::Peer(PassRefPtr<ThreadableWebSocketChannelClientWrapper> clientWrapper, WorkerLoaderProxy& loaderProxy, ScriptExecutionContext* context, const String& taskMode)
: m_workerClientWrapper(clientWrapper)
, m_loaderProxy(loaderProxy)
, m_mainWebSocketChannel(WebSocketChannel::create(context, this, url, protocol))
, m_mainWebSocketChannel(WebSocketChannel::create(context, this))
, m_taskMode(taskMode)
{
ASSERT(isMainThread());
......@@ -143,12 +143,12 @@ bool WorkerThreadableWebSocketChannel::Peer::useHixie76Protocol()
return m_mainWebSocketChannel->useHixie76Protocol();
}
void WorkerThreadableWebSocketChannel::Peer::connect()
void WorkerThreadableWebSocketChannel::Peer::connect(const KURL& url, const String& protocol)
{
ASSERT(isMainThread());
if (!m_mainWebSocketChannel)
return;
m_mainWebSocketChannel->connect();
m_mainWebSocketChannel->connect(url, protocol);
}
static void workerContextDidSend(ScriptExecutionContext* context, RefPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper, bool sent)
......@@ -279,21 +279,21 @@ void WorkerThreadableWebSocketChannel::Bridge::setWebSocketChannel(ScriptExecuti
workerClientWrapper->setSyncMethodDone();
}
void WorkerThreadableWebSocketChannel::Bridge::mainThreadCreateWebSocketChannel(ScriptExecutionContext* context, Bridge* thisPtr, PassRefPtr<ThreadableWebSocketChannelClientWrapper> prpClientWrapper, const String& taskMode, const KURL& url, const String& protocol)
void WorkerThreadableWebSocketChannel::Bridge::mainThreadCreateWebSocketChannel(ScriptExecutionContext* context, Bridge* thisPtr, PassRefPtr<ThreadableWebSocketChannelClientWrapper> prpClientWrapper, const String& taskMode)
{
ASSERT(isMainThread());
ASSERT_UNUSED(context, context->isDocument());
RefPtr<ThreadableWebSocketChannelClientWrapper> clientWrapper = prpClientWrapper;
Peer* peer = Peer::create(clientWrapper, thisPtr->m_loaderProxy, context, taskMode, url, protocol);
Peer* peer = Peer::create(clientWrapper, thisPtr->m_loaderProxy, context, taskMode);
thisPtr->m_loaderProxy.postTaskForModeToWorkerContext(
createCallbackTask(&Bridge::setWebSocketChannel,
AllowCrossThreadAccess(thisPtr),
AllowCrossThreadAccess(peer), clientWrapper, peer->useHixie76Protocol()), taskMode);
}
WorkerThreadableWebSocketChannel::Bridge::Bridge(PassRefPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper, PassRefPtr<WorkerContext> workerContext, const String& taskMode, const KURL& url, const String& protocol)
WorkerThreadableWebSocketChannel::Bridge::Bridge(PassRefPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper, PassRefPtr<WorkerContext> workerContext, const String& taskMode)
: m_workerClientWrapper(workerClientWrapper)
, m_workerContext(workerContext)
, m_loaderProxy(m_workerContext->thread()->workerLoaderProxy())
......@@ -304,7 +304,7 @@ WorkerThreadableWebSocketChannel::Bridge::Bridge(PassRefPtr<ThreadableWebSocketC
setMethodNotCompleted();
m_loaderProxy.postTaskToLoader(
createCallbackTask(&Bridge::mainThreadCreateWebSocketChannel,
AllowCrossThreadAccess(this), m_workerClientWrapper, m_taskMode, url, protocol));
AllowCrossThreadAccess(this), m_workerClientWrapper, m_taskMode));
waitForMethodCompletion();
ASSERT(m_peer);
}
......@@ -314,20 +314,20 @@ WorkerThreadableWebSocketChannel::Bridge::~Bridge()
disconnect();
}
void WorkerThreadableWebSocketChannel::mainThreadConnect(ScriptExecutionContext* context, Peer* peer)
void WorkerThreadableWebSocketChannel::mainThreadConnect(ScriptExecutionContext* context, Peer* peer, const KURL& url, const String& protocol)
{
ASSERT(isMainThread());
ASSERT_UNUSED(context, context->isDocument());
ASSERT(peer);
peer->connect();
peer->connect(url, protocol);
}
void WorkerThreadableWebSocketChannel::Bridge::connect()
void WorkerThreadableWebSocketChannel::Bridge::connect(const KURL& url, const String& protocol)
{
ASSERT(m_workerClientWrapper);
ASSERT(m_peer);
m_loaderProxy.postTaskToLoader(createCallbackTask(&WorkerThreadableWebSocketChannel::mainThreadConnect, AllowCrossThreadAccess(m_peer)));
m_loaderProxy.postTaskToLoader(createCallbackTask(&WorkerThreadableWebSocketChannel::mainThreadConnect, AllowCrossThreadAccess(m_peer), url, protocol));
}
void WorkerThreadableWebSocketChannel::mainThreadSend(ScriptExecutionContext* context, Peer* peer, const String& message)
......
......@@ -54,14 +54,14 @@ class WorkerRunLoop;
class WorkerThreadableWebSocketChannel : public RefCounted<WorkerThreadableWebSocketChannel>, public ThreadableWebSocketChannel {
WTF_MAKE_FAST_ALLOCATED;
public:
static PassRefPtr<ThreadableWebSocketChannel> create(WorkerContext* workerContext, WebSocketChannelClient* client, const String& taskMode, const KURL& url, const String& protocol)
static PassRefPtr<ThreadableWebSocketChannel> create(WorkerContext* workerContext, WebSocketChannelClient* client, const String& taskMode)
{
return adoptRef(new WorkerThreadableWebSocketChannel(workerContext, client, taskMode, url, protocol));
return adoptRef(new WorkerThreadableWebSocketChannel(workerContext, client, taskMode));
}
virtual ~WorkerThreadableWebSocketChannel();
virtual bool useHixie76Protocol();
virtual void connect();
virtual void connect(const KURL&, const String& protocol);
virtual bool send(const String& message);
virtual unsigned long bufferedAmount() const;
virtual void close();
......@@ -83,14 +83,14 @@ private:
class Peer : public WebSocketChannelClient {
WTF_MAKE_NONCOPYABLE(Peer); WTF_MAKE_FAST_ALLOCATED;
public:
static Peer* create(PassRefPtr<ThreadableWebSocketChannelClientWrapper> clientWrapper, WorkerLoaderProxy& loaderProxy, ScriptExecutionContext* context, const String& taskMode, const KURL& url, const String& protocol)
static Peer* create(PassRefPtr<ThreadableWebSocketChannelClientWrapper> clientWrapper, WorkerLoaderProxy& loaderProxy, ScriptExecutionContext* context, const String& taskMode)
{
return new Peer(clientWrapper, loaderProxy, context, taskMode, url, protocol);
return new Peer(clientWrapper, loaderProxy, context, taskMode);
}
~Peer();
bool useHixie76Protocol();
void connect();
void connect(const KURL&, const String& protocol);
void send(const String& message);
void bufferedAmount();
void close();
......@@ -105,7 +105,7 @@ private:
virtual void didClose(unsigned long unhandledBufferedAmount, ClosingHandshakeCompletionStatus);
private:
Peer(PassRefPtr<ThreadableWebSocketChannelClientWrapper>, WorkerLoaderProxy&, ScriptExecutionContext*, const String& taskMode, const KURL&, const String& protocol);
Peer(PassRefPtr<ThreadableWebSocketChannelClientWrapper>, WorkerLoaderProxy&, ScriptExecutionContext*, const String& taskMode);
RefPtr<ThreadableWebSocketChannelClientWrapper> m_workerClientWrapper;
WorkerLoaderProxy& m_loaderProxy;
......@@ -116,12 +116,12 @@ private:
// Bridge for Peer. Running on the worker thread.
class Bridge : public RefCounted<Bridge> {
public:
static PassRefPtr<Bridge> create(PassRefPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper, PassRefPtr<WorkerContext> workerContext, const String& taskMode, const KURL& url, const String& protocol)
static PassRefPtr<Bridge> create(PassRefPtr<ThreadableWebSocketChannelClientWrapper> workerClientWrapper, PassRefPtr<WorkerContext> workerContext, const String& taskMode)
{
return adoptRef(new Bridge(workerClientWrapper, workerContext, taskMode, url, protocol));
return adoptRef(new Bridge(workerClientWrapper, workerContext, taskMode));
}
~Bridge();
void connect();
void connect(const KURL&, const String& protocol);
bool send(const String& message);
unsigned long bufferedAmount();
void close();
......@@ -134,12 +134,12 @@ private:
using RefCounted<Bridge>::deref;
private:
Bridge(PassRefPtr<ThreadableWebSocketChannelClientWrapper>, PassRefPtr<WorkerContext>, const String& taskMode, const KURL&, const String& protocol);
Bridge(PassRefPtr<ThreadableWebSocketChannelClientWrapper>, PassRefPtr<WorkerContext>, const String& taskMode);
static void setWebSocketChannel(ScriptExecutionContext*, Bridge* thisPtr, Peer*, PassRefPtr<ThreadableWebSocketChannelClientWrapper>, bool useHixie76Protocol);
// Executed on the main thread to create a Peer for this bridge.
static void mainThreadCreateWebSocketChannel(ScriptExecutionContext*, Bridge* thisPtr, PassRefPtr<ThreadableWebSocketChannelClientWrapper>, const String& taskMode, const KURL&, const String& protocol);
static void mainThreadCreateWebSocketChannel(ScriptExecutionContext*, Bridge* thisPtr, PassRefPtr<ThreadableWebSocketChannelClientWrapper>, const String& taskMode);
// Executed on the worker context's thread.
void clearClientWrapper();
......@@ -154,9 +154,9 @@ private:
Peer* m_peer;
};
WorkerThreadableWebSocketChannel(WorkerContext*, WebSocketChannelClient*, const String& taskMode, const KURL&, const String& protocol);
WorkerThreadableWebSocketChannel(WorkerContext*, WebSocketChannelClient*, const String& taskMode);
static void mainThreadConnect(ScriptExecutionContext*, Peer*);
static void mainThreadConnect(ScriptExecutionContext*, Peer*, const KURL&, const String& protocol);
static void mainThreadSend(ScriptExecutionContext*, Peer*, const String& message);
static void mainThreadBufferedAmount(ScriptExecutionContext*, Peer*);
static void mainThreadClose(ScriptExecutionContext*, Peer*);
......
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