diff --git a/lib/protocol/1.js b/lib/protocol/1.js index 15c6e08..f6d57f0 100644 --- a/lib/protocol/1.js +++ b/lib/protocol/1.js @@ -4,7 +4,52 @@ * MIT Licensed */ -var EventEmitter = require('events').EventEmitter; +var EventEmitter = this.EventEmitter || require('events').EventEmitter + , keys = Object.keys || (function polyfill () { + var has = Object.prototype.hasOwnProperty + , hasDontEnumBug = !{ toString: null }.propertyIsEnumerable('toString') + , DontEnums = [ + 'toString' + , 'toLocaleString' + , 'valueOf' + , 'hasOwnProperty' + , 'isPrototypeOf' + , 'propertyIsEnumerable' + , 'constructor' + ] + , DontEnumsLength = DontEnums.length; + + /** + * Return all the keys of the given object. + * + * @param {Object} o + * @returns {Array} + * @api public + */ + + return function keys (o) { + if (typeof o !== 'object' && typeof o !== 'function' || o === null) { + throw new TypeError('Object.keys called on a non-object'); + } + + var result = []; + for (var name in o) { + if (has.call(o, name)) { + result.push(name); + } + } + + if (hasDontEnumBug) { + for (var i = 0; i < DontEnumsLength; i++) { + if (has.call(o, DontEnums[i])) { + result.push(DontEnums[i]); + } + } + } + + return result; + }; + })(); /** * The protocol. @@ -20,9 +65,38 @@ function Protocol (encode, decode) { this.encode = encode || JSON.stringify; this.decode = decode || JSON.parse; + + EventEmitter.call(this); } -Protocol.prototype.__proto__ = EventEmitter.prototype; +Protocol.prototype = new EventEmitter; +Protocol.prototype.constructor = Protocol; + +/** + * A object of all protocol types with a mapping to it's index. + * + * @type {Object} + * @api private + */ + +Protocol.types = { + 'disconnect': 0 // disconnect initiated by server + , 'connect': 1 // successfull connection + , 'heartbeat': 2 // heartbeat signal + , 'codec': 3 // JavaScript Object encoded with a codec + , 'event': 4 // event for EventEmitter + , 'reboot': 5 // the server is rebooting + , 'error': 6 // error +}; + +/** + * A list of protocol types. + * + * @type {Array} + * @api private + */ + +Protocol.typelist = keys(Protocol.types); /** * Encode the message. @@ -54,8 +128,24 @@ Protocol.prototype.decode = function decode (message) { * @api private */ +Protocol.regexp = /(\d+)#(\d+)?#(\d+)?#/; Protocol.prototype.parse = function parse () { + var data + , type + , id + , length + , message; + + while (this.queue.length) { + data = this.queue.match(Protocol.regexp); + + // we don't have enough data yet to parse out the wire format + // or we don't have enough data yet to splice out all the information + if (!data || this.queue.length < +data[2]) break; + + } + this.emit('message'); }; /** diff --git a/lib/red.js b/lib/red.js index 8c69693..30b7506 100644 --- a/lib/red.js +++ b/lib/red.js @@ -358,6 +358,7 @@ RED.prototype.transport = function transport (data, request, response, head) { sessionid: data.session , connectionid: data.id , specification: data.query.callback || +data.query.specification || 0 + , protocol: new Protocol[data.protocol] }); // initialize the request diff --git a/tests/common.js b/tests/common.js index cab8c3a..796ec8c 100644 --- a/tests/common.js +++ b/tests/common.js @@ -8,9 +8,16 @@ * Expose globals that we would be using in most of the test suites. */ -RED = require('../'); -Engine = require('../lib/engine'); -request = require('request'); +global.RED = RED = require('../'); +global.Engine = Engine = require('../lib/engine'); +global.Protocols = Protocols = require('../lib/protocol'); + +/** + * Global dependencies + */ + +global.should = should = require('should'); +global.require = request = require('request'); /** * Helper tools diff --git a/tests/engine.test.js b/tests/engine.test.js index 6682191..e622885 100644 --- a/tests/engine.test.js +++ b/tests/engine.test.js @@ -66,13 +66,15 @@ describe('engine.js', function () { hostname: 'wtftrololol' }); - engine.connect(); - engine.on('error', function () {}); engine.once('connect failed', function (err) { + err.message.should.equal('Failed to establish a connection'); + engine.close(); next(); }); + + engine.connect(); }); }); diff --git a/tests/protocol.1.test.js b/tests/protocol.1.test.js new file mode 100644 index 0000000..4fd1f50 --- /dev/null +++ b/tests/protocol.1.test.js @@ -0,0 +1,31 @@ +describe('Protocol.1', function () { + var Protocol = Protocols['1']; + + it('should be exported as a function', function () { + Protocol.should.be.a('function'); + }); + + it('should initialize without any issues', function () { + var parser = new Protocol(); + }); + + it('should be a instance of EventEmitter', function () { + var parser = new Protocol(); + + if (!(parser instanceof process.EventEmitter)) { + should.fail('should be an EventEmitter'); + } + }); + + describe('#encode', function () { + + }); + + describe('#decode', function () { + + }); + + describe('#stream', function () { + + }); +}); diff --git a/tests/ssl/red-csr.pem b/tests/ssl/red-csr.pem new file mode 100644 index 0000000..c3a3937 --- /dev/null +++ b/tests/ssl/red-csr.pem @@ -0,0 +1,11 @@ +-----BEGIN CERTIFICATE REQUEST----- +MIIBhDCB7gIBADBFMQswCQYDVQQGEwJBVTETMBEGA1UECBMKU29tZS1TdGF0ZTEh +MB8GA1UEChMYSW50ZXJuZXQgV2lkZ2l0cyBQdHkgTHRkMIGfMA0GCSqGSIb3DQEB +AQUAA4GNADCBiQKBgQDDPFU8twQqH545fN4pdFQXGog/LvfrVpLdv+UBOuJkB6bP +evhR/WUn31uovmHMD5cKWvtc2zPH1ERYn/OLf6CnDrQQYmrbtiVB/Tzk/0RDrFei +DAHfxvtq9phuWjyqEOm1UzRAy/HZJjdrXgTF1xwJPBl+6nMTMQ+ddUAKICj+aQID +AQABoAAwDQYJKoZIhvcNAQEFBQADgYEAfsCljBwOpPI7fhyWtpOW/MXo2VRBd1av +wj+jr1fzCskshEHJeOM1CS2s2JjaN+I8ygSZBsE8gIIxT5Eu2S+fEY3FjDXlJk25 +hMZP03yKmNav1ULKbVwx05H0wGD1ht3xcDoY+OHfuLVYX/iQ8tCAXBEmmd0lX12X +o/Vc7IoVAuI= +-----END CERTIFICATE REQUEST----- diff --git a/transports/transport.js b/transports/transport.js index b890a25..90a679a 100644 --- a/transports/transport.js +++ b/transports/transport.js @@ -35,6 +35,9 @@ function Transport (engine, response, options) { // restrictions this.maxiumBuffer = 38400; + // protocol parser + this.protocol = null; + _.extend(this, options || {}); this.engine = engine;