Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(268)

Unified Diff: sdk/lib/io/websocket_impl.dart

Issue 13686005: WebSocket: Correctly expect masked frames from clients, and send masked frames from the client. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « sdk/lib/io/http_session.dart ('k') | tests/standalone/io/web_socket_protocol_processor_test.dart » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: sdk/lib/io/websocket_impl.dart
diff --git a/sdk/lib/io/websocket_impl.dart b/sdk/lib/io/websocket_impl.dart
index fcbe1ca857dce9f701f2e80bd50c43847917df4a..2d29a5f658dd1c0dee32a68a58f14b5a3840ba23 100644
--- a/sdk/lib/io/websocket_impl.dart
+++ b/sdk/lib/io/websocket_impl.dart
@@ -50,7 +50,9 @@ class _WebSocketProtocolTransformer extends StreamEventTransformer {
static const int CLOSED = 5;
static const int FAILURE = 6;
- _WebSocketProtocolTransformer() {
+ bool _serverSide;
+
+ _WebSocketProtocolTransformer([bool this._serverSide = false]) {
_prepareForNextFrame();
_currentMessageType = _WebSocketMessageType.NONE;
}
@@ -223,9 +225,15 @@ class _WebSocketProtocolTransformer extends StreamEventTransformer {
void _lengthDone(EventSink sink) {
if (_masked) {
+ if (!_serverSide) {
+ throw new WebSocketException("Received masked frame from server");
+ }
_state = MASK;
_remainingMaskingKeyBytes = 4;
} else {
+ if (_serverSide) {
+ throw new WebSocketException("Received unmasked frame from client");
+ }
_remainingPayloadBytes = _len;
_startPayload(sink);
}
@@ -392,7 +400,7 @@ class _WebSocketTransformerImpl implements WebSocketTransformer {
response.headers.add("Sec-WebSocket-Accept", accept);
response.headers.contentLength = 0;
return response.detachSocket()
- .then((socket) => new _WebSocketImpl._fromSocket(socket));
+ .then((socket) => new _WebSocketImpl._fromSocket(socket, true));
}
static bool _isUpgradeRequest(HttpRequest request) {
@@ -428,6 +436,7 @@ class _WebSocketImpl extends Stream implements WebSocket {
final StreamController _controller = new StreamController();
final Socket _socket;
+ final bool _serverSide;
int _readyState = WebSocket.CONNECTING;
bool _writeClosed = false;
int _closeCode;
@@ -505,11 +514,12 @@ class _WebSocketImpl extends Stream implements WebSocket {
});
}
- _WebSocketImpl._fromSocket(Socket this._socket) {
+ _WebSocketImpl._fromSocket(Socket this._socket,
+ [bool this._serverSide = false]) {
_readyState = WebSocket.OPEN;
bool closed = false;
- var transformer = new _WebSocketProtocolTransformer();
+ var transformer = new _WebSocketProtocolTransformer(_serverSide);
_socket.transform(transformer).listen(
(data) {
_controller.add(data);
@@ -631,7 +641,7 @@ class _WebSocketImpl extends Stream implements WebSocket {
void _sendFrame(int opcode, [List<int> data]) {
if (_writeClosed) return;
- bool mask = false; // Masking not implemented for server.
+ bool mask = !_serverSide; // Masking not implemented for server.
int dataLength = data == null ? 0 : data.length;
// Determine the header size.
int headerSize = (mask) ? 6 : 2;
@@ -658,6 +668,19 @@ class _WebSocketImpl extends Stream implements WebSocket {
for (int i = 0; i < lengthBytes; i++) {
header[index++] = dataLength >> (((lengthBytes - 1) - i) * 8) & 0xFF;
}
+ if (mask) {
+ header[1] |= 1 << 7;
+ var maskBytes = _IOCrypto.getRandomBytes(4);
+ header.setRange(index, 4, maskBytes);
+ index += 4;
+ if (data != null) {
+ var list = new Uint8List(data.length);
+ for (int i = 0; i < data.length; i++) {
+ list[i] = data[i] ^ maskBytes[i % 4];
+ }
+ data = list;
+ }
+ }
assert(index == headerSize);
try {
_socket.writeBytes(header);
« no previous file with comments | « sdk/lib/io/http_session.dart ('k') | tests/standalone/io/web_socket_protocol_processor_test.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698