summaryrefslogtreecommitdiffstats
path: root/WebCore/websockets
diff options
context:
space:
mode:
Diffstat (limited to 'WebCore/websockets')
-rw-r--r--WebCore/websockets/WebSocket.cpp52
-rw-r--r--WebCore/websockets/WebSocketChannel.cpp52
-rw-r--r--WebCore/websockets/WebSocketChannel.h17
-rw-r--r--WebCore/websockets/WebSocketHandshake.cpp15
4 files changed, 64 insertions, 72 deletions
diff --git a/WebCore/websockets/WebSocket.cpp b/WebCore/websockets/WebSocket.cpp
index 32e0559..ee78174 100644
--- a/WebCore/websockets/WebSocket.cpp
+++ b/WebCore/websockets/WebSocket.cpp
@@ -43,35 +43,11 @@
#include "Logging.h"
#include "MessageEvent.h"
#include "ScriptExecutionContext.h"
-#include "SecurityOrigin.h"
#include "WebSocketChannel.h"
#include <wtf/StdLibExtras.h>
namespace WebCore {
-class ProcessWebSocketEventTask : public ScriptExecutionContext::Task {
-public:
- typedef void (WebSocket::*Method)(Event*);
- static PassRefPtr<ProcessWebSocketEventTask> create(PassRefPtr<WebSocket> webSocket, PassRefPtr<Event> event)
- {
- return adoptRef(new ProcessWebSocketEventTask(webSocket, event));
- }
- virtual void performTask(ScriptExecutionContext*)
- {
- ExceptionCode ec = 0;
- m_webSocket->dispatchEvent(m_event.get(), ec);
- ASSERT(!ec);
- }
-
- private:
- ProcessWebSocketEventTask(PassRefPtr<WebSocket> webSocket, PassRefPtr<Event> event)
- : m_webSocket(webSocket)
- , m_event(event) { }
-
- RefPtr<WebSocket> m_webSocket;
- RefPtr<Event> m_event;
-};
-
static bool isValidProtocolString(const WebCore::String& protocol)
{
if (protocol.isNull())
@@ -80,7 +56,7 @@ static bool isValidProtocolString(const WebCore::String& protocol)
return false;
const UChar* characters = protocol.characters();
for (size_t i = 0; i < protocol.length(); i++) {
- if (characters[i] < 0x21 || characters[i] > 0x7E)
+ if (characters[i] < 0x20 || characters[i] > 0x7E)
return false;
}
return true;
@@ -110,7 +86,7 @@ WebSocket::WebSocket(ScriptExecutionContext* context)
WebSocket::~WebSocket()
{
- if (m_channel.get())
+ if (m_channel)
m_channel->disconnect();
}
@@ -126,18 +102,29 @@ void WebSocket::connect(const KURL& url, const String& protocol, ExceptionCode&
m_protocol = protocol;
if (!m_url.protocolIs("ws") && !m_url.protocolIs("wss")) {
- LOG_ERROR("Error: wrong url for WebSocket %s", url.string().utf8().data());
+ LOG(Network, "Wrong url scheme for WebSocket %s", url.string().utf8().data());
+ m_state = CLOSED;
+ ec = SYNTAX_ERR;
+ return;
+ }
+ if (m_url.hasFragmentIdentifier()) {
+ LOG(Network, "URL has fragment component %s", url.string().utf8().data());
m_state = CLOSED;
ec = SYNTAX_ERR;
return;
}
if (!isValidProtocolString(m_protocol)) {
- LOG_ERROR("Error: wrong protocol for WebSocket %s", m_protocol.utf8().data());
+ LOG(Network, "Wrong protocol for WebSocket %s", m_protocol.utf8().data());
m_state = CLOSED;
ec = SYNTAX_ERR;
return;
}
- // FIXME: if m_url.port() is blocking port, raise SECURITY_ERR.
+ if (!portAllowed(url)) {
+ LOG(Network, "WebSocket port %d blocked", url.port());
+ m_state = CLOSED;
+ ec = SECURITY_ERR;
+ return;
+ }
m_channel = WebSocketChannel::create(scriptExecutionContext(), this, m_url, m_protocol);
m_channel->connect();
@@ -196,7 +183,7 @@ void WebSocket::didConnect()
return;
}
m_state = OPEN;
- scriptExecutionContext()->postTask(ProcessWebSocketEventTask::create(this, Event::create(eventNames().openEvent, false, false)));
+ dispatchEvent(Event::create(eventNames().openEvent, false, false));
}
void WebSocket::didReceiveMessage(const String& msg)
@@ -207,15 +194,14 @@ void WebSocket::didReceiveMessage(const String& msg)
RefPtr<MessageEvent> evt = MessageEvent::create();
// FIXME: origin, lastEventId, source, messagePort.
evt->initMessageEvent(eventNames().messageEvent, false, false, SerializedScriptValue::create(msg), "", "", 0, 0);
- scriptExecutionContext()->postTask(ProcessWebSocketEventTask::create(this, evt));
+ dispatchEvent(evt);
}
void WebSocket::didClose()
{
LOG(Network, "WebSocket %p didClose", this);
m_state = CLOSED;
- if (scriptExecutionContext())
- scriptExecutionContext()->postTask(ProcessWebSocketEventTask::create(this, Event::create(eventNames().closeEvent, false, false)));
+ dispatchEvent(Event::create(eventNames().closeEvent, false, false));
}
EventTargetData* WebSocket::eventTargetData()
diff --git a/WebCore/websockets/WebSocketChannel.cpp b/WebCore/websockets/WebSocketChannel.cpp
index be388b4..a222b4d 100644
--- a/WebCore/websockets/WebSocketChannel.cpp
+++ b/WebCore/websockets/WebSocketChannel.cpp
@@ -69,7 +69,7 @@ WebSocketChannel::~WebSocketChannel()
void WebSocketChannel::connect()
{
LOG(Network, "WebSocketChannel %p connect", this);
- ASSERT(!m_handle.get());
+ ASSERT(!m_handle);
m_handshake.reset();
ref();
m_handle = SocketStreamHandle::create(m_handshake.url(), this);
@@ -82,7 +82,7 @@ bool WebSocketChannel::send(const String& msg)
buf.append('\0'); // frame type
buf.append(msg.utf8().data(), msg.utf8().length());
buf.append('\xff'); // frame end
- if (!m_handle.get()) {
+ if (!m_handle) {
m_unhandledBufferSize += buf.size();
return false;
}
@@ -92,7 +92,7 @@ bool WebSocketChannel::send(const String& msg)
unsigned long WebSocketChannel::bufferedAmount() const
{
LOG(Network, "WebSocketChannel %p bufferedAmount", this);
- if (!m_handle.get())
+ if (!m_handle)
return m_unhandledBufferSize;
return m_handle->bufferedAmount();
}
@@ -100,7 +100,7 @@ unsigned long WebSocketChannel::bufferedAmount() const
void WebSocketChannel::close()
{
LOG(Network, "WebSocketChannel %p close", this);
- if (m_handle.get())
+ if (m_handle)
m_handle->close(); // will call didClose()
}
@@ -108,22 +108,14 @@ void WebSocketChannel::disconnect()
{
LOG(Network, "WebSocketChannel %p disconnect", this);
m_client = 0;
- if (m_handle.get())
+ if (m_handle)
m_handle->close();
}
-void WebSocketChannel::willOpenStream(SocketStreamHandle*, const KURL&)
-{
-}
-
-void WebSocketChannel::willSendData(SocketStreamHandle*, const char*, int)
-{
-}
-
void WebSocketChannel::didOpen(SocketStreamHandle* handle)
{
LOG(Network, "WebSocketChannel %p didOpen", this);
- ASSERT(handle == m_handle.get());
+ ASSERT(handle == m_handle);
const CString& handshakeMessage = m_handshake.clientHandshakeMessage();
if (!handle->send(handshakeMessage.data(), handshakeMessage.length())) {
LOG(Network, "Error in sending handshake message.");
@@ -134,8 +126,8 @@ void WebSocketChannel::didOpen(SocketStreamHandle* handle)
void WebSocketChannel::didClose(SocketStreamHandle* handle)
{
LOG(Network, "WebSocketChannel %p didClose", this);
- ASSERT(handle == m_handle.get() || !m_handle.get());
- if (m_handle.get()) {
+ ASSERT(handle == m_handle || !m_handle);
+ if (m_handle) {
m_unhandledBufferSize = handle->bufferedAmount();
WebSocketChannelClient* client = m_client;
m_client = 0;
@@ -149,7 +141,7 @@ void WebSocketChannel::didClose(SocketStreamHandle* handle)
void WebSocketChannel::didReceiveData(SocketStreamHandle* handle, const char* data, int len)
{
LOG(Network, "WebSocketChannel %p didReceiveData %d", this, len);
- ASSERT(handle == m_handle.get());
+ ASSERT(handle == m_handle);
if (!appendToBuffer(data, len)) {
handle->close();
return;
@@ -167,8 +159,10 @@ void WebSocketChannel::didReceiveData(SocketStreamHandle* handle, const char* da
if (!m_handshake.serverSetCookie().isEmpty()) {
if (m_context->isDocument()) {
Document* document = static_cast<Document*>(m_context);
- if (cookiesEnabled(document))
- document->setCookie(m_handshake.serverSetCookie());
+ if (cookiesEnabled(document)) {
+ ExceptionCode ec; // Exception (for sandboxed documents) ignored.
+ document->setCookie(m_handshake.serverSetCookie(), ec);
+ }
}
}
// FIXME: handle set-cookie2.
@@ -193,19 +187,23 @@ void WebSocketChannel::didReceiveData(SocketStreamHandle* handle, const char* da
unsigned char frameByte = static_cast<unsigned char>(*p++);
if ((frameByte & 0x80) == 0x80) {
int length = 0;
- while (p < end && (*p & 0x80) == 0x80) {
+ while (p < end) {
if (length > std::numeric_limits<int>::max() / 128) {
LOG(Network, "frame length overflow %d", length);
handle->close();
return;
}
- length = length * 128 + (*p & 0x7f);
+ char msgByte = *p;
+ length = length * 128 + (msgByte & 0x7f);
++p;
+ if (!(msgByte & 0x80))
+ break;
}
if (p + length < end) {
p += length;
nextFrame = p;
- }
+ } else
+ break;
} else {
const char* msgStart = p;
while (p < end && *p != '\xff')
@@ -224,10 +222,18 @@ void WebSocketChannel::didReceiveData(SocketStreamHandle* handle, const char* da
void WebSocketChannel::didFail(SocketStreamHandle* handle, const SocketStreamError&)
{
LOG(Network, "WebSocketChannel %p didFail", this);
- ASSERT(handle == m_handle.get() || !m_handle.get());
+ ASSERT(handle == m_handle || !m_handle);
handle->close();
}
+void WebSocketChannel::didReceiveAuthenticationChallenge(SocketStreamHandle*, const AuthenticationChallenge&)
+{
+}
+
+void WebSocketChannel::didCancelAuthenticationChallenge(SocketStreamHandle*, const AuthenticationChallenge&)
+{
+}
+
bool WebSocketChannel::appendToBuffer(const char* data, int len)
{
char* newBuffer = 0;
diff --git a/WebCore/websockets/WebSocketChannel.h b/WebCore/websockets/WebSocketChannel.h
index ad38163..14b1e8c 100644
--- a/WebCore/websockets/WebSocketChannel.h
+++ b/WebCore/websockets/WebSocketChannel.h
@@ -50,21 +50,18 @@ namespace WebCore {
static PassRefPtr<WebSocketChannel> create(ScriptExecutionContext* context, WebSocketChannelClient* client, const KURL& url, const String& protocol) { return adoptRef(new WebSocketChannel(context, client, url, protocol)); }
virtual ~WebSocketChannel();
- virtual void connect();
+ void connect();
+ bool send(const String& msg);
+ unsigned long bufferedAmount() const;
+ void close();
+ void disconnect(); // Will suppress didClose().
- virtual bool send(const String& msg);
- virtual unsigned long bufferedAmount() const;
-
- virtual void close();
-
- virtual void disconnect();
-
- virtual void willOpenStream(SocketStreamHandle*, const KURL&);
- virtual void willSendData(SocketStreamHandle*, const char*, int);
virtual void didOpen(SocketStreamHandle*);
virtual void didClose(SocketStreamHandle*);
virtual void didReceiveData(SocketStreamHandle*, const char*, int);
virtual void didFail(SocketStreamHandle*, const SocketStreamError&);
+ virtual void didReceiveAuthenticationChallenge(SocketStreamHandle*, const AuthenticationChallenge&);
+ virtual void didCancelAuthenticationChallenge(SocketStreamHandle*, const AuthenticationChallenge&);
private:
WebSocketChannel(ScriptExecutionContext*, WebSocketChannelClient*, const KURL&, const String&);
diff --git a/WebCore/websockets/WebSocketHandshake.cpp b/WebCore/websockets/WebSocketHandshake.cpp
index 691fa1c..d1da443 100644
--- a/WebCore/websockets/WebSocketHandshake.cpp
+++ b/WebCore/websockets/WebSocketHandshake.cpp
@@ -74,6 +74,13 @@ static String extractResponseCode(const char* header, int len)
return String(space1 + 1, space2 - space1 - 1);
}
+static String resourceName(const KURL& url)
+{
+ if (url.query().isNull())
+ return url.path();
+ return url.path() + "?" + url.query();
+}
+
WebSocketHandshake::WebSocketHandshake(const KURL& url, const String& protocol, ScriptExecutionContext* context)
: m_url(url)
, m_clientProtocol(protocol)
@@ -139,7 +146,7 @@ String WebSocketHandshake::clientLocation() const
builder.append(String::number(m_url.port()));
}
}
- builder.append(m_url.path());
+ builder.append(resourceName(m_url));
return builder.toString();
}
@@ -148,11 +155,7 @@ CString WebSocketHandshake::clientHandshakeMessage() const
StringBuilder builder;
builder.append("GET ");
- builder.append(m_url.path());
- if (!m_url.query().isEmpty()) {
- builder.append("?");
- builder.append(m_url.query());
- }
+ builder.append(resourceName(m_url));
builder.append(" HTTP/1.1\r\n");
builder.append("Upgrade: WebSocket\r\n");
builder.append("Connection: Upgrade\r\n");