[WebSocket] CloseEvent's code and reason properties support.

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

Patch by Takashi Toyoshima <toyoshim@chromium.org> on 2011-08-19
Reviewed by Kent Tamura.

Current WebSocket implementation miss code and reason properties
in CloseEvent. This change expose incoming closing frame's code
and reason to JavaScript API.

Source/WebCore:

Tests: http/tests/websocket/tests/hybi/close-code-and-reason.html
       http/tests/websocket/tests/hybi/workers/close-code-and-reason.html

* websockets/CloseEvent.h:
(WebCore::CloseEvent::initCloseEvent):
(WebCore::CloseEvent::code):
(WebCore::CloseEvent::reason):
(WebCore::CloseEvent::CloseEvent):
* websockets/CloseEvent.idl:
Add code and reason properies.
* websockets/ThreadableWebSocketChannelClientWrapper.cpp:
(WebCore::ThreadableWebSocketChannelClientWrapper::didClose):
(WebCore::ThreadableWebSocketChannelClientWrapper::didCloseCallback):
* websockets/ThreadableWebSocketChannelClientWrapper.h:
* websockets/WebSocket.cpp:
(WebCore::WebSocket::didConnect):
(WebCore::WebSocket::didClose):
* websockets/WebSocket.h:
Add implement to handle code and reason.
* websockets/WebSocketChannel.cpp:
(WebCore::WebSocketChannel::WebSocketChannel):
(WebCore::WebSocketChannel::didCloseSocketStream):
(WebCore::WebSocketChannel::processFrame):
* websockets/WebSocketChannel.h:
Add closing frame payload parser.
* websockets/WebSocketChannelClient.h:
(WebCore::WebSocketChannelClient::didClose):
* websockets/WorkerThreadableWebSocketChannel.cpp:
(WebCore::workerContextDidClose):
(WebCore::WorkerThreadableWebSocketChannel::Peer::didClose):
* websockets/WorkerThreadableWebSocketChannel.h:
Add implement to handle code and reason.

LayoutTests:

* http/tests/websocket/tests/hybi/close-code-and-reason-expected.txt: Added.
* http/tests/websocket/tests/hybi/close-code-and-reason.html: Added.
* http/tests/websocket/tests/hybi/close-code-and-reason_wsh.py: Added.
* http/tests/websocket/tests/hybi/workers/close-code-and-reason-expected.txt: Added.
* http/tests/websocket/tests/hybi/workers/close-code-and-reason.html: Added.
* http/tests/websocket/tests/hybi/workers/resources/close-code-and-reason.js: Added.
(postResult):
(ws.onopen):
(ws.onmessage):
(ws.onclose):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@93393 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent e6e56a6f
2011-08-19 Takashi Toyoshima <toyoshim@chromium.org>
[WebSocket] CloseEvent's code and reason properties support.
https://bugs.webkit.org/show_bug.cgi?id=66362
Reviewed by Kent Tamura.
Current WebSocket implementation miss code and reason properties
in CloseEvent. This change expose incoming closing frame's code
and reason to JavaScript API.
* http/tests/websocket/tests/hybi/close-code-and-reason-expected.txt: Added.
* http/tests/websocket/tests/hybi/close-code-and-reason.html: Added.
* http/tests/websocket/tests/hybi/close-code-and-reason_wsh.py: Added.
* http/tests/websocket/tests/hybi/workers/close-code-and-reason-expected.txt: Added.
* http/tests/websocket/tests/hybi/workers/close-code-and-reason.html: Added.
* http/tests/websocket/tests/hybi/workers/resources/close-code-and-reason.js: Added.
(postResult):
(ws.onopen):
(ws.onmessage):
(ws.onclose):
2011-08-19 MORITA Hajime <morrita@google.com>
Spell-checking doesn't recognize word boundaries on contests inserted by execCommand('insertHTML')
CONSOLE MESSAGE: line 0: WebSocket is closed before the connection is established.
Test CloseEvent code and reason property.
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
ws.onclose() was called.
PASS closeEvent.wasClean is false
PASS closeEvent.code is codeAbnormalClosure
PASS closeEvent.reason is emptyString
WebSocketTest.onopen() was called with testId = 0.
WebSocketTest.onclose() was called with testId = 0.
PASS closeEvent.wasClean is true
PASS closeEvent.code is expectedCode[testId]
PASS closeEvent.reason is expectedReason[testId]
PASS closeEvent.code is expectedCode[testId]
PASS closeEvent.reason is expectedReason[testId]
WebSocketTest.onopen() was called with testId = 1.
WebSocketTest.onclose() was called with testId = 1.
PASS closeEvent.wasClean is true
PASS closeEvent.code is expectedCode[testId]
PASS closeEvent.reason is expectedReason[testId]
PASS closeEvent.code is expectedCode[testId]
PASS closeEvent.reason is expectedReason[testId]
WebSocketTest.onopen() was called with testId = 2.
WebSocketTest.onclose() was called with testId = 2.
PASS closeEvent.wasClean is true
PASS closeEvent.code is expectedCode[testId]
PASS closeEvent.reason is expectedReason[testId]
PASS closeEvent.code is expectedCode[testId]
PASS closeEvent.reason is expectedReason[testId]
PASS successfullyParsed is true
TEST COMPLETE
<!DOCTYPE HTML>
<html>
<head>
<link rel="stylesheet" href="../../../../js-test-resources/js-test-style.css">
<script src="../../../../js-test-resources/js-test-pre.js"></script>
</head>
<body>
<div id="description"></div>
<div id="console"></div>
<script type="text/javascript">
description("Test CloseEvent code and reason property.");
window.jsTestIsAsync = true;
if (window.layoutTestController)
layoutTestController.overridePreference("WebKitHixie76WebSocketProtocolEnabled", 0);
var closeEvent;
var codeNoStatusRcvd = 1005;
var codeAbnormalClosure = 1006;
var emptyString = "";
var ws = new WebSocket("ws://127.0.0.1:8880/websocket/tests/hybi/hanging-handshake");
ws.onopen = function(event)
{
testFailed("ws.onopen() was called. (message = \"" + event.data + "\")");
};
ws.onclose = function(event)
{
debug("ws.onclose() was called.");
closeEvent = event;
shouldBeFalse("closeEvent.wasClean");
shouldBe("closeEvent.code", "codeAbnormalClosure");
shouldBe("closeEvent.reason", "emptyString");
};
ws.close();
var testId = 0;
var testNum = 3;
var sendData = [
"-", // request close frame without code and reason
"--", // request close frame with invalid body which size is 1
"65535 good bye", // request close frame with specified code and reason
];
var expectedCode = [
codeNoStatusRcvd,
codeNoStatusRcvd,
65535,
];
var expectedReason = [
"",
"",
"good bye",
];
WebSocketTest = function() {
this.ws = new WebSocket("ws://127.0.0.1:8880/websocket/tests/hybi/close-code-and-reason");
this.ws.onopen = this.onopen;
this.ws.onmessage = this.onmessage;
this.ws.onclose = this.onclose;
};
WebSocketTest.prototype.onopen = function()
{
debug("WebSocketTest.onopen() was called with testId = " + testId + ".");
this.send(sendData[testId]);
};
WebSocketTest.prototype.onmessage = function(event)
{
testFailed("WebSocketTest.onmessage() was called. (message = \"" + event.data + "\")");
};
WebSocketTest.prototype.onclose = function(event)
{
closeEvent = event;
debug("WebSocketTest.onclose() was called with testId = " + testId + ".");
shouldBeTrue("closeEvent.wasClean");
shouldBe("closeEvent.code", "expectedCode[testId]");
shouldBe("closeEvent.reason", "expectedReason[testId]");
closeEvent.code = 0;
closeEvent.reason = "readonly";
shouldBe("closeEvent.code", "expectedCode[testId]");
shouldBe("closeEvent.reason", "expectedReason[testId]");
testId++;
if (testId < testNum)
test = new WebSocketTest();
else
finishJSTest();
};
var test = new WebSocketTest();
var successfullyParsed = true;
</script>
<script src="../../../../js-test-resources/js-test-post.js"></script>
</body>
</html>
import struct
from mod_pywebsocket import stream
def web_socket_do_extra_handshake(request):
pass
def web_socket_transfer_data(request):
line = request.ws_stream.receive_message()
if line is None:
return
if line == '-':
data = ''
elif line == '--':
data = 'X'
else:
code, reason = line.split(' ', 1)
data = struct.pack('!H', int(code)) + reason.encode('utf-8')
request.connection.write(stream.create_close_frame(data))
CONSOLE MESSAGE: line 0: WebSocket is closed before the connection is established.
Test CloseEvent code and reason property in Worker.
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
ws.onclose() was called.
PASS PASS: worker: event.wasClean is false
PASS PASS: worker: event.code is codeAbnormalClosure
PASS PASS: worker: event.reason is emptyString
WebSocketTest.onopen() was called with testId = 0.
WebSocketTest.onclose() was called with testId = 0.
PASS PASS: worker: event.wasClean is true
PASS PASS: worker: event.code is 1005
PASS PASS: worker: event.reason is
PASS PASS: worker: event.code is 1005
PASS PASS: worker: event.reason is
WebSocketTest.onopen() was called with testId = 1.
WebSocketTest.onclose() was called with testId = 1.
PASS PASS: worker: event.wasClean is true
PASS PASS: worker: event.code is 1005
PASS PASS: worker: event.reason is
PASS PASS: worker: event.code is 1005
PASS PASS: worker: event.reason is
WebSocketTest.onopen() was called with testId = 2.
WebSocketTest.onclose() was called with testId = 2.
PASS PASS: worker: event.wasClean is true
PASS PASS: worker: event.code is 65535
PASS PASS: worker: event.reason is good bye
PASS PASS: worker: event.code is 65535
PASS PASS: worker: event.reason is good bye
DONE
PASS successfullyParsed is true
TEST COMPLETE
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="../../../../../js-test-resources/js-test-style.css">
<script src="../../../../../js-test-resources/js-test-pre.js"></script>
</head>
<body>
<div id="description"></div>
<div id="console"></div>
<script type="text/javascript">
description("Test CloseEvent code and reason property in Worker.");
window.jsTestIsAsync = true;
if (window.layoutTestController)
layoutTestController.overridePreference("WebKitHixie76WebSocketProtocolEnabled", 0);
function startsWith(str, prefix)
{
return str.indexOf(prefix) == 0;
}
var worker = new Worker("resources/close-code-and-reason.js");
worker.onmessage = function (event)
{
var message = event.data;
if (startsWith(message, "PASS"))
testPassed(message);
else if (startsWith(message, "FAIL"))
testFailed(message)
else
debug(message);
if (message === "DONE")
finishJSTest();
};
var successfullyParsed = true;
</script>
<script src="../../../../../js-test-resources/js-test-post.js"></script>
</body>
</html>
var codeNoStatusRcvd = 1005;
var codeAbnormalClosure = 1006;
var emptyString = "";
function postResult(result, actual, expected)
{
var message = result ? "PASS" : "FAIL";
message += ": worker: " + actual + " is ";
if (!result)
message += "not ";
message += expected;
postMessage(message);
}
var ws = new WebSocket("ws://127.0.0.1:8880/websocket/tests/hybi/hanging-handshake");
ws.onopen = function(event)
{
testFailed("FAIL: ws.onopen() was called. (message = \"" + event.data + "\")");
};
ws.onclose = function(event)
{
postMessage("ws.onclose() was called.");
postResult(!event.wasClean, "event.wasClean", "false");
postResult(event.code == codeAbnormalClosure, "event.code", "codeAbnormalClosure");
postResult(event.reason == emptyString, "event.reason", "emptyString");
};
ws.close();
var testId = 0;
var testNum = 3;
var sendData = [
"-", // request close frame without code and reason
"--", // request close frame with invalid body which size is 1
"65535 good bye", // request close frame with specified code and reason
];
var expectedCode = [
codeNoStatusRcvd,
codeNoStatusRcvd,
65535,
];
var expectedReason = [
"",
"",
"good bye",
];
WebSocketTest = function() {
this.ws = new WebSocket("ws://127.0.0.1:8880/websocket/tests/hybi/close-code-and-reason");
this.ws.onopen = this.onopen;
this.ws.onmessage = this.onmessage;
this.ws.onclose = this.onclose;
};
WebSocketTest.prototype.onopen = function()
{
postMessage("WebSocketTest.onopen() was called with testId = " + testId + ".");
this.send(sendData[testId]);
};
WebSocketTest.prototype.onmessage = function(event)
{
postMessage("FAIL: WebSocketTest.onmessage() was called. (message = \"" + event.data + "\")");
};
WebSocketTest.prototype.onclose = function(event)
{
postMessage("WebSocketTest.onclose() was called with testId = " + testId + ".");
postResult(event.wasClean, "event.wasClean", "true");
postResult(event.code == expectedCode[testId], "event.code", expectedCode[testId]);
postResult(event.reason == expectedReason[testId], "event.reason", expectedReason[testId]);
event.code = 0;
event.reason = "readonly";
postResult(event.code == expectedCode[testId], "event.code", expectedCode[testId]);
postResult(event.reason == expectedReason[testId], "event.reason", expectedReason[testId]);
testId++;
if (testId < testNum)
test = new WebSocketTest();
else
postMessage("DONE")
};
var test = new WebSocketTest();
2011-08-19 Takashi Toyoshima <toyoshim@chromium.org>
[WebSocket] CloseEvent's code and reason properties support.
https://bugs.webkit.org/show_bug.cgi?id=66362
Reviewed by Kent Tamura.
Current WebSocket implementation miss code and reason properties
in CloseEvent. This change expose incoming closing frame's code
and reason to JavaScript API.
Tests: http/tests/websocket/tests/hybi/close-code-and-reason.html
http/tests/websocket/tests/hybi/workers/close-code-and-reason.html
* websockets/CloseEvent.h:
(WebCore::CloseEvent::initCloseEvent):
(WebCore::CloseEvent::code):
(WebCore::CloseEvent::reason):
(WebCore::CloseEvent::CloseEvent):
* websockets/CloseEvent.idl:
Add code and reason properies.
* websockets/ThreadableWebSocketChannelClientWrapper.cpp:
(WebCore::ThreadableWebSocketChannelClientWrapper::didClose):
(WebCore::ThreadableWebSocketChannelClientWrapper::didCloseCallback):
* websockets/ThreadableWebSocketChannelClientWrapper.h:
* websockets/WebSocket.cpp:
(WebCore::WebSocket::didConnect):
(WebCore::WebSocket::didClose):
* websockets/WebSocket.h:
Add implement to handle code and reason.
* websockets/WebSocketChannel.cpp:
(WebCore::WebSocketChannel::WebSocketChannel):
(WebCore::WebSocketChannel::didCloseSocketStream):
(WebCore::WebSocketChannel::processFrame):
* websockets/WebSocketChannel.h:
Add closing frame payload parser.
* websockets/WebSocketChannelClient.h:
(WebCore::WebSocketChannelClient::didClose):
* websockets/WorkerThreadableWebSocketChannel.cpp:
(WebCore::workerContextDidClose):
(WebCore::WorkerThreadableWebSocketChannel::Peer::didClose):
* websockets/WorkerThreadableWebSocketChannel.h:
Add implement to handle code and reason.
2011-08-19 MORITA Hajime <morrita@google.com>
Spell-checking doesn't recognize word boundaries on contests inserted by execCommand('insertHTML')
......@@ -45,7 +45,7 @@ public:
return adoptRef(new CloseEvent());
}
void initCloseEvent(const AtomicString& type, bool canBubble, bool cancelable, bool wasClean)
void initCloseEvent(const AtomicString& type, bool canBubble, bool cancelable, bool wasClean, unsigned short code, const String& reason)
{
if (dispatched())
return;
......@@ -53,17 +53,24 @@ public:
initEvent(type, canBubble, cancelable);
m_wasClean = wasClean;
m_code = code;
m_reason = reason;
}
bool wasClean() const { return m_wasClean; }
unsigned short code() const { return m_code; }
String reason() const { return m_reason; }
private:
CloseEvent()
: Event(eventNames().closeEvent, false, false)
, m_wasClean(false)
, m_code(0)
{ }
bool m_wasClean;
unsigned short m_code;
String m_reason;
};
} // namespace WebCore
......
......@@ -34,10 +34,14 @@ module events {
NoStaticTables
] CloseEvent : Event {
readonly attribute boolean wasClean;
readonly attribute unsigned short code;
readonly attribute [ConvertingNullStringTo=Undefined] DOMString reason;
void initCloseEvent(in [Optional=CallWithDefaultValue] DOMString typeArg,
in [Optional=CallWithDefaultValue] boolean canBubbleArg,
in [Optional=CallWithDefaultValue] boolean cancelableArg,
in [Optional=CallWithDefaultValue] boolean wasCleanArg);
in [Optional=CallWithDefaultValue] boolean wasCleanArg,
in [Optional=CallWithDefaultValue] unsigned short codeArg,
in [Optional=CallWithDefaultValue] DOMString reasonArg);
};
}
......@@ -139,9 +139,9 @@ void ThreadableWebSocketChannelClientWrapper::didStartClosingHandshake()
processPendingTasks();
}
void ThreadableWebSocketChannelClientWrapper::didClose(unsigned long unhandledBufferedAmount, WebSocketChannelClient::ClosingHandshakeCompletionStatus closingHandshakeCompletion)
void ThreadableWebSocketChannelClientWrapper::didClose(unsigned long unhandledBufferedAmount, WebSocketChannelClient::ClosingHandshakeCompletionStatus closingHandshakeCompletion, unsigned short code, const String& reason)
{
m_pendingTasks.append(createCallbackTask(&ThreadableWebSocketChannelClientWrapper::didCloseCallback, AllowCrossThreadAccess(this), unhandledBufferedAmount, closingHandshakeCompletion));
m_pendingTasks.append(createCallbackTask(&ThreadableWebSocketChannelClientWrapper::didCloseCallback, AllowCrossThreadAccess(this), unhandledBufferedAmount, closingHandshakeCompletion, code, reason));
if (!m_suspended)
processPendingTasks();
}
......@@ -187,11 +187,11 @@ void ThreadableWebSocketChannelClientWrapper::didStartClosingHandshakeCallback(S
wrapper->m_client->didStartClosingHandshake();
}
void ThreadableWebSocketChannelClientWrapper::didCloseCallback(ScriptExecutionContext* context, ThreadableWebSocketChannelClientWrapper* wrapper, unsigned long unhandledBufferedAmount, WebSocketChannelClient::ClosingHandshakeCompletionStatus closingHandshakeCompletion)
void ThreadableWebSocketChannelClientWrapper::didCloseCallback(ScriptExecutionContext* context, ThreadableWebSocketChannelClientWrapper* wrapper, unsigned long unhandledBufferedAmount, WebSocketChannelClient::ClosingHandshakeCompletionStatus closingHandshakeCompletion, unsigned short code, const String& reason)
{
ASSERT_UNUSED(context, !context);
if (wrapper->m_client)
wrapper->m_client->didClose(unhandledBufferedAmount, closingHandshakeCompletion);
wrapper->m_client->didClose(unhandledBufferedAmount, closingHandshakeCompletion, code, reason);
}
} // namespace WebCore
......
......@@ -73,7 +73,7 @@ public:
void didConnect();
void didReceiveMessage(const String& message);
void didStartClosingHandshake();
void didClose(unsigned long unhandledBufferedAmount, WebSocketChannelClient::ClosingHandshakeCompletionStatus);
void didClose(unsigned long unhandledBufferedAmount, WebSocketChannelClient::ClosingHandshakeCompletionStatus, unsigned short code, const String& reason);
void suspend();
void resume();
......@@ -85,7 +85,7 @@ protected:
static void didConnectCallback(ScriptExecutionContext*, ThreadableWebSocketChannelClientWrapper*);
static void didReceiveMessageCallback(ScriptExecutionContext*, ThreadableWebSocketChannelClientWrapper*, const String& message);
static void didStartClosingHandshakeCallback(ScriptExecutionContext*, ThreadableWebSocketChannelClientWrapper*);
static void didCloseCallback(ScriptExecutionContext*, ThreadableWebSocketChannelClientWrapper*, unsigned long unhandledBufferedAmount, WebSocketChannelClient::ClosingHandshakeCompletionStatus);
static void didCloseCallback(ScriptExecutionContext*, ThreadableWebSocketChannelClientWrapper*, unsigned long unhandledBufferedAmount, WebSocketChannelClient::ClosingHandshakeCompletionStatus, unsigned short code, const String& reason);
WebSocketChannelClient* m_client;
bool m_syncMethodDone;
......
......@@ -378,7 +378,7 @@ void WebSocket::didConnect()
{
LOG(Network, "WebSocket %p didConnect", this);
if (m_state != CONNECTING) {
didClose(0, ClosingHandshakeIncomplete);
didClose(0, ClosingHandshakeIncomplete, WebSocketChannel::CloseEventCodeAbnormalClosure, "");
return;
}
ASSERT(scriptExecutionContext());
......@@ -413,7 +413,7 @@ void WebSocket::didStartClosingHandshake()
m_state = CLOSING;
}
void WebSocket::didClose(unsigned long unhandledBufferedAmount, ClosingHandshakeCompletionStatus closingHandshakeCompletion)
void WebSocket::didClose(unsigned long unhandledBufferedAmount, ClosingHandshakeCompletionStatus closingHandshakeCompletion, unsigned short code, const String& reason)
{
LOG(Network, "WebSocket %p didClose", this);
if (!m_channel)
......@@ -423,7 +423,7 @@ void WebSocket::didClose(unsigned long unhandledBufferedAmount, ClosingHandshake
m_bufferedAmountAfterClose += unhandledBufferedAmount;
ASSERT(scriptExecutionContext());
RefPtr<CloseEvent> event = CloseEvent::create();
event->initCloseEvent(eventNames().closeEvent, false, false, wasClean);
event->initCloseEvent(eventNames().closeEvent, false, false, wasClean, code, reason);
dispatchEvent(event);
if (m_channel) {
m_channel->disconnect();
......
......@@ -102,7 +102,7 @@ namespace WebCore {
virtual void didReceiveMessage(const String& message);
virtual void didReceiveMessageError();
virtual void didStartClosingHandshake();
virtual void didClose(unsigned long unhandledBufferedAmount, ClosingHandshakeCompletionStatus);
virtual void didClose(unsigned long unhandledBufferedAmount, ClosingHandshakeCompletionStatus, unsigned short code, const String& reason);
private:
WebSocket(ScriptExecutionContext*);
......
......@@ -98,6 +98,7 @@ WebSocketChannel::WebSocketChannel(ScriptExecutionContext* context, WebSocketCha
, m_identifier(0)
, m_useHixie76Protocol(true)
, m_hasContinuousFrame(false)
, m_closeEventCode(CloseEventCodeAbnormalClosure)
{
ASSERT(m_context->isDocument());
Document* document = static_cast<Document*>(m_context);
......@@ -246,7 +247,7 @@ void WebSocketChannel::didCloseSocketStream(SocketStreamHandle* handle)
m_context = 0;
m_handle = 0;
if (client)
client->didClose(m_unhandledBufferedAmount, m_receivedClosingHandshake ? WebSocketChannelClient::ClosingHandshakeComplete : WebSocketChannelClient::ClosingHandshakeIncomplete);
client->didClose(m_unhandledBufferedAmount, m_receivedClosingHandshake ? WebSocketChannelClient::ClosingHandshakeComplete : WebSocketChannelClient::ClosingHandshakeIncomplete, m_closeEventCode, m_closeEventReason);
}
deref();
}
......@@ -623,7 +624,16 @@ bool WebSocketChannel::processFrame()
break;
case OpCodeClose:
// FIXME: Handle payload.
if (frame.payloadLength >= 2) {
unsigned char highByte = static_cast<unsigned char>(frame.payload[0]);
unsigned char lowByte = static_cast<unsigned char>(frame.payload[1]);
m_closeEventCode = highByte << 8 | lowByte;
} else
m_closeEventCode = CloseEventCodeNoStatusRcvd;
if (frame.payloadLength >= 3)
m_closeEventReason = String::fromUTF8(&frame.payload[2], frame.payloadLength - 2);
else
m_closeEventReason = "";
skipBuffer(frame.frameEnd - m_buffer);
m_receivedClosingHandshake = true;
startClosingHandshake();
......
......@@ -74,6 +74,17 @@ namespace WebCore {
virtual void didReceiveAuthenticationChallenge(SocketStreamHandle*, const AuthenticationChallenge&);
virtual void didCancelAuthenticationChallenge(SocketStreamHandle*, const AuthenticationChallenge&);
enum CloseEventCode {
CloseEventCodeNormalClosure = 1000,
CloseEventCodeGoingAway = 1001,
CloseEventCodeProtocolError = 1002,
CloseEventCodeUnsupportedData = 1003,
CloseEventCodeFrameTooLarge = 1004,
CloseEventCodeNoStatusRcvd = 1005,
CloseEventCodeAbnormalClosure = 1006,
CloseEventCodeInvalidUTF8 = 1007
};
using RefCounted<WebSocketChannel>::ref;
using RefCounted<WebSocketChannel>::deref;
......@@ -154,6 +165,8 @@ namespace WebCore {
bool m_hasContinuousFrame;
OpCode m_continuousFrameOpCode;
Vector<char> m_continuousFrameData;
unsigned short m_closeEventCode;
String m_closeEventReason;
};
} // namespace WebCore
......
/*
* Copyright (C) 2009 Google Inc. All rights reserved.
* Copyright (C) 2011 Google Inc. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
......@@ -46,7 +46,7 @@ namespace WebCore {
ClosingHandshakeIncomplete,
ClosingHandshakeComplete
};
virtual void didClose(unsigned long /* unhandledBufferedAmount */, ClosingHandshakeCompletionStatus) { }
virtual void didClose(unsigned long /* unhandledBufferedAmount */, ClosingHandshakeCompletionStatus, unsigned short /* code */, const String& /* reason */) { }
protected:
WebSocketChannelClient() { }
......