pax_global_header00006660000000000000000000000064135411124230014506gustar00rootroot0000000000000052 comment=652402a8568c2138da3c27c96756b32efca6c4bf socket.io-parser-3.4.0/000077500000000000000000000000001354111242300147025ustar00rootroot00000000000000socket.io-parser-3.4.0/.gitignore000066400000000000000000000000361354111242300166710ustar00rootroot00000000000000node_modules build components socket.io-parser-3.4.0/.travis.yml000066400000000000000000000014171354111242300170160ustar00rootroot00000000000000language: node_js sudo: false node_js: - '8' - '10' git: depth: 1 matrix: include: - node_js: node env: BROWSERS=1 cache: directories: - node_modules env: global: - secure: >- Ea4P/R9UlWzDlHSP5ynmLiD/YgLjecIvCviOcRTle9mV3P1j2k94Ay1LVu1Jw4whlNmWLq2Z/p8M63L92ODPMlarPsuME8HlP4zGr41whFhRbFdda4k3zrHfUhZBlnhY1MVWXTtVm/l7DOzpBrNh+wKecxZB3yyyEaA+PSG3qcQ= - secure: >- JmPf38qx5Rb6K+WYOMwb5YmESkDmVJ6tgggiJIuyRfHsgQVOO7XBwZuspIKGTSFolUIMaqwQe79Kd+Ehs2ZZ/0lUyF2/6xW3FqFnASUusYJcZdfRjypmBFWs6BRdtEORM8HL0dgBx4O4u/e4ZvtygumbPahjQbMDaqN+MvlpjD0= - secure: >- c3pnLhy3VDJqMl16ABA+8vt3I623aNa2wkLceLXb2V1Dc6eiZeulDH2ekwmdVo/r2WwGIKP3Y6B0mq/xP4W0hg4uT+xWh0AmFHclVyM/yp/AqfXrDUv17Vm0vB7OIgp332OiAlK6Dr13YDbWW8iZxmID41O2+2qohLGPn5JMncg= socket.io-parser-3.4.0/LICENSE000066400000000000000000000021211354111242300157030ustar00rootroot00000000000000(The MIT License) Copyright (c) 2014 Guillermo Rauch Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. socket.io-parser-3.4.0/Makefile000066400000000000000000000010471354111242300163440ustar00rootroot00000000000000 help: ## print this message @grep -E '^[a-zA-Z_-]+:.*?## .*$$' $(MAKEFILE_LIST) | awk 'BEGIN {FS = ":.*?## "}; {printf "\033[36m%-20s\033[0m %s\n", $$1, $$2}' test: ## run tests either in the browser or in Node.js, based on the `BROWSERS` variable @if [ "x$(BROWSERS)" = "x" ]; then make test-node; else make test-zuul; fi test-node: ## run tests in Node.js @./node_modules/.bin/mocha --reporter dot --bail test/index.js test-zuul: ## run tests in the browser @./node_modules/zuul/bin/zuul test/index.js .PHONY: help test test-node test-zuul socket.io-parser-3.4.0/Readme.md000066400000000000000000000040551354111242300164250ustar00rootroot00000000000000 # socket.io-parser [![Build Status](https://secure.travis-ci.org/socketio/socket.io-parser.svg?branch=master)](http://travis-ci.org/socketio/socket.io-parser) [![NPM version](https://badge.fury.io/js/socket.io-parser.svg)](http://badge.fury.io/js/socket.io-parser) A socket.io encoder and decoder written in JavaScript complying with version `4` of [socket.io-protocol](https://github.com/socketio/socket.io-protocol). Used by [socket.io](https://github.com/automattic/socket.io) and [socket.io-client](https://github.com/automattic/socket.io-client). ## Parser API socket.io-parser is the reference implementation of socket.io-protocol. Read the full API here: [socket.io-protocol](https://github.com/learnboost/socket.io-protocol). ## Example Usage ### Encoding and decoding a packet ```js var parser = require('socket.io-parser'); var encoder = new parser.Encoder(); var packet = { type: parser.EVENT, data: 'test-packet', id: 13 }; encoder.encode(packet, function(encodedPackets) { var decoder = new parser.Decoder(); decoder.on('decoded', function(decodedPacket) { // decodedPacket.type == parser.EVENT // decodedPacket.data == 'test-packet' // decodedPacket.id == 13 }); for (var i = 0; i < encodedPackets.length; i++) { decoder.add(encodedPackets[i]); } }); ``` ### Encoding and decoding a packet with binary data ```js var parser = require('socket.io-parser'); var encoder = new parser.Encoder(); var packet = { type: parser.BINARY_EVENT, data: {i: new Buffer(1234), j: new Blob([new ArrayBuffer(2)])} id: 15 }; encoder.encode(packet, function(encodedPackets) { var decoder = new parser.Decoder(); decoder.on('decoded', function(decodedPacket) { // decodedPacket.type == parser.BINARY_EVENT // Buffer.isBuffer(decodedPacket.data.i) == true // Buffer.isBuffer(decodedPacket.data.j) == true // decodedPacket.id == 15 }); for (var i = 0; i < encodedPackets.length; i++) { decoder.add(encodedPackets[i]); } }); ``` See the test suite for more examples of how socket.io-parser is used. ## License MIT socket.io-parser-3.4.0/bench/000077500000000000000000000000001354111242300157615ustar00rootroot00000000000000socket.io-parser-3.4.0/bench/bench.js000066400000000000000000000003651354111242300174020ustar00rootroot00000000000000var bencher = require('./index'); bencher(function(benchmark) { function logMean(test) { console.log(test.name + ' mean run time: ' + test.stats.mean); } for (var i = 0; i < benchmark.length; i++) { logMean(benchmark[i]); } }); socket.io-parser-3.4.0/bench/index.js000066400000000000000000000035571354111242300174400ustar00rootroot00000000000000var Benchmark = require('benchmark'); var parser = require('../index'); function test(packet, deferred) { var encoder = new parser.Encoder(); var decoder = new parser.Decoder(); encoder.encode(packet, function(encodedPackets) { var decoder = new parser.Decoder(); decoder.on('decoded', function(packet) { deferred.resolve(); }); decoder.add(encodedPackets[0]); }); } var dataObject = { 'a': [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17], 'b': 'xxxyyyzzzalsdfalskdjfalksdjfalksdjfalksdjfjjfjfjfjjfjfjfj', 'data': { 'is': 'cool', 'or': { 'is': { 'it': true } } } }; var bigArray = []; for (var i = 0; i < 250; i++) { bigArray.push(dataObject); } module.exports = function(callback) { var suite = new Benchmark.Suite(); suite.add('small json parse', {defer: true, fn: function(deferred) { var packet = { type: parser.EVENT, nsp: '/bench', data: dataObject }; test(packet, deferred); }}) .add('big json parse', {defer: true, fn: function(deferred) { var packet = { type: parser.EVENT, nsp: '/bench', data: bigArray }; test(packet, deferred); }}) .add('json with small binary parse', {defer: true, fn: function(deferred) { var packet = { type: parser.EVENT, nsp: '/bench', data: {'a': [1, 2, 3], 'b': 'xxxyyyzzz', 'data': new Buffer(1000)} }; test(packet, deferred); }}) .add('json with big binary parse', {defer: true, fn: function(deferred) { var bigBinaryData = { bin1: new Buffer(10000), arr: bigArray, bin2: new Buffer(10000), bin3: new Buffer(10000) }; var packet = { type: parser.EVENT, nsp: '/bench', data: bigBinaryData }; test(packet, deferred); }}) .on('complete', function() { callback(this); }) .run({'async': true}); }; socket.io-parser-3.4.0/binary.js000066400000000000000000000077721354111242300165410ustar00rootroot00000000000000/*global Blob,File*/ /** * Module requirements */ var isArray = require('isarray'); var isBuf = require('./is-buffer'); var toString = Object.prototype.toString; var withNativeBlob = typeof Blob === 'function' || (typeof Blob !== 'undefined' && toString.call(Blob) === '[object BlobConstructor]'); var withNativeFile = typeof File === 'function' || (typeof File !== 'undefined' && toString.call(File) === '[object FileConstructor]'); /** * Replaces every Buffer | ArrayBuffer in packet with a numbered placeholder. * Anything with blobs or files should be fed through removeBlobs before coming * here. * * @param {Object} packet - socket.io event packet * @return {Object} with deconstructed packet and list of buffers * @api public */ exports.deconstructPacket = function(packet) { var buffers = []; var packetData = packet.data; var pack = packet; pack.data = _deconstructPacket(packetData, buffers); pack.attachments = buffers.length; // number of binary 'attachments' return {packet: pack, buffers: buffers}; }; function _deconstructPacket(data, buffers) { if (!data) return data; if (isBuf(data)) { var placeholder = { _placeholder: true, num: buffers.length }; buffers.push(data); return placeholder; } else if (isArray(data)) { var newData = new Array(data.length); for (var i = 0; i < data.length; i++) { newData[i] = _deconstructPacket(data[i], buffers); } return newData; } else if (typeof data === 'object' && !(data instanceof Date)) { var newData = {}; for (var key in data) { newData[key] = _deconstructPacket(data[key], buffers); } return newData; } return data; } /** * Reconstructs a binary packet from its placeholder packet and buffers * * @param {Object} packet - event packet with placeholders * @param {Array} buffers - binary buffers to put in placeholder positions * @return {Object} reconstructed packet * @api public */ exports.reconstructPacket = function(packet, buffers) { packet.data = _reconstructPacket(packet.data, buffers); packet.attachments = undefined; // no longer useful return packet; }; function _reconstructPacket(data, buffers) { if (!data) return data; if (data && data._placeholder) { return buffers[data.num]; // appropriate buffer (should be natural order anyway) } else if (isArray(data)) { for (var i = 0; i < data.length; i++) { data[i] = _reconstructPacket(data[i], buffers); } } else if (typeof data === 'object') { for (var key in data) { data[key] = _reconstructPacket(data[key], buffers); } } return data; } /** * Asynchronously removes Blobs or Files from data via * FileReader's readAsArrayBuffer method. Used before encoding * data as msgpack. Calls callback with the blobless data. * * @param {Object} data * @param {Function} callback * @api private */ exports.removeBlobs = function(data, callback) { function _removeBlobs(obj, curKey, containingObject) { if (!obj) return obj; // convert any blob if ((withNativeBlob && obj instanceof Blob) || (withNativeFile && obj instanceof File)) { pendingBlobs++; // async filereader var fileReader = new FileReader(); fileReader.onload = function() { // this.result == arraybuffer if (containingObject) { containingObject[curKey] = this.result; } else { bloblessData = this.result; } // if nothing pending its callback time if(! --pendingBlobs) { callback(bloblessData); } }; fileReader.readAsArrayBuffer(obj); // blob -> arraybuffer } else if (isArray(obj)) { // handle array for (var i = 0; i < obj.length; i++) { _removeBlobs(obj[i], i, obj); } } else if (typeof obj === 'object' && !isBuf(obj)) { // and object for (var key in obj) { _removeBlobs(obj[key], key, obj); } } } var pendingBlobs = 0; var bloblessData = data; _removeBlobs(bloblessData); if (!pendingBlobs) { callback(bloblessData); } }; socket.io-parser-3.4.0/index.js000066400000000000000000000175511354111242300163600ustar00rootroot00000000000000 /** * Module dependencies. */ var debug = require('debug')('socket.io-parser'); var Emitter = require('component-emitter'); var binary = require('./binary'); var isArray = require('isarray'); var isBuf = require('./is-buffer'); /** * Protocol version. * * @api public */ exports.protocol = 4; /** * Packet types. * * @api public */ exports.types = [ 'CONNECT', 'DISCONNECT', 'EVENT', 'ACK', 'ERROR', 'BINARY_EVENT', 'BINARY_ACK' ]; /** * Packet type `connect`. * * @api public */ exports.CONNECT = 0; /** * Packet type `disconnect`. * * @api public */ exports.DISCONNECT = 1; /** * Packet type `event`. * * @api public */ exports.EVENT = 2; /** * Packet type `ack`. * * @api public */ exports.ACK = 3; /** * Packet type `error`. * * @api public */ exports.ERROR = 4; /** * Packet type 'binary event' * * @api public */ exports.BINARY_EVENT = 5; /** * Packet type `binary ack`. For acks with binary arguments. * * @api public */ exports.BINARY_ACK = 6; /** * Encoder constructor. * * @api public */ exports.Encoder = Encoder; /** * Decoder constructor. * * @api public */ exports.Decoder = Decoder; /** * A socket.io Encoder instance * * @api public */ function Encoder() {} var ERROR_PACKET = exports.ERROR + '"encode error"'; /** * Encode a packet as a single string if non-binary, or as a * buffer sequence, depending on packet type. * * @param {Object} obj - packet object * @param {Function} callback - function to handle encodings (likely engine.write) * @return Calls callback with Array of encodings * @api public */ Encoder.prototype.encode = function(obj, callback){ debug('encoding packet %j', obj); if (exports.BINARY_EVENT === obj.type || exports.BINARY_ACK === obj.type) { encodeAsBinary(obj, callback); } else { var encoding = encodeAsString(obj); callback([encoding]); } }; /** * Encode packet as string. * * @param {Object} packet * @return {String} encoded * @api private */ function encodeAsString(obj) { // first is type var str = '' + obj.type; // attachments if we have them if (exports.BINARY_EVENT === obj.type || exports.BINARY_ACK === obj.type) { str += obj.attachments + '-'; } // if we have a namespace other than `/` // we append it followed by a comma `,` if (obj.nsp && '/' !== obj.nsp) { str += obj.nsp + ','; } // immediately followed by the id if (null != obj.id) { str += obj.id; } // json data if (null != obj.data) { var payload = tryStringify(obj.data); if (payload !== false) { str += payload; } else { return ERROR_PACKET; } } debug('encoded %j as %s', obj, str); return str; } function tryStringify(str) { try { return JSON.stringify(str); } catch(e){ return false; } } /** * Encode packet as 'buffer sequence' by removing blobs, and * deconstructing packet into object with placeholders and * a list of buffers. * * @param {Object} packet * @return {Buffer} encoded * @api private */ function encodeAsBinary(obj, callback) { function writeEncoding(bloblessData) { var deconstruction = binary.deconstructPacket(bloblessData); var pack = encodeAsString(deconstruction.packet); var buffers = deconstruction.buffers; buffers.unshift(pack); // add packet info to beginning of data list callback(buffers); // write all the buffers } binary.removeBlobs(obj, writeEncoding); } /** * A socket.io Decoder instance * * @return {Object} decoder * @api public */ function Decoder() { this.reconstructor = null; } /** * Mix in `Emitter` with Decoder. */ Emitter(Decoder.prototype); /** * Decodes an encoded packet string into packet JSON. * * @param {String} obj - encoded packet * @return {Object} packet * @api public */ Decoder.prototype.add = function(obj) { var packet; if (typeof obj === 'string') { packet = decodeString(obj); if (exports.BINARY_EVENT === packet.type || exports.BINARY_ACK === packet.type) { // binary packet's json this.reconstructor = new BinaryReconstructor(packet); // no attachments, labeled binary but no binary data to follow if (this.reconstructor.reconPack.attachments === 0) { this.emit('decoded', packet); } } else { // non-binary full packet this.emit('decoded', packet); } } else if (isBuf(obj) || obj.base64) { // raw binary data if (!this.reconstructor) { throw new Error('got binary data when not reconstructing a packet'); } else { packet = this.reconstructor.takeBinaryData(obj); if (packet) { // received final buffer this.reconstructor = null; this.emit('decoded', packet); } } } else { throw new Error('Unknown type: ' + obj); } }; /** * Decode a packet String (JSON data) * * @param {String} str * @return {Object} packet * @api private */ function decodeString(str) { var i = 0; // look up type var p = { type: Number(str.charAt(0)) }; if (null == exports.types[p.type]) { return error('unknown packet type ' + p.type); } // look up attachments if type binary if (exports.BINARY_EVENT === p.type || exports.BINARY_ACK === p.type) { var buf = ''; while (str.charAt(++i) !== '-') { buf += str.charAt(i); if (i == str.length) break; } if (buf != Number(buf) || str.charAt(i) !== '-') { throw new Error('Illegal attachments'); } p.attachments = Number(buf); } // look up namespace (if any) if ('/' === str.charAt(i + 1)) { p.nsp = ''; while (++i) { var c = str.charAt(i); if (',' === c) break; p.nsp += c; if (i === str.length) break; } } else { p.nsp = '/'; } // look up id var next = str.charAt(i + 1); if ('' !== next && Number(next) == next) { p.id = ''; while (++i) { var c = str.charAt(i); if (null == c || Number(c) != c) { --i; break; } p.id += str.charAt(i); if (i === str.length) break; } p.id = Number(p.id); } // look up json data if (str.charAt(++i)) { var payload = tryParse(str.substr(i)); var isPayloadValid = payload !== false && (p.type === exports.ERROR || isArray(payload)); if (isPayloadValid) { p.data = payload; } else { return error('invalid payload'); } } debug('decoded %s as %j', str, p); return p; } function tryParse(str) { try { return JSON.parse(str); } catch(e){ return false; } } /** * Deallocates a parser's resources * * @api public */ Decoder.prototype.destroy = function() { if (this.reconstructor) { this.reconstructor.finishedReconstruction(); } }; /** * A manager of a binary event's 'buffer sequence'. Should * be constructed whenever a packet of type BINARY_EVENT is * decoded. * * @param {Object} packet * @return {BinaryReconstructor} initialized reconstructor * @api private */ function BinaryReconstructor(packet) { this.reconPack = packet; this.buffers = []; } /** * Method to be called when binary data received from connection * after a BINARY_EVENT packet. * * @param {Buffer | ArrayBuffer} binData - the raw binary data received * @return {null | Object} returns null if more binary data is expected or * a reconstructed packet object if all buffers have been received. * @api private */ BinaryReconstructor.prototype.takeBinaryData = function(binData) { this.buffers.push(binData); if (this.buffers.length === this.reconPack.attachments) { // done with buffer list var packet = binary.reconstructPacket(this.reconPack, this.buffers); this.finishedReconstruction(); return packet; } return null; }; /** * Cleans up binary packet reconstruction variables. * * @api private */ BinaryReconstructor.prototype.finishedReconstruction = function() { this.reconPack = null; this.buffers = []; }; function error(msg) { return { type: exports.ERROR, data: 'parser error: ' + msg }; } socket.io-parser-3.4.0/is-buffer.js000066400000000000000000000011001354111242300171120ustar00rootroot00000000000000 module.exports = isBuf; var withNativeBuffer = typeof Buffer === 'function' && typeof Buffer.isBuffer === 'function'; var withNativeArrayBuffer = typeof ArrayBuffer === 'function'; var isView = function (obj) { return typeof ArrayBuffer.isView === 'function' ? ArrayBuffer.isView(obj) : (obj.buffer instanceof ArrayBuffer); }; /** * Returns true if obj is a buffer or an arraybuffer. * * @api private */ function isBuf(obj) { return (withNativeBuffer && Buffer.isBuffer(obj)) || (withNativeArrayBuffer && (obj instanceof ArrayBuffer || isView(obj))); } socket.io-parser-3.4.0/package.json000066400000000000000000000011701354111242300171670ustar00rootroot00000000000000{ "name": "socket.io-parser", "version": "3.4.0", "description": "socket.io protocol parser", "repository": { "type": "git", "url": "https://github.com/Automattic/socket.io-parser.git" }, "files": [ "binary.js", "index.js", "is-buffer.js" ], "dependencies": { "debug": "~4.1.0", "component-emitter": "1.2.1", "isarray": "2.0.1" }, "devDependencies": { "benchmark": "2.1.2", "expect.js": "0.3.1", "mocha": "3.2.0", "socket.io-browsers": "^1.0.0", "zuul": "3.11.1", "zuul-ngrok": "4.0.0" }, "scripts": { "test": "make test" }, "license": "MIT" } socket.io-parser-3.4.0/test/000077500000000000000000000000001354111242300156615ustar00rootroot00000000000000socket.io-parser-3.4.0/test/arraybuffer.js000066400000000000000000000036121354111242300205310ustar00rootroot00000000000000var parser = require('../index.js'); var expect = require('expect.js'); var helpers = require('./helpers.js'); var encoder = new parser.Encoder(); describe('parser', function() { it('encodes an ArrayBuffer', function() { var packet = { type: parser.BINARY_EVENT, data: ['a', new ArrayBuffer(2)], id: 0, nsp: '/' }; helpers.test_bin(packet); }); it('encodes a TypedArray', function() { var array = new Uint8Array(5); for (var i = 0; i < array.length; i++) array[i] = i; var packet = { type: parser.BINARY_EVENT, data: ['a', array], id: 0, nsp: '/' }; helpers.test_bin(packet); }); it('encodes ArrayBuffers deep in JSON', function() { var packet = { type: parser.BINARY_EVENT, data: ['a', {a: 'hi', b: {why: new ArrayBuffer(3)}, c: {a: 'bye', b: { a: new ArrayBuffer(6)}}}], id: 999, nsp: '/deep' }; helpers.test_bin(packet); }); it('encodes deep binary JSON with null values', function() { var packet = { type: parser.BINARY_EVENT, data: ['a', {a: 'b', c: 4, e: {g: null}, h: new ArrayBuffer(9)}], nsp: '/', id: 600 }; helpers.test_bin(packet); }); it('cleans itself up on close', function() { var packet = { type: parser.BINARY_EVENT, data: [new ArrayBuffer(2), new ArrayBuffer(3)], id: 0, nsp: '/' }; encoder.encode(packet, function(encodedPackets) { var decoder = new parser.Decoder(); decoder.on('decoded', function(packet) { throw new Error("received a packet when not all binary data was sent."); }); decoder.add(encodedPackets[0]); // add metadata decoder.add(encodedPackets[1]); // add first attachment decoder.destroy(); // destroy before all data added expect(decoder.reconstructor.buffers.length).to.be(0); // expect that buffer is clean }); }); }); socket.io-parser-3.4.0/test/blob.js000066400000000000000000000032041354111242300171340ustar00rootroot00000000000000var parser = require('../index.js'); var helpers = require('./helpers.js'); var BlobBuilder = typeof BlobBuilder !== 'undefined' ? BlobBuilder : typeof WebKitBlobBuilder !== 'undefined' ? WebKitBlobBuilder : typeof MSBlobBuilder !== 'undefined' ? MSBlobBuilder : typeof MozBlobBuilder !== 'undefined' ? MozBlobBuilder : false; describe('parser', function() { it('encodes a Blob', function() { var data; if (BlobBuilder) { var bb = new BlobBuilder(); bb.append(new ArrayBuffer(2)); data = bb.getBlob(); } else { data = new Blob([new ArrayBuffer(2)]); } var packet = { type: parser.BINARY_EVENT, data: data, id: 0, nsp: '/' }; helpers.test_bin(packet); }); it('encodes an Blob deep in JSON', function() { var data; if (BlobBuilder) { var bb = new BlobBuilder(); bb.append(new ArrayBuffer(2)); data = bb.getBlob(); } else { data = new Blob([new ArrayBuffer(2)]); } var packet = { type: parser.BINARY_EVENT, data: {a: 'hi', b: { why: data }, c: 'bye'}, id: 999, nsp: '/deep' }; helpers.test_bin(packet); }); it('encodes a binary ack with a blob', function() { var data; if (BlobBuilder) { var bb = new BlobBuilder(); bb.append(new ArrayBuffer(2)); data = bb.getBlob(); } else { data = new Blob([new ArrayBuffer(2)]); } var packet = { type: parser.BINARY_ACK, data: {a: 'hi ack', b: { why: data }, c: 'bye ack'}, id: 999, nsp: '/deep' }; helpers.test_bin(packet); }) }); socket.io-parser-3.4.0/test/buffer.js000066400000000000000000000011411354111242300174650ustar00rootroot00000000000000var parser = require('../index.js'); var expect = require('expect.js'); var helpers = require('./helpers.js'); var encode = parser.encode; var decode = parser.decode; describe('parser', function() { it('encodes a Buffer', function() { helpers.test_bin({ type: parser.BINARY_EVENT, data: ['a', new Buffer('abc', 'utf8')], id: 23, nsp: '/cool' }); }); it('encodes a binary ack with Buffer', function() { helpers.test_bin({ type: parser.BINARY_ACK, data: ['a', new Buffer('xxx', 'utf8'), {}], id: 127, nsp: '/back' }) }); }); socket.io-parser-3.4.0/test/helpers.js000066400000000000000000000024251354111242300176640ustar00rootroot00000000000000var parser = require('../index.js'); var expect = require('expect.js'); var encoder = new parser.Encoder(); // tests encoding and decoding a single packet module.exports.test = function(obj){ encoder.encode(obj, function(encodedPackets) { var decoder = new parser.Decoder(); decoder.on('decoded', function(packet) { expect(packet).to.eql(obj); }); decoder.add(encodedPackets[0]); }); } // tests encoding of binary packets module.exports.test_bin = function test_bin(obj) { var originalData = obj.data; encoder.encode(obj, function(encodedPackets) { var decoder = new parser.Decoder(); decoder.on('decoded', function(packet) { obj.data = originalData; obj.attachments = undefined; expect(obj).to.eql(packet); }); for (var i = 0; i < encodedPackets.length; i++) { decoder.add(encodedPackets[i]); } }); } // array buffer's slice is native code that is not transported across // socket.io via msgpack, so regular .eql fails module.exports.testArrayBuffers = function(buf1, buf2) { buf1.slice = undefined; buf2.slice = undefined; expect(buf1).to.eql(buf2); } module.exports.testPacketMetadata = function(p1, p2) { expect(p1.type).to.eql(p2.type); expect(p1.id).to.eql(p2.id); expect(p1.nsp).to.eql(p2.nsp); } socket.io-parser-3.4.0/test/index.js000066400000000000000000000015401354111242300173260ustar00rootroot00000000000000var env = require('./support/env.js'); var blobSupported = (function() { try { new Blob(['hi']); return true; } catch(e) {} return false; })(); /** * Create a blob builder even when vendor prefixes exist */ var BlobBuilder = typeof BlobBuilder !== 'undefined' ? BlobBuilder : typeof WebKitBlobBuilder !== 'undefined' ? WebKitBlobBuilder : typeof MSBlobBuilder !== 'undefined' ? MSBlobBuilder : typeof MozBlobBuilder !== 'undefined' ? MozBlobBuilder : false; var blobBuilderSupported = !!BlobBuilder && !!BlobBuilder.prototype.append && !!BlobBuilder.prototype.getBlob; require('./parser.js'); if (!env.browser) { require('./buffer.js'); } if (typeof ArrayBuffer !== 'undefined') { require('./arraybuffer.js'); } if (blobSupported || blobBuilderSupported) { require('./blob.js'); } socket.io-parser-3.4.0/test/parser.js000066400000000000000000000041311354111242300175120ustar00rootroot00000000000000var parser = require('../index.js'); var expect = require('expect.js'); var helpers = require('./helpers.js'); describe('parser', function(){ it('exposes types', function(){ expect(parser.CONNECT).to.be.a('number'); expect(parser.DISCONNECT).to.be.a('number'); expect(parser.EVENT).to.be.a('number'); expect(parser.ACK).to.be.a('number'); expect(parser.ERROR).to.be.a('number'); expect(parser.BINARY_EVENT).to.be.a('number'); expect(parser.BINARY_ACK).to.be.a('number'); }); it('encodes connection', function(){ helpers.test({ type: parser.CONNECT, nsp: '/woot' }); }); it('encodes disconnection', function(){ helpers.test({ type: parser.DISCONNECT, nsp: '/woot' }); }); it('encodes an event', function(){ helpers.test({ type: parser.EVENT, data: ['a', 1, {}], nsp: '/' }); helpers.test({ type: parser.EVENT, data: ['a', 1, {}], id: 1, nsp: '/test' }); }); it('encodes an ack', function(){ helpers.test({ type: parser.ACK, data: ['a', 1, {}], id: 123, nsp: '/' }); }); it('encodes an error', function(){ helpers.test({ type: parser.ERROR, data: 'Unauthorized', nsp: '/' }); }); it('properly handles circular objects', function() { var a = {}; a.b = a; var data = { type: parser.EVENT, data: a, id: 1, nsp: '/' } var encoder = new parser.Encoder(); encoder.encode(data, function(encodedPackets) { expect(encodedPackets[0]).to.be('4"encode error"'); }); }); it('decodes a bad binary packet', function(){ try { var decoder = new parser.Decoder(); decoder.add('5'); } catch(e){ expect(e.message).to.match(/Illegal/); } }); it('returns an error packet on parsing error', function(done){ var decoder = new parser.Decoder(); decoder.on('decoded', function(packet) { expect(packet).to.eql({ type: 4, data: 'parser error: invalid payload' }); done(); }); decoder.add('442["some","data"'); }); }); socket.io-parser-3.4.0/test/support/000077500000000000000000000000001354111242300173755ustar00rootroot00000000000000socket.io-parser-3.4.0/test/support/env.js000066400000000000000000000003551354111242300205260ustar00rootroot00000000000000// WARNING this is bad practice // we only do this in our tests because we need to test engine.io-client // support in browsers and in node.js // some tests do not yet work in both module.exports.browser = typeof window !== 'undefined'; socket.io-parser-3.4.0/zuul.config.js000066400000000000000000000014471354111242300175110ustar00rootroot00000000000000'use strict'; var browsers = require('socket.io-browsers'); var zuulConfig = module.exports = { ui: 'mocha-bdd', // test on localhost by default local: true, concurrency: 2, // ngrok only accepts two tunnels by default // if browser does not sends output in 120s since last output: // stop testing, something is wrong browser_output_timeout: 120 * 1000, browser_open_timeout: 60 * 4 * 1000, // we want to be notified something is wrong asap, so no retry browser_retries: 1 }; if (process.env.CI === 'true') { zuulConfig.local = false; zuulConfig.tunnel = { type: 'ngrok', bind_tls: true }; } var isPullRequest = process.env.TRAVIS_PULL_REQUEST && process.env.TRAVIS_PULL_REQUEST !== 'false'; zuulConfig.browsers = isPullRequest ? browsers.pullRequest : browsers.all;