From ee22f7595905a1545b0e316257bb2368b07bcef5 Mon Sep 17 00:00:00 2001 From: James Coglan Date: Sat, 22 Dec 2012 23:13:04 +0000 Subject: [PATCH] Remove trailing whitespace. --- examples/autobahn_client.js | 10 +- examples/server.js | 16 +-- examples/sse.html | 16 +-- examples/ws.html | 16 +-- lib/faye/eventsource.js | 38 +++---- lib/faye/websocket.js | 20 ++-- lib/faye/websocket/api.js | 20 ++-- lib/faye/websocket/api/event.js | 4 +- lib/faye/websocket/api/event_target.js | 16 +-- lib/faye/websocket/client.js | 26 ++--- lib/faye/websocket/draft75_parser.js | 24 ++-- lib/faye/websocket/draft76_parser.js | 24 ++-- lib/faye/websocket/hybi_parser.js | 104 +++++++++--------- lib/faye/websocket/hybi_parser/handshake.js | 26 ++--- .../websocket/hybi_parser/stream_reader.js | 10 +- spec/faye/websocket/client_spec.js | 60 +++++----- spec/faye/websocket/draft75parser_spec.js | 24 ++-- spec/faye/websocket/draft76parser_spec.js | 8 +- spec/faye/websocket/hybi_parser_spec.js | 52 ++++----- spec/runner.js | 4 +- 20 files changed, 259 insertions(+), 259 deletions(-) diff --git a/examples/autobahn_client.js b/examples/autobahn_client.js index c152b74..47034dc 100644 --- a/examples/autobahn_client.js +++ b/examples/autobahn_client.js @@ -17,24 +17,24 @@ socket.onclose = function() { if (n > cases) { socket = new WebSocket.Client(host + '/updateReports?agent=' + encodeURIComponent(agent)); socket.onclose = process.exit - + } else if (skip.indexOf(n) >= 0) { runCase(n + 1); - + } else { console.log('Running test case #' + n + ' ...'); socket = new WebSocket.Client(host + '/runCase?case=' + n + '&agent=' + encodeURIComponent(agent)); - + socket.onmessage = function(event) { socket.send(event.data); }; - + socket.onclose = function() { runCase(n + 1); }; } }; - + runCase(1); }; diff --git a/examples/server.js b/examples/server.js index 5d08277..cb54715 100644 --- a/examples/server.js +++ b/examples/server.js @@ -9,11 +9,11 @@ var port = process.argv[2] || 7000, var upgradeHandler = function(request, socket, head) { var ws = new WebSocket(request, socket, head, ['irc', 'xmpp'], {ping: 5}); console.log('open', ws.url, ws.version, ws.protocol); - + ws.onmessage = function(event) { ws.send(event.data); }; - + ws.onclose = function(event) { console.log('close', event.code, event.reason); ws = null; @@ -23,12 +23,12 @@ var upgradeHandler = function(request, socket, head) { var requestHandler = function(request, response) { if (!WebSocket.EventSource.isEventSource(request)) return staticHandler(request, response); - + var es = new WebSocket.EventSource(request, response), time = parseInt(es.lastEventId, 10) || 0; - + console.log('open', es.url, es.lastEventId); - + var loop = setInterval(function() { time += 1; es.send('Time: ' + time); @@ -36,9 +36,9 @@ var requestHandler = function(request, response) { if (es) es.send('Update!!', {event: 'update', id: time}); }, 1000); }, 2000); - + es.send('Welcome!\n\nThis is an EventSource server.'); - + es.onclose = function() { clearInterval(loop); console.log('close', es.url); @@ -48,7 +48,7 @@ var requestHandler = function(request, response) { var staticHandler = function(request, response) { var path = request.url; - + fs.readFile(__dirname + path, function(err, content) { var status = err ? 404 : 200; response.writeHead(status, {'Content-Type': 'text/html'}); diff --git a/examples/sse.html b/examples/sse.html index 7d40760..2afa273 100644 --- a/examples/sse.html +++ b/examples/sse.html @@ -5,35 +5,35 @@ EventSource test - +

EventSource test

- + - + diff --git a/examples/ws.html b/examples/ws.html index c7dabca..e322f2a 100644 --- a/examples/ws.html +++ b/examples/ws.html @@ -5,40 +5,40 @@ WebSocket test - +

WebSocket test

- + - + diff --git a/lib/faye/eventsource.js b/lib/faye/eventsource.js index b2039a6..eab3a46 100644 --- a/lib/faye/eventsource.js +++ b/lib/faye/eventsource.js @@ -12,42 +12,42 @@ var isSecureConnection = function(request) { var EventSource = function(request, response, options) { options = options || {}; - + this._request = request; this._response = response; this._stream = response.socket; this._ping = options.ping || this.DEFAULT_PING; this._retry = options.retry || this.DEFAULT_RETRY; - + var scheme = isSecureConnection(request) ? 'https:' : 'http:'; this.url = scheme + '//' + request.headers.host + request.url; - + this.lastEventId = request.headers['last-event-id'] || ''; - + var self = this; this.readyState = API.CONNECTING; this._sendBuffer = []; process.nextTick(function() { self._open() }); - + var handshake = 'HTTP/1.1 200 OK\r\n' + 'Content-Type: text/event-stream\r\n' + 'Cache-Control: no-cache, no-store\r\n' + 'Connection: close\r\n' + '\r\n\r\n' + 'retry: ' + Math.floor(this._retry * 1000) + '\r\n\r\n'; - + this.readyState = API.OPEN; - + if (this._ping) this._pingLoop = setInterval(function() { self.ping() }, this._ping * 1000); - + if (!this._stream || !this._stream.writable) return; - + this._stream.setTimeout(0); this._stream.setNoDelay(true); - + try { this._stream.write(handshake, 'utf8') } catch (e) {} - + ['close', 'end', 'error'].forEach(function(event) { self._stream.addListener(event, function() { self.close() }); }); @@ -61,18 +61,18 @@ EventSource.isEventSource = function(request) { var instance = { DEFAULT_PING: 10, DEFAULT_RETRY: 5, - + send: function(message, options) { if (this.readyState !== API.OPEN) return false; - + message = String(message).replace(/(\r\n|\r|\n)/g, '$1data: '); options = options || {}; - + var frame = ''; if (options.event) frame += 'event: ' + options.event + '\r\n'; if (options.id) frame += 'id: ' + options.id + '\r\n'; frame += 'data: ' + message + '\r\n\r\n'; - + try { this._stream.write(frame, 'utf8'); return true; @@ -80,7 +80,7 @@ var instance = { return false; } }, - + ping: function() { try { this._stream.write(':\r\n\r\n', 'utf8'); @@ -89,15 +89,15 @@ var instance = { return false; } }, - + close: function() { if (this.readyState === API.CLOSING || this.readyState === API.CLOSED) return; - + this.readyState = API.CLOSED; clearInterval(this._pingLoop); this._response.end(); - + var event = new Event('close'); event.initEvent('close', false, false); this.dispatchEvent(event); diff --git a/lib/faye/websocket.js b/lib/faye/websocket.js index 943b2c0..bbf9d29 100644 --- a/lib/faye/websocket.js +++ b/lib/faye/websocket.js @@ -36,38 +36,38 @@ var WebSocket = function(request, socket, head, supportedProtos, options) { this._stream = request.socket; this._ping = options && options.ping; this._pingId = 0; - + var scheme = isSecureConnection(request) ? 'wss:' : 'ws:'; this.url = scheme + '//' + request.headers.host + request.url; this.readyState = API.CONNECTING; this.bufferedAmount = 0; - + var Parser = getParser(request); this._parser = new Parser(this, {protocols: supportedProtos}); - + var self = this; this._sendBuffer = []; process.nextTick(function() { self._open() }); - + var handshake = this._parser.handshakeResponse(head); if (this._parser.isOpen()) this.readyState = API.OPEN; - + if (this._ping) this._pingLoop = setInterval(function() { self._pingId += 1; self.ping(self._pingId.toString()); }, this._ping * 1000); - + this.protocol = this._parser.protocol || ''; this.version = this._parser.getVersion(); - + if (!this._stream || !this._stream.writable) return; - + this._stream.setTimeout(0); this._stream.setNoDelay(true); - + try { this._stream.write(handshake, 'binary') } catch (e) {} - + this._stream.addListener('data', function(data) { var response = self._parser.parse(data); if (!response) return; diff --git a/lib/faye/websocket/api.js b/lib/faye/websocket/api.js index 5f1ab04..cdbc80f 100644 --- a/lib/faye/websocket/api.js +++ b/lib/faye/websocket/api.js @@ -6,22 +6,22 @@ var API = { OPEN: 1, CLOSING: 2, CLOSED: 3, - + _open: function() { if (this._parser && !this._parser.isOpen()) return; this.readyState = API.OPEN; - + var buffer = this._sendBuffer || [], message; - + while (message = buffer.shift()) this.send.apply(this, message); - + var event = new Event('open'); event.initEvent('open', false, false); this.dispatchEvent(event); }, - + receive: function(data) { if (this.readyState !== API.OPEN) return false; var event = new Event('message'); @@ -29,7 +29,7 @@ var API = { event.data = data; this.dispatchEvent(event); }, - + send: function(data, type, errorType) { if (this.readyState === API.CONNECTING) { if (this._sendBuffer) { @@ -39,12 +39,12 @@ var API = { throw new Error('Cannot call send(), socket is not open yet'); } } - + if (this.readyState === API.CLOSED) return false; - + if (!(data instanceof Buffer)) data = String(data); - + var frame = this._parser.frame(data, type, errorType); try { this._stream.write(frame, 'binary'); @@ -53,7 +53,7 @@ var API = { return false; } }, - + close: function(code, reason, ack) { if (this.readyState === API.CLOSING || this.readyState === API.CLOSED) return; diff --git a/lib/faye/websocket/api/event.js b/lib/faye/websocket/api/event.js index 81f7b67..2f707d8 100644 --- a/lib/faye/websocket/api/event.js +++ b/lib/faye/websocket/api/event.js @@ -3,7 +3,7 @@ var Event = function(eventType, options) { for (var key in options) this[key] = options[key]; }; - + Event.prototype.initEvent = function(eventType, canBubble, cancelable) { this.type = eventType; this.bubbles = canBubble; @@ -12,7 +12,7 @@ Event.prototype.initEvent = function(eventType, canBubble, cancelable) { Event.prototype.stopPropagation = function() {}; Event.prototype.preventDefault = function() {}; - + Event.CAPTURING_PHASE = 1; Event.AT_TARGET = 2; Event.BUBBLING_PHASE = 3; diff --git a/lib/faye/websocket/api/event_target.js b/lib/faye/websocket/api/event_target.js index 95213f1..056a8f4 100644 --- a/lib/faye/websocket/api/event_target.js +++ b/lib/faye/websocket/api/event_target.js @@ -5,38 +5,38 @@ var EventTarget = { onmessage: null, onerror: null, onclose: null, - + addEventListener: function(eventType, listener, useCapture) { this._listeners = this._listeners || {}; var list = this._listeners[eventType] = this._listeners[eventType] || []; list.push(listener); }, - + removeEventListener: function(eventType, listener, useCapture) { if (!this._listeners || !this._listeners[eventType]) return; - + if (!listener) { delete this._listeners[eventType]; return; } var list = this._listeners[eventType], i = list.length; - + while (i--) { if (listener !== list[i]) continue; list.splice(i,1); } }, - + dispatchEvent: function(event) { event.target = event.currentTarget = this; event.eventPhase = Event.AT_TARGET; - + if (this['on' + event.type]) this['on' + event.type](event); - + if (!this._listeners || !this._listeners[event.type]) return; - + this._listeners[event.type].forEach(function(listener) { listener(event); }, this); diff --git a/lib/faye/websocket/client.js b/lib/faye/websocket/client.js index 1f981fb..cde0002 100644 --- a/lib/faye/websocket/client.js +++ b/lib/faye/websocket/client.js @@ -8,30 +8,30 @@ var HybiParser = require('./hybi_parser'), var Client = function(url, protocols, options) { this.url = url; this._uri = require('url').parse(url); - + this.protocol = ''; this.readyState = API.CONNECTING; this.bufferedAmount = 0; - + var secure = (this._uri.protocol === 'wss:'), self = this, onConnect = function() { self._onConnect() }, tlsOptions = {}; - + if (options && options.verify === false) tlsOptions.rejectUnauthorized = false; var connection = secure ? tls.connect(this._uri.port || 443, this._uri.hostname, tlsOptions, onConnect) : net.createConnection(this._uri.port || 80, this._uri.hostname); - + this._parser = new HybiParser(this, {masking: true, protocols: protocols}); this._stream = connection; - + this._stream.setTimeout(0); this._stream.setNoDelay(true); - + if (!secure) connection.addListener('connect', onConnect); - + connection.addListener('data', function(data) { self._onData(data); }); @@ -39,7 +39,7 @@ var Client = function(url, protocols, options) { connection.addListener(event, function() { self.close(1006, '', false) }); }); }; - + Client.prototype._onConnect = function() { this._handshake = this._parser.createHandshake(this._uri, this._stream); this._message = []; @@ -54,18 +54,18 @@ Client.prototype._onData = function(data) { var bytes = this._handshake.parse(data); for (var i = 0, n = bytes.length; i < n; i++) this._message.push(bytes[i]); - + if (!this._handshake.isComplete()) return; - + if (this._handshake.isValid()) { this.protocol = this._handshake.protocol || ''; this.readyState = API.OPEN; var event = new Event('open'); event.initEvent('open', false, false); this.dispatchEvent(event); - + this._parser.parse(this._message); - + } else { this.readyState = API.CLOSED; var event = new Event('close', {code: 1006, reason: ''}); @@ -73,7 +73,7 @@ Client.prototype._onData = function(data) { this.dispatchEvent(event); } break; - + case API.OPEN: case API.CLOSING: this._parser.parse(data); diff --git a/lib/faye/websocket/draft75_parser.js b/lib/faye/websocket/draft75_parser.js index cf92619..b4e00aa 100644 --- a/lib/faye/websocket/draft75_parser.js +++ b/lib/faye/websocket/draft75_parser.js @@ -7,7 +7,7 @@ var instance = { getVersion: function() { return 'hixie-75'; }, - + handshakeResponse: function() { return new Buffer('HTTP/1.1 101 Web Socket Protocol Handshake\r\n' + 'Upgrade: WebSocket\r\n' + @@ -16,25 +16,25 @@ var instance = { 'WebSocket-Location: ' + this._socket.url + '\r\n\r\n', 'utf8'); }, - + isOpen: function() { return true; }, - + parse: function(buffer) { var data, message, value; for (var i = 0, n = buffer.length; i < n; i++) { data = buffer[i]; - + switch (this._stage) { case 0: this._parseLeadingByte(data); break; - + case 1: value = (data & 0x7F); this._length = value + 128 * this._length; - + if (this._closing && this._length === 0) { this._socket.close(null, null, false); } @@ -49,7 +49,7 @@ var instance = { } } break; - + case 2: if (data === 0xFF) { message = new Buffer(this._buffer); @@ -65,7 +65,7 @@ var instance = { } } }, - + _parseLeadingByte: function(data) { if ((0x80 & data) === 0x80) { this._length = 0; @@ -76,17 +76,17 @@ var instance = { this._stage = 2; } }, - + frame: function(data) { if (Buffer.isBuffer(data)) return data; - + var buffer = new Buffer(data, 'utf8'), frame = new Buffer(buffer.length + 2); - + frame[0] = 0x00; frame[buffer.length + 1] = 0xFF; buffer.copy(frame, 1); - + return frame; } }; diff --git a/lib/faye/websocket/draft76_parser.js b/lib/faye/websocket/draft76_parser.js index 3cabd3b..82da1a0 100644 --- a/lib/faye/websocket/draft76_parser.js +++ b/lib/faye/websocket/draft76_parser.js @@ -25,17 +25,17 @@ var bigEndian = function(number) { Draft76Parser.prototype.getVersion = function() { return 'hixie-76'; }; - + Draft76Parser.prototype.handshakeResponse = function(head) { var request = this._socket.request, tmp; - + var response = new Buffer('HTTP/1.1 101 Web Socket Protocol Handshake\r\n' + 'Upgrade: WebSocket\r\n' + 'Connection: Upgrade\r\n' + 'Sec-WebSocket-Origin: ' + request.headers.origin + '\r\n' + 'Sec-WebSocket-Location: ' + this._socket.url + '\r\n\r\n', 'binary'); - + var signature = this.handshakeSignature(head); if (signature) { tmp = new Buffer(response.length + signature.length); @@ -43,7 +43,7 @@ Draft76Parser.prototype.handshakeResponse = function(head) { signature.copy(tmp, response.length); response = tmp; } - + return response; }; @@ -53,21 +53,21 @@ Draft76Parser.prototype.isOpen = function() { Draft76Parser.prototype.handshakeSignature = function(head) { if (head.length === 0) return null; - + var request = this._socket.request, - + key1 = request.headers['sec-websocket-key1'], value1 = numberFromKey(key1) / spacesInKey(key1), - + key2 = request.headers['sec-websocket-key2'], value2 = numberFromKey(key2) / spacesInKey(key2), - + MD5 = crypto.createHash('md5'); - + MD5.update(bigEndian(value1)); MD5.update(bigEndian(value2)); MD5.update(head.toString('binary')); - + this._handshakeComplete = true; return new Buffer(MD5.digest('binary'), 'binary'); }; @@ -75,14 +75,14 @@ Draft76Parser.prototype.handshakeSignature = function(head) { Draft76Parser.prototype.parse = function(data) { if (this._handshakeComplete) return Draft75Parser.prototype.parse.call(this, data); - + return this.handshakeSignature(data); }; Draft76Parser.prototype._parseLeadingByte = function(data) { if (data !== 0xFF) return Draft75Parser.prototype._parseLeadingByte.call(this, data); - + this._closing = true; this._length = 0; this._stage = 1; diff --git a/lib/faye/websocket/hybi_parser.js b/lib/faye/websocket/hybi_parser.js index 3726e8b..57464da 100644 --- a/lib/faye/websocket/hybi_parser.js +++ b/lib/faye/websocket/hybi_parser.js @@ -9,9 +9,9 @@ var HybiParser = function(webSocket, options) { this._stage = 0; this._masking = options && options.masking; this._protocols = options && options.protocols; - + this._pingCallbacks = {}; - + if (typeof this._protocols === 'string') this._protocols = this._protocols.split(/\s*,\s*/); }; @@ -19,7 +19,7 @@ var HybiParser = function(webSocket, options) { HybiParser.mask = function(payload, mask, offset) { if (mask.length === 0) return payload; offset = offset || 0; - + for (var i = 0, n = payload.length - offset; i < n; i++) { payload[offset + i] = payload[offset + i] ^ mask[i % 4]; } @@ -35,7 +35,7 @@ var instance = { RSV3: 16, OPCODE: 15, LENGTH: 127, - + OPCODES: { continuation: 0, text: 1, @@ -44,7 +44,7 @@ var instance = { ping: 9, pong: 10 }, - + ERRORS: { normal_closure: 1000, going_away: 1001, @@ -56,38 +56,38 @@ var instance = { extension_error: 1010, unexpected_condition: 1011 }, - + FRAGMENTED_OPCODES: [0,1,2], OPENING_OPCODES: [1,2], - + ERROR_CODES: [1000,1001,1002,1003,1007,1008,1009,1010,1011], - + UTF8_MATCH: /^([\x00-\x7F]|[\xC2-\xDF][\x80-\xBF]|\xE0[\xA0-\xBF][\x80-\xBF]|[\xE1-\xEC\xEE\xEF][\x80-\xBF]{2}|\xED[\x80-\x9F][\x80-\xBF]|\xF0[\x90-\xBF][\x80-\xBF]{2}|[\xF1-\xF3][\x80-\xBF]{3}|\xF4[\x80-\x8F][\x80-\xBF]{2})*$/, - + getVersion: function() { var version = this._socket.request.headers['sec-websocket-version']; return 'hybi-' + version; }, - + handshakeResponse: function() { var secKey = this._socket.request.headers['sec-websocket-key']; if (!secKey) return null; - + var SHA1 = crypto.createHash('sha1'); SHA1.update(secKey + Handshake.GUID); - + var accept = SHA1.digest('base64'), protos = this._socket.request.headers['sec-websocket-protocol'], supported = this._protocols, proto, - + headers = [ 'HTTP/1.1 101 Switching Protocols', 'Upgrade: websocket', 'Connection: Upgrade', 'Sec-WebSocket-Accept: ' + accept ]; - + if (protos !== undefined && supported !== undefined) { if (typeof protos === 'string') protos = protos.split(/\s*,\s*/); proto = protos.filter(function(p) { return supported.indexOf(p) >= 0 })[0]; @@ -96,18 +96,18 @@ var instance = { headers.push('Sec-WebSocket-Protocol: ' + proto); } } - + return new Buffer(headers.concat('','').join('\r\n'), 'utf8'); }, - + isOpen: function() { return true; }, - + createHandshake: function(uri) { return new Handshake(uri, this._protocols); }, - + parse: function(data) { this._reader.put(data); var buffer = true; @@ -117,17 +117,17 @@ var instance = { buffer = this._reader.read(1); if (buffer) this._parseOpcode(buffer[0]); break; - + case 1: buffer = this._reader.read(1); if (buffer) this._parseLength(buffer[0]); break; - + case 2: buffer = this._reader.read(this._lengthSize); if (buffer) this._parseExtendedLength(buffer); break; - + case 3: buffer = this._reader.read(4); if (buffer) { @@ -135,7 +135,7 @@ var instance = { this._stage = 4; } break; - + case 4: buffer = this._reader.read(this._length); if (buffer) { @@ -147,40 +147,40 @@ var instance = { } } }, - + _parseOpcode: function(data) { var rsvs = [this.RSV1, this.RSV2, this.RSV3].filter(function(rsv) { return (data & rsv) === rsv; }, this); - + if (rsvs.length > 0) return this._socket.close(this.ERRORS.protocol_error, null, false); - + this._final = (data & this.FIN) === this.FIN; this._opcode = (data & this.OPCODE); this._mask = []; this._payload = []; - + var valid = false; - + for (var key in this.OPCODES) { if (this.OPCODES[key] === this._opcode) valid = true; } if (!valid) return this._socket.close(this.ERRORS.protocol_error, null, false); - + if (this.FRAGMENTED_OPCODES.indexOf(this._opcode) < 0 && !this._final) return this._socket.close(this.ERRORS.protocol_error, null, false); - + if (this._mode && this.OPENING_OPCODES.indexOf(this._opcode) >= 0) return this._socket.close(this.ERRORS.protocol_error, null, false); - + this._stage = 1; }, - + _parseLength: function(data) { this._masked = (data & this.MASK) === this.MASK; this._length = (data & this.LENGTH); - + if (this._length >= 0 && this._length <= 125) { this._stage = this._masked ? 3 : 4; } else { @@ -189,15 +189,15 @@ var instance = { this._stage = 2; } }, - + _parseExtendedLength: function(buffer) { this._length = this._getInteger(buffer); this._stage = this._masked ? 3 : 4; }, - + frame: function(data, type, code) { if (this._closed) return null; - + var isText = (typeof data === 'string'), opcode = this.OPCODES[type || (isText ? 'text' : 'binary')], buffer = isText ? new Buffer(data, 'utf8') : data, @@ -209,9 +209,9 @@ var instance = { frame = new Buffer(length + offset), BYTE = this.BYTE, mask, i; - + frame[0] = this.FIN | opcode; - + if (length <= 125) { frame[1] = masked | length; } else if (length <= 65535) { @@ -229,45 +229,45 @@ var instance = { frame[8] = Math.floor(length / Math.pow(2,8)) & BYTE; frame[9] = length & BYTE; } - + if (code) { frame[offset] = Math.floor(code / 256) & BYTE; frame[offset+1] = code & BYTE; } buffer.copy(frame, offset + insert); - + if (this._masking) { mask = [Math.floor(Math.random() * 256), Math.floor(Math.random() * 256), Math.floor(Math.random() * 256), Math.floor(Math.random() * 256)]; new Buffer(mask).copy(frame, header); HybiParser.mask(frame, mask, offset); } - + return frame; }, - + ping: function(message, callback, context) { message = message || ''; if (callback) this._pingCallbacks[message] = [callback, context]; return this._socket.send(message, 'ping'); }, - + close: function(code, reason, callback, context) { if (this._closed) return; if (callback) this._closingCallback = [callback, context]; this._socket.send(reason || '', 'close', code || this.ERRORS.normal_closure); this._closed = true; }, - + buffer: function(fragment) { for (var i = 0, n = fragment.length; i < n; i++) this._buffer.push(fragment[i]); }, - + _emitFrame: function() { var payload = HybiParser.mask(this._payload, this._mask), opcode = this._opcode; - + if (opcode === this.OPCODES.continuation) { if (!this._mode) return this._socket.close(this.ERRORS.protocol_error, null, false); this.buffer(payload); @@ -300,15 +300,15 @@ var instance = { else if (opcode === this.OPCODES.close) { var code = (payload.length >= 2) ? 256 * payload[0] + payload[1] : null, reason = (payload.length > 2) ? this._encode(payload.slice(2)) : null; - + if (!(payload.length === 0) && !(code !== null && code >= 3000 && code < 5000) && this.ERROR_CODES.indexOf(code) < 0) code = this.ERRORS.protocol_error; - + if (payload.length > 125 || (payload.length > 2 && !reason)) code = this.ERRORS.protocol_error; - + this._socket.close(code, (payload.length > 2) ? reason : null, false); if (this._closingCallback) this._closingCallback[0].call(this._closingCallback[1]); @@ -321,17 +321,17 @@ var instance = { var callbacks = this._pingCallbacks, message = this._encode(payload), callback = callbacks[message]; - + delete callbacks[message]; if (callback) callback[0].call(callback[1]); } }, - + _reset: function() { this._mode = null; this._buffer = []; }, - + _encode: function(buffer) { try { var string = buffer.toString('binary', 0, buffer.length); @@ -339,7 +339,7 @@ var instance = { } catch (e) {} return buffer.toString('utf8', 0, buffer.length); }, - + _getInteger: function(bytes) { var number = 0; for (var i = 0, n = bytes.length; i < n; i++) diff --git a/lib/faye/websocket/hybi_parser/handshake.js b/lib/faye/websocket/hybi_parser/handshake.js index 304564e..0a75191 100644 --- a/lib/faye/websocket/hybi_parser/handshake.js +++ b/lib/faye/websocket/hybi_parser/handshake.js @@ -3,25 +3,25 @@ var crypto = require('crypto'); var Handshake = function(uri, protocols) { this._uri = uri; this._protocols = protocols; - + var buffer = new Buffer(16), i = 16; while (i--) buffer[i] = Math.floor(Math.random() * 256); this._key = buffer.toString('base64'); - + var SHA1 = crypto.createHash('sha1'); SHA1.update(this._key + Handshake.GUID); this._accept = SHA1.digest('base64'); - + var HTTPParser = process.binding('http_parser').HTTPParser, parser = new HTTPParser(HTTPParser.RESPONSE || 'response'), current = null, self = this; - + this._nodeVersion = HTTPParser.RESPONSE ? 6 : 4; this._complete = false; this._headers = {}; this._parser = parser; - + parser.onHeaderField = function(b, start, length) { current = b.toString('utf8', start, start + length); }; @@ -41,10 +41,10 @@ var Handshake = function(uri, protocols) { }; Handshake.GUID = '258EAFA5-E914-47DA-95CA-C5AB0DC85B11'; - + Handshake.prototype.requestData = function() { var u = this._uri; - + var headers = [ 'GET ' + (u.pathname || '/') + (u.search || '') + ' HTTP/1.1', 'Host: ' + u.hostname + (u.port ? ':' + u.port : ''), @@ -53,17 +53,17 @@ Handshake.prototype.requestData = function() { 'Sec-WebSocket-Key: ' + this._key, 'Sec-WebSocket-Version: 13' ]; - + if (this._protocols) headers.push('Sec-WebSocket-Protocol: ' + this._protocols.join(', ')); - + return new Buffer(headers.concat('','').join('\r\n'), 'utf8'); }; Handshake.prototype.parse = function(data) { var consumed = this._parser.execute(data, 0, data.length), offset = (this._nodeVersion < 6) ? 1 : 0; - + return (consumed === data.length) ? [] : data.slice(consumed + offset); }; @@ -73,15 +73,15 @@ Handshake.prototype.isComplete = function() { Handshake.prototype.isValid = function() { if (this._status !== 101) return false; - + var upgrade = this._headers.Upgrade, connection = this._headers.Connection, protocol = this._headers['Sec-WebSocket-Protocol']; - + this.protocol = this._protocols && this._protocols.indexOf(protocol) >= 0 ? protocol : null; - + return upgrade && /^websocket$/i.test(upgrade) && connection && connection.split(/\s*,\s*/).indexOf('Upgrade') >= 0 && ((!this._protocols && !protocol) || this.protocol) && diff --git a/lib/faye/websocket/hybi_parser/stream_reader.js b/lib/faye/websocket/hybi_parser/stream_reader.js index f594aa7..01e607f 100644 --- a/lib/faye/websocket/hybi_parser/stream_reader.js +++ b/lib/faye/websocket/hybi_parser/stream_reader.js @@ -20,9 +20,9 @@ StreamReader.prototype._readBuffer = function(length) { n = queue.length, i = 0, chunk, offset, size; - + if (remain === 0) return buffer; - + while (remain > 0 && i < n) { chunk = queue[i]; offset = (i === 0) ? this._cursor : 0; @@ -31,12 +31,12 @@ StreamReader.prototype._readBuffer = function(length) { remain -= size; i += 1; } - + if (remain > 0) return null; - + queue.splice(0, i-1); this._cursor = (i === 1 ? this._cursor : 0) + size; - + return buffer; }; diff --git a/spec/faye/websocket/client_spec.js b/spec/faye/websocket/client_spec.js index 049d9fa..e9aa6bc 100644 --- a/spec/faye/websocket/client_spec.js +++ b/spec/faye/websocket/client_spec.js @@ -7,29 +7,29 @@ JS.ENV.WebSocketSteps = JS.Test.asyncSteps({ this._port = port setTimeout(callback, 100) }, - + stop: function(callback) { this._adapter.stop() setTimeout(callback, 100) }, - + open_socket: function(url, protocols, callback) { var done = false, self = this, - + resume = function(open) { if (done) return done = true self._open = open callback() } - + this._ws = new Client(url, protocols, {verify: false}) - + this._ws.onopen = function() { resume(true) } this._ws.onclose = function() { resume(false) } }, - + close_socket: function(callback) { var self = this this._ws.onclose = function() { @@ -38,38 +38,38 @@ JS.ENV.WebSocketSteps = JS.Test.asyncSteps({ } this._ws.close() }, - + check_open: function(callback) { this.assert( this._open ) callback() }, - + check_closed: function(callback) { this.assert( !this._open ) callback() }, - + check_protocol: function(protocol, callback) { this.assertEqual( protocol, this._ws.protocol ) callback() }, - + listen_for_message: function(callback) { var self = this this._ws.addEventListener('message', function(message) { self._message = message.data }) callback() }, - + send_message: function(message, callback) { this._ws.send(message) setTimeout(callback, 100) }, - + check_response: function(message, callback) { this.assertEqual( message, this._message ) callback() }, - + check_no_response: function(callback) { this.assert( !this._message ) callback() @@ -79,67 +79,67 @@ JS.ENV.WebSocketSteps = JS.Test.asyncSteps({ JS.ENV.ClientSpec = JS.Test.describe("Client", function() { with(this) { include(WebSocketSteps) - + before(function() { this.protocols = ["foo", "echo"] this.plain_text_url = "ws://localhost:8000/bayeux" this.secure_url = "wss://localhost:8000/bayeux" }) - + sharedBehavior("socket client", function() { with(this) { it("can open a connection", function() { with(this) { open_socket(socket_url, protocols) check_open() check_protocol("echo") }}) - + it("cannot open a connection with unacceptable protocols", function() { with(this) { open_socket(socket_url, ["foo"]) check_closed() }}) - + it("can close the connection", function() { with(this) { open_socket(socket_url, protocols) close_socket() check_closed() }}) - + describe("in the OPEN state", function() { with(this) { before(function() { with(this) { open_socket(socket_url, protocols) }}) - + it("can send and receive messages", function() { with(this) { listen_for_message() send_message("I expect this to be echoed") check_response("I expect this to be echoed") }}) - + it("sends numbers as strings", function() { with(this) { listen_for_message() send_message(13) check_response("13") }}) - + it("sends booleans as strings", function() { with(this) { listen_for_message() send_message(false) check_response("false") }}) - + it("sends arrays as strings", function() { with(this) { listen_for_message() send_message([13,14,15]) check_response("13,14,15") }}) }}) - + describe("in the CLOSED state", function() { with(this) { before(function() { with(this) { open_socket(socket_url, protocols) close_socket() }}) - + it("cannot send and receive messages", function() { with(this) { listen_for_message() send_message("I expect this to be echoed") @@ -147,28 +147,28 @@ JS.ENV.ClientSpec = JS.Test.describe("Client", function() { with(this) { }}) }}) }}) - + describe("with a plain-text server", function() { with(this) { before(function() { this.socket_url = this.plain_text_url this.blocked_url = this.secure_url }) - + before(function() { this.server(8000, false) }) after (function() { this.stop() }) - + behavesLike("socket client") }}) - + describe("with a secure server", function() { with(this) { before(function() { this.socket_url = this.secure_url this.blocked_url = this.plain_text_url }) - + before(function() { this.server(8000, true) }) after (function() { this.stop() }) - + behavesLike("socket client") }}) }}) diff --git a/spec/faye/websocket/draft75parser_spec.js b/spec/faye/websocket/draft75parser_spec.js index 0c2dfa3..6197193 100644 --- a/spec/faye/websocket/draft75parser_spec.js +++ b/spec/faye/websocket/draft75parser_spec.js @@ -5,66 +5,66 @@ JS.ENV.Draft75ParserSpec = JS.Test.describe("Draft75Parser", function() { with(t this.webSocket = {dispatchEvent: function() {}} this.parser = new Draft75Parser(webSocket) }}) - + describe("parse", function() { with(this) { sharedBehavior("draft-75 parser", function() { with(this) { it("parses text frames", function() { with(this) { expect(webSocket, "receive").given("Hello") parser.parse([0x00, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0xff]) }}) - + it("parses multiple frames from the same packet", function() { with(this) { expect(webSocket, "receive").given("Hello").exactly(2) parser.parse([0x00, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0xff, 0x00, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0xff]) }}) - + it("parses text frames beginning 0x00-0x7F", function() { with(this) { expect(webSocket, "receive").given("Hello") parser.parse([0x66, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0xff]) }}) - + it("ignores frames with a length header", function() { with(this) { expect(webSocket, "receive").exactly(0) parser.parse([0x80, 0x05, 0x48, 0x65, 0x6c, 0x6c, 0x6f]) }}) - + it("parses text following an ignored block", function() { with(this) { expect(webSocket, "receive").given("Hello") parser.parse([0x80, 0x02, 0x48, 0x65, 0x00, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0xff]) }}) - + it("parses multibyte text frames", function() { with(this) { expect(webSocket, "receive").given("Apple = ") parser.parse([0x00, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x3d, 0x20, 0xef, 0xa3, 0xbf, 0xff]) }}) - + it("parses frames received in several packets", function() { with(this) { expect(webSocket, "receive").given("Apple = ") parser.parse([0x00, 0x41, 0x70, 0x70, 0x6c, 0x65]) parser.parse([0x20, 0x3d, 0x20, 0xef, 0xa3, 0xbf, 0xff]) }}) - + it("parses fragmented frames", function() { with(this) { expect(webSocket, "receive").given("Hello") parser.parse([0x00, 0x48, 0x65, 0x6c]) parser.parse([0x6c, 0x6f, 0xff]) }}) }}) - + behavesLike("draft-75 parser") - + it("does not close the socket if a 76 close frame is received", function() { with(this) { expect(webSocket, "close").exactly(0) expect(webSocket, "receive").given("") parser.parse([0xFF, 0x00]) }}) }}) - + describe("frame", function() { with(this) { it("returns the given string formatted as a WebSocket frame", function() { with(this) { assertBufferEqual( [0x00, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0xff], parser.frame("Hello") ) }}) - + it("encodes multibyte characters correctly", function() { with(this) { assertBufferEqual( [0x00, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x3d, 0x20, 0xef, 0xa3, 0xbf, 0xff], parser.frame("Apple = ") ) }}) diff --git a/spec/faye/websocket/draft76parser_spec.js b/spec/faye/websocket/draft76parser_spec.js index 923fe3a..775c1e3 100644 --- a/spec/faye/websocket/draft76parser_spec.js +++ b/spec/faye/websocket/draft76parser_spec.js @@ -6,21 +6,21 @@ JS.ENV.Draft76ParserSpec = JS.Test.describe("Draft76Parser", function() { with(t this.parser = new Draft76Parser(webSocket) parser._handshakeComplete = true }}) - + describe("parse", function() { with(this) { behavesLike("draft-75 parser") - + it("closes the socket if a close frame is received", function() { with(this) { expect(webSocket, "close") parser.parse([0xFF, 0x00]) }}) }}) - + describe("frame", function() { with(this) { it("returns the given string formatted as a WebSocket frame", function() { with(this) { assertBufferEqual( [0x00, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0xff], parser.frame("Hello") ) }}) - + it("encodes multibyte characters correctly", function() { with(this) { assertBufferEqual( [0x00, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x3d, 0x20, 0xef, 0xa3, 0xbf, 0xff], parser.frame("Apple = ") ) }}) diff --git a/spec/faye/websocket/hybi_parser_spec.js b/spec/faye/websocket/hybi_parser_spec.js index 825b8df..5531b9d 100644 --- a/spec/faye/websocket/hybi_parser_spec.js +++ b/spec/faye/websocket/hybi_parser_spec.js @@ -5,13 +5,13 @@ JS.ENV.HybiParserSpec = JS.Test.describe("HybiParser", function() { with(this) { this.webSocket = {dispatchEvent: function() {}} this.parser = new HybiParser(webSocket) }}) - + define("parse", function() { var bytes = []; for (var i = 0, n = arguments.length; i < n; i++) bytes = bytes.concat(arguments[i]) this.parser.parse(new Buffer(bytes)) }) - + define("buffer", function(string) { return { equals: function(buffer) { @@ -19,12 +19,12 @@ JS.ENV.HybiParserSpec = JS.Test.describe("HybiParser", function() { with(this) { } } }) - + describe("parse", function() { with(this) { define("mask", function() { return this._mask = this._mask || [1,2,3,4].map(function() { return Math.floor(Math.random() * 255) }) }) - + define("maskMessage", function(bytes) { var output = [] Array.prototype.forEach.call(bytes, function(b, i) { @@ -32,115 +32,115 @@ JS.ENV.HybiParserSpec = JS.Test.describe("HybiParser", function() { with(this) { }, this) return output }) - + it("parses unmasked text frames", function() { with(this) { expect(webSocket, "receive").given("Hello") parse([0x81, 0x05, 0x48, 0x65, 0x6c, 0x6c, 0x6f]) }}) - + it("parses multiple frames from the same packet", function() { with(this) { expect(webSocket, "receive").given("Hello").exactly(2) parse([0x81, 0x05, 0x48, 0x65, 0x6c, 0x6c, 0x6f, 0x81, 0x05, 0x48, 0x65, 0x6c, 0x6c, 0x6f]) }}) - + it("parses empty text frames", function() { with(this) { expect(webSocket, "receive").given("") parse([0x81, 0x00]) }}) - + it("parses fragmented text frames", function() { with(this) { expect(webSocket, "receive").given("Hello") parse([0x01, 0x03, 0x48, 0x65, 0x6c]) parse([0x80, 0x02, 0x6c, 0x6f]) }}) - + it("parses masked text frames", function() { with(this) { expect(webSocket, "receive").given("Hello") parse([0x81, 0x85], mask(), maskMessage([0x48, 0x65, 0x6c, 0x6c, 0x6f])) }}) - + it("parses masked empty text frames", function() { with(this) { expect(webSocket, "receive").given("") parse([0x81, 0x80], mask(), maskMessage([])) }}) - + it("parses masked fragmented text frames", function() { with(this) { expect(webSocket, "receive").given("Hello") parse([0x01, 0x81], mask(), maskMessage([0x48])) parse([0x80, 0x84], mask(), maskMessage([0x65, 0x6c, 0x6c, 0x6f])) }}) - + it("closes the socket if the frame has an unrecognized opcode", function() { with(this) { expect(webSocket, "close").given(1002, null, false) parse([0x83, 0x00]) }}) - + it("closes the socket if a close frame is received", function() { with(this) { expect(webSocket, "close").given(1000, "Hello", false) parse([0x88, 0x07, 0x03, 0xe8, 0x48, 0x65, 0x6c, 0x6c, 0x6f]) }}) - + it("parses unmasked multibyte text frames", function() { with(this) { expect(webSocket, "receive").given("Apple = ") parse([0x81, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x3d, 0x20, 0xef, 0xa3, 0xbf]) }}) - + it("parses frames received in several packets", function() { with(this) { expect(webSocket, "receive").given("Apple = ") parse([0x81, 0x0b, 0x41, 0x70, 0x70, 0x6c]) parse([0x65, 0x20, 0x3d, 0x20, 0xef, 0xa3, 0xbf]) }}) - + it("parses fragmented multibyte text frames", function() { with(this) { expect(webSocket, "receive").given("Apple = ") parse([0x01, 0x0a, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x3d, 0x20, 0xef, 0xa3]) parse([0x80, 0x01, 0xbf]) }}) - + it("parses masked multibyte text frames", function() { with(this) { expect(webSocket, "receive").given("Apple = ") parse([0x81, 0x8b], mask(), maskMessage([0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x3d, 0x20, 0xef, 0xa3, 0xbf])) }}) - + it("parses masked fragmented multibyte text frames", function() { with(this) { expect(webSocket, "receive").given("Apple = ") parse([0x01, 0x8a], mask(), maskMessage([0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x3d, 0x20, 0xef, 0xa3])) parse([0x80, 0x81], mask(), maskMessage([0xbf])) }}) - + it("parses unmasked medium-length text frames", function() { with(this) { expect(webSocket, "receive").given("HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello") parse([129, 126, 0, 200, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111]) }}) - + it("parses masked medium-length text frames", function() { with(this) { expect(webSocket, "receive").given("HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello") parse([129, 254, 0, 200], mask(), maskMessage([72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111])) }}) - + it("replies to pings with a pong", function() { with(this) { expect(webSocket, "send").given(buffer("OHAI"), "pong") parse([0x89, 0x04, 0x4f, 0x48, 0x41, 0x49]) }}) }}) - + describe("frame", function() { with(this) { it("returns the given string formatted as a WebSocket frame", function() { with(this) { assertBufferEqual( [0x81, 0x05, 0x48, 0x65, 0x6c, 0x6c, 0x6f], parser.frame("Hello") ) }}) - + it("encodes multibyte characters correctly", function() { with(this) { assertBufferEqual( [0x81, 0x0b, 0x41, 0x70, 0x70, 0x6c, 0x65, 0x20, 0x3d, 0x20, 0xef, 0xa3, 0xbf], parser.frame("Apple = ") ) }}) - + it("encodes medium-length strings using extra length bytes", function() { with(this) { assertBufferEqual( [129, 126, 0, 200, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111, 72, 101, 108, 108, 111], parser.frame("HelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHelloHello") ) }}) - + it("encodes close frames with an error code", function() { with(this) { assertBufferEqual( [0x88, 0x07, 0x03, 0xea, 0x48, 0x65, 0x6c, 0x6c, 0x6f], parser.frame("Hello", "close", 1002) ) }}) - + it("encodes pong frames", function() { with(this) { assertBufferEqual( [0x8a, 0x00], parser.frame("", "pong") ) }}) diff --git a/spec/runner.js b/spec/runner.js index 03231c8..68ad93e 100644 --- a/spec/runner.js +++ b/spec/runner.js @@ -14,7 +14,7 @@ EchoServer.prototype.listen = function(port, ssl) { cert: fs.readFileSync(__dirname + '/server.crt') }) : http.createServer() - + server.addListener('upgrade', function(request, socket, head) { var ws = new WebSocket(request, socket, head, ["echo"]) ws.onmessage = function(event) { @@ -44,7 +44,7 @@ JS.require('JS.Test', function() { while (n--) ary[n] = buffer[n]; this.assertEqual(array, ary); }) - + JS.require( 'ClientSpec', 'Draft75ParserSpec', 'Draft76ParserSpec',