From 0cb729dcaa122b6e84bc2a1fbde2529e273b6271 Mon Sep 17 00:00:00 2001 From: Ilya Grigorik Date: Fri, 5 Jul 2013 22:33:02 -0700 Subject: [PATCH 01/17] add 'peerjs' bin script for simple(r) bootstrap --- bin/peerjs | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++ package.json | 3 ++- 2 files changed, 73 insertions(+), 1 deletion(-) create mode 100755 bin/peerjs diff --git a/bin/peerjs b/bin/peerjs new file mode 100755 index 0000000..83ba95a --- /dev/null +++ b/bin/peerjs @@ -0,0 +1,71 @@ +#!/usr/bin/env node + +var path = require('path') + , pkg = require('../package.json') + , fs = require('fs') + , version = pkg.version + , PeerServer = require('../lib/server').PeerServer + , opts = require('optimist') + .usage('Usage: $0') + .options({ + debug: { + demand: false, + alias: 'd', + description: 'debug', + default: false + }, + timeout: { + demand: false, + alias: 't', + description: 'timeout (milliseconds)', + default: 5000 + }, + ip_limit: { + demand: false, + alias: 'i', + description: 'IP limit', + default: 5000 + }, + concurrent_limit: { + demand: false, + alias: 'c', + description: 'concurrent limit', + default: 5000 + }, + key: { + demand: false, + alias: 'k', + description: 'connection key', + default: 'peerjs' + }, + sslkey: { + demand: false, + description: 'path to SSL key' + }, + sslcert: { + demand: false, + description: 'path to SSL certificate' + }, + port: { + demand: true, + alias: 'p', + description: 'port', + } + }).argv; + +opts.version = version; + +if (opts.sslkey && opts.sslcert) { + opts['ssl'] = {}; + opts.ssl['key'] = fs.readFileSync(path.resolve(opts.sslkey)); + opts.ssl['certificate'] = fs.readFileSync(path.resolve(opts.sslcert)); +} + +process.on('uncaughtException', function(e) { + console.error('Error: ' + e); +}); + +var server = new PeerServer(opts); +console.log( + "Started PeerServer, port: " + opts.port + (" (v. %s)"), version +); diff --git a/package.json b/package.json index 2da52db..0dbed8d 100644 --- a/package.json +++ b/package.json @@ -11,6 +11,7 @@ "license": "MIT", "dependencies": { "restify": "~2.3.5", - "ws": "~0.4.25" + "ws": "~0.4.25", + "optimist": "*" } } From 101a033fca75c6ee480081b84d2766ddb61e6eb6 Mon Sep 17 00:00:00 2001 From: Ilya Grigorik Date: Fri, 5 Jul 2013 22:35:55 -0700 Subject: [PATCH 02/17] update readme with bin script example --- README.md | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 9fc4515..4ed22c8 100644 --- a/README.md +++ b/README.md @@ -12,12 +12,22 @@ PeerServer helps broker connections between PeerJS clients. Data is not proxied Install the library: - npm install peer +```bash +$> npm install peer +``` Run the server: - var PeerServer = require('peer').PeerServer; - var server = new PeerServer({ port: 9000 }); +```bash +$> peerjs -p 9000 --key mykey +``` + +Or, create a custom server: + +```javascript +var PeerServer = require('peer').PeerServer; +var server = new PeerServer({ port: 9000 }); +``` Connecting to the server from PeerJS: From 443680f1398f3f60570544fade9a42785c2db3dc Mon Sep 17 00:00:00 2001 From: Ilya Grigorik Date: Fri, 5 Jul 2013 22:42:30 -0700 Subject: [PATCH 03/17] fix ip lookup --- lib/server.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/server.js b/lib/server.js index 5cf2572..9bea262 100644 --- a/lib/server.js +++ b/lib/server.js @@ -73,7 +73,7 @@ PeerServer.prototype._initializeWSS = function() { socket.close(); return; } - + if (!self._clients[key] || !self._clients[key][id]) { self._checkKey(key, ip, function(err) { if (!err) { @@ -203,7 +203,7 @@ PeerServer.prototype._initializeHTTP = function() { var id = req.params.id; var token = req.params.token; var key = req.params.key; - var ip = req.ip; + var ip = req.connection.remoteAddress; if (!self._clients[key] || !self._clients[key][id]) { self._checkKey(key, ip, function(err) { @@ -307,7 +307,7 @@ PeerServer.prototype._pruneOutstanding = function() { var keys = Object.keys(this._outstanding); for (var k = 0, kk = keys.length; k < kk; k += 1) { var key = keys[k]; - var dsts = Object.keys(this._outstanding[key]); + var dsts = Object.keys(this._outstanding[key]); for (var i = 0, ii = dsts.length; i < ii; i += 1) { var offers = this._outstanding[key][dsts[i]]; var seen = {}; From c2bcd2cf1715540bd4f9bb221f6469bcf52d2574 Mon Sep 17 00:00:00 2001 From: Ilya Grigorik Date: Sat, 6 Jul 2013 11:26:37 -0700 Subject: [PATCH 04/17] woops, forgot the bin script in package.json --- package.json | 1 + 1 file changed, 1 insertion(+) diff --git a/package.json b/package.json index 0dbed8d..d926e79 100644 --- a/package.json +++ b/package.json @@ -3,6 +3,7 @@ "version": "0.1.6", "description": "Peer-to-peer data in browsers", "main": "lib/server.js", + "bin": { "peerjs": "./bin/peerjs" }, "repository": { "type": "git", "url": "git://github.com/peers/peerjs-server.git" From f9c2172c8e618a6e2258fa91fb57e3860e2415ab Mon Sep 17 00:00:00 2001 From: Ilya Grigorik Date: Sat, 6 Jul 2013 11:28:21 -0700 Subject: [PATCH 05/17] use longform port flag + consistent formatting --- README.md | 32 ++++++++++++++++++-------------- 1 file changed, 18 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 4ed22c8..a212387 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ $> npm install peer Run the server: ```bash -$> peerjs -p 9000 --key mykey +$> peerjs --port 9000 --key peerjs ``` Or, create a custom server: @@ -31,23 +31,27 @@ var server = new PeerServer({ port: 9000 }); Connecting to the server from PeerJS: - +```html + +``` Using HTTPS: Simply pass in PEM-encoded certificate and key. - var fs = require('fs'); - var PeerServer = require('peer').PeerServer; +```javascript +var fs = require('fs'); +var PeerServer = require('peer').PeerServer; - var server = new PeerServer({ - port: 9000, - ssl: { - key: fs.readFileSync('/path/to/your/ssl/key/here.key'), - certificate: fs.readFileSync('/path/to/your/ssl/certificate/here.crt') - } - }); +var server = new PeerServer({ + port: 9000, + ssl: { + key: fs.readFileSync('/path/to/your/ssl/key/here.key'), + certificate: fs.readFileSync('/path/to/your/ssl/certificate/here.crt') + } +}); +``` ## Problems? From 5a37679a402eeac87f62f3860ba018abcfbb97ff Mon Sep 17 00:00:00 2001 From: Michelle Bu Date: Sat, 6 Jul 2013 11:53:15 -0700 Subject: [PATCH 06/17] Up version for npm --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index d926e79..19e9c3f 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "peer", - "version": "0.1.6", + "version": "0.2.0", "description": "Peer-to-peer data in browsers", "main": "lib/server.js", "bin": { "peerjs": "./bin/peerjs" }, From 6140fb391dc1a76cc526108171dfdef4f44aea99 Mon Sep 17 00:00:00 2001 From: Michelle Bu Date: Sat, 6 Jul 2013 22:33:13 -0700 Subject: [PATCH 07/17] Optional options --- lib/util.js | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/util.js b/lib/util.js index 01b0e89..fbd7ab6 100644 --- a/lib/util.js +++ b/lib/util.js @@ -13,6 +13,7 @@ var util = { }); }, extend: function(dest, source) { + source = source || {} for(var key in source) { if(source.hasOwnProperty(key)) { dest[key] = source[key]; From c9e647609463dc338c55135690dde28a3f52c77f Mon Sep 17 00:00:00 2001 From: Michelle Bu Date: Sat, 6 Jul 2013 22:43:49 -0700 Subject: [PATCH 08/17] Test suite skeleton. Closes #6 --- package.json | 5 ++++ test/server.js | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+) create mode 100644 test/server.js diff --git a/package.json b/package.json index 19e9c3f..faddbe4 100644 --- a/package.json +++ b/package.json @@ -14,5 +14,10 @@ "restify": "~2.3.5", "ws": "~0.4.25", "optimist": "*" + }, + "devDependencies": { + "expect.js": "*", + "sinon": "*", + "mocha": "*" } } diff --git a/test/server.js b/test/server.js new file mode 100644 index 0000000..cbcc576 --- /dev/null +++ b/test/server.js @@ -0,0 +1,68 @@ +var PeerServer = require('../').PeerServer; +var expect = require('expect.js'); +var sinon = require('sinon'); + +describe('PeerServer', function() { + describe('constructor', function() { + before(function() { + PeerServer.prototype._initializeWSS = sinon.stub(); + PeerServer.prototype._initializeHTTP = sinon.stub(); + }); + + it('should be able to be created without the `new` keyword', function() { + var p = PeerServer(); + expect(p.constructor).to.be(PeerServer); + }); + + it('should default to port 80, key `peerjs`', function() { + var p = new PeerServer(); + expect(p._options.key).to.be('peerjs'); + expect(p._options.port).to.be(80); + }); + + it('should accept a custom port', function() { + var p = new PeerServer({ port: 8000 }); + expect(p._options.port).to.be(8000); + }); + }); + + describe('#_initializeWSS', function() { + + }); + + describe('#_configureWS', function() { + + }); + + describe('#_checkKey', function() { + + }); + + describe('#_initializeHTTP', function() { + + }); + + describe('#_startStreaming', function() { + + }); + + describe('#_pruneOutstanding', function() { + + }); + + describe('#_processOutstanding', function() { + + }); + + describe('#_removePeer', function() { + + }); + + describe('#_handleTransmission', function() { + + }); + + describe('#_generateClientId', function() { + + }); +}); From f4c86ef4d259d5ba68b728ead044f9bdb7818597 Mon Sep 17 00:00:00 2001 From: Michelle Bu Date: Sat, 6 Jul 2013 22:48:42 -0700 Subject: [PATCH 09/17] Add test directives --- .travis.yml | 4 ++++ package.json | 3 +++ 2 files changed, 7 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..895dbd3 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,4 @@ +language: node_js +node_js: + - 0.6 + - 0.8 diff --git a/package.json b/package.json index faddbe4..b5f3f45 100644 --- a/package.json +++ b/package.json @@ -19,5 +19,8 @@ "expect.js": "*", "sinon": "*", "mocha": "*" + }, + "scripts": { + "test": "mocha test" } } From 5f2e6753f48bc9216a92c8839daddee9de9796aa Mon Sep 17 00:00:00 2001 From: Michelle Bu Date: Sat, 6 Jul 2013 22:51:29 -0700 Subject: [PATCH 10/17] build --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index a212387..d08ded5 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,5 @@ +[![Build Status](https://travis-ci.org/peers/peerjs-server.png?branch=master)](https://travis-ci.org/peers/peerjs-server) + # PeerJS Server: Server component for PeerJS # PeerServer helps broker connections between PeerJS clients. Data is not proxied through the server. From 102b39f06633a676615cc5e3b5efaa0a01cc5229 Mon Sep 17 00:00:00 2001 From: Michelle Bu Date: Sat, 6 Jul 2013 22:52:56 -0700 Subject: [PATCH 11/17] change version --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 895dbd3..09d3ef3 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,4 @@ language: node_js node_js: - - 0.6 - 0.8 + - 0.10 From 6a1b20f80ea2aff57dae5e8c59998d139f886778 Mon Sep 17 00:00:00 2001 From: Michelle Bu Date: Sun, 7 Jul 2013 00:21:57 -0700 Subject: [PATCH 12/17] More test --- test/server.js | 47 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/test/server.js b/test/server.js index cbcc576..8a04bc5 100644 --- a/test/server.js +++ b/test/server.js @@ -27,6 +27,7 @@ describe('PeerServer', function() { }); describe('#_initializeWSS', function() { + WebSocketServer = sinon.stub(); }); @@ -35,6 +36,42 @@ describe('PeerServer', function() { }); describe('#_checkKey', function() { + var p; + before(function() { + PeerServer.prototype._initializeHTTP = sinon.stub(); + p = new PeerServer({ port: 8000 }); + p._checkKey('peerjs', 'myip', function() {}); + }); + + it('should reject keys that are not the default', function(done) { + p._checkKey('bad key', null, function(response) { + expect(response).to.be('Invalid key provided'); + done(); + }); + }); + + it('should accept valid key/ip pairs', function(done) { + p._checkKey('peerjs', 'myip', function(response) { + expect(response).to.be(null); + done(); + }); + }); + + it('should reject ips that are at their limit', function(done) { + p._options.ip_limit = 0; + p._checkKey('peerjs', 'myip', function(response) { + expect(response).to.be('myip has reached its concurrent user limit'); + done(); + }); + }); + + it('should reject when the server is at its limit', function(done) { + p._options.concurrent_limit = 0; + p._checkKey('peerjs', 'myip', function(response) { + expect(response).to.be('Server has reached its concurrent user limit'); + done(); + }); + }); }); @@ -59,10 +96,18 @@ describe('PeerServer', function() { }); describe('#_handleTransmission', function() { - + // TODO: this is probably the most important method to test. }); describe('#_generateClientId', function() { + var p; + before(function() { + PeerServer.prototype._initializeHTTP = sinon.stub(); + p = new PeerServer({ port: 8000 }); + }); + it('should generate a 16-character ID', function() { + expect(p._generateClientId('anykey').length).to.be(16); + }); }); }); From a146c7a5a292de0588e53d293c765c54021201b9 Mon Sep 17 00:00:00 2001 From: Michelle Bu Date: Sun, 7 Jul 2013 00:29:01 -0700 Subject: [PATCH 13/17] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index d08ded5..8568436 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ [![Build Status](https://travis-ci.org/peers/peerjs-server.png?branch=master)](https://travis-ci.org/peers/peerjs-server) -# PeerJS Server: Server component for PeerJS # +# PeerServer: A server for PeerJS # PeerServer helps broker connections between PeerJS clients. Data is not proxied through the server. From 72998056e04686cf513b285b839e0e08f3291b89 Mon Sep 17 00:00:00 2001 From: Michelle Bu Date: Tue, 9 Jul 2013 08:07:57 -0700 Subject: [PATCH 14/17] Match restify engine dependencies --- package.json | 3 +++ 1 file changed, 3 insertions(+) diff --git a/package.json b/package.json index b5f3f45..a4240f6 100644 --- a/package.json +++ b/package.json @@ -20,6 +20,9 @@ "sinon": "*", "mocha": "*" }, + "engines": { + "node": ">=0.8" + }, "scripts": { "test": "mocha test" } From 974f00c996629608c7bed681ae6dbcf3d867aec0 Mon Sep 17 00:00:00 2001 From: yosssi Date: Mon, 7 Oct 2013 10:22:14 +0900 Subject: [PATCH 15/17] fixed some syntax mistakes. --- lib/server.js | 16 ++++++++-------- lib/util.js | 2 +- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/lib/server.js b/lib/server.js index 9bea262..86c6e6c 100644 --- a/lib/server.js +++ b/lib/server.js @@ -49,7 +49,7 @@ function PeerServer(options) { this._ips = {}; this._setCleanupIntervals(); -}; +} util.inherits(PeerServer, EventEmitter); @@ -131,8 +131,8 @@ PeerServer.prototype._configureWS = function(socket, key, id, token) { // Clean up if a Peer sends a LEAVE. if (!message.dst) { self._removePeer(key, id); - break; } + break; // ICE candidates case 'CANDIDATE': // Offer or answer between peers. @@ -150,11 +150,11 @@ PeerServer.prototype._configureWS = function(socket, key, id, token) { util.prettyError('Message unrecognized'); } } catch(e) { - throw e; util.log('Invalid message', data); + throw e; } }); -} +}; PeerServer.prototype._checkKey = function(key, ip, cb) { @@ -181,14 +181,14 @@ PeerServer.prototype._checkKey = function(key, ip, cb) { } else { cb('Invalid key provided'); } -} +}; /** Initialize HTTP server routes. */ PeerServer.prototype._initializeHTTP = function() { var self = this; this._app.use(restify.bodyParser({ mapParams: false })); - this._app.use(restify.queryParser()) + this._app.use(restify.queryParser()); this._app.use(util.allowCrossDomain); // Retrieve guaranteed random ID. @@ -332,7 +332,7 @@ PeerServer.prototype._setCleanupIntervals = function() { var keys = Object.keys(self._ips); for (var i = 0, ii = keys.length; i < ii; i += 1) { var key = keys[i]; - if (self._ips[key] == 0) { + if (self._ips[key] === 0) { delete self._ips[key]; } } @@ -383,7 +383,7 @@ PeerServer.prototype._handleTransmission = function(key, message) { destination.res.write(data); } else { // Neither socket no res available. Peer dead? - throw "Peer dead" + throw "Peer dead"; } } catch (e) { // This happens when a peer disconnects without closing connections and diff --git a/lib/util.js b/lib/util.js index fbd7ab6..8a81cf1 100644 --- a/lib/util.js +++ b/lib/util.js @@ -13,7 +13,7 @@ var util = { }); }, extend: function(dest, source) { - source = source || {} + source = source || {}; for(var key in source) { if(source.hasOwnProperty(key)) { dest[key] = source[key]; From 32381d1f2f11d9de2dbdfc08f6741ae6c7e45443 Mon Sep 17 00:00:00 2001 From: yosssi Date: Mon, 7 Oct 2013 22:25:56 +0900 Subject: [PATCH 16/17] Deleted the unused variable. --- lib/server.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/server.js b/lib/server.js index 86c6e6c..4f8657c 100644 --- a/lib/server.js +++ b/lib/server.js @@ -21,8 +21,6 @@ function PeerServer(options) { util.debug = this._options.debug; - // Set up HTTPS server if key and certificate are provided. - var secure = this._options.ssl.key && this._options.ssl.certificate; // Print warning if only one of the two is given. if (Object.keys(this._options.ssl).length === 1) { util.prettyError('Warning: PeerServer will not run on an HTTPS server' From 5affb856d8a1b28f169dabca20aac5630f5cebe5 Mon Sep 17 00:00:00 2001 From: Michelle Bu Date: Fri, 18 Oct 2013 20:04:05 -0700 Subject: [PATCH 17/17] Remove ugly switch --- lib/server.js | 31 +++++++++---------------------- 1 file changed, 9 insertions(+), 22 deletions(-) diff --git a/lib/server.js b/lib/server.js index 4f8657c..0e5d087 100644 --- a/lib/server.js +++ b/lib/server.js @@ -124,28 +124,15 @@ PeerServer.prototype._configureWS = function(socket, key, id, token) { try { var message = JSON.parse(data); - switch (message.type) { - case 'LEAVE': - // Clean up if a Peer sends a LEAVE. - if (!message.dst) { - self._removePeer(key, id); - } - break; - // ICE candidates - case 'CANDIDATE': - // Offer or answer between peers. - case 'OFFER': - case 'ANSWER': - // Use the ID we know to be correct to prevent spoofing. - self._handleTransmission(key, { - type: message.type, - src: id, - dst: message.dst, - payload: message.payload - }); - break; - default: - util.prettyError('Message unrecognized'); + if (['LEAVE', 'CANDIDATE', 'OFFER', 'ANSWER'].indexOf(message.type) !== -1) { + self._handleTransmission(key, { + type: message.type, + src: id, + dst: message.dst, + payload: message.payload + }); + } else { + util.prettyError('Message unrecognized'); } } catch(e) { util.log('Invalid message', data);