From 914ac2dcc9cfec644b1df178fc5de223304a6062 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miroslav=20Bajto=C5=A1?= Date: Wed, 8 Jan 2014 15:20:17 +0100 Subject: [PATCH] Implement `app.listen` The method starts a http server on the host & port configured in the app config. --- lib/application.js | 50 ++++++++++++++++++++++++++++++++++++++ test/app.test.js | 60 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 110 insertions(+) diff --git a/lib/application.js b/lib/application.js index 76287efd..ddcdfdbd 100644 --- a/lib/application.js +++ b/lib/application.js @@ -439,3 +439,53 @@ function tryReadConfig(cwd, fileName) { } } + +/** + * Listen for connections and update the configured port. + * + * When there are no parameters or there is only one callback parameter, + * the server will listen on `app.get('host')` and `app.get('port')`. + * + * ```js + * // listen on host/port configured in app config + * app.listen(); + * ``` + * + * Otherwise all arguments are forwarded to `http.Server.listen`. + * + * ```js + * // listen on the specified port and all hosts, ignore app config + * app.listen(80); + * ``` + * + * The function also installs a `listening` callback that calls + * `app.set('port')` with the value returned by `server.address().port`. + * This way the port param contains always the real port number, even when + * listen was called with port number 0. + * + * @param {Function=} cb If specified, the callback will be added as a listener + * for the server's "listening" event. + * @returns {http.Server} A node `http.Server` with this application configured + * as the request handler. + */ +app.listen = function(cb) { + var self = this; + + var server = require('http').createServer(this); + + server.on('listening', function() { + self.set('port', this.address().port); + }); + + var useAppConfig = + arguments.length == 0 || + (arguments.length == 1 && typeof arguments[0] == 'function'); + + if (useAppConfig) { + server.listen(this.get('port'), this.get('host'), cb); + } else { + server.listen.apply(server, arguments); + } + + return server; +} diff --git a/test/app.test.js b/test/app.test.js index e8bd7df7..be1d4013 100644 --- a/test/app.test.js +++ b/test/app.test.js @@ -197,6 +197,66 @@ describe('app', function() { }); }); + describe('listen()', function() { + it('starts http server', function(done) { + var app = loopback(); + app.set('port', 0); + app.get('/', function(req, res) { res.send(200, 'OK'); }); + + var server = app.listen(); + + expect(server).to.be.an.instanceOf(require('http').Server); + + request(server) + .get('/') + .expect(200, done); + }); + + it('updates port on "listening" event', function(done) { + var app = loopback(); + app.set('port', 0); + + app.listen(function() { + expect(app.get('port'), 'port').to.not.equal(0); + done(); + }); + }); + + it('forwards to http.Server.listen on more than one arg', function(done) { + var app = loopback(); + app.set('port', 1); + app.listen(0, '127.0.0.1', function() { + expect(app.get('port'), 'port').to.not.equal(0).and.not.equal(1); + expect(this.address().address).to.equal('127.0.0.1'); + done(); + }); + }); + + it('forwards to http.Server.listen when the single arg is not a function', + function(done) { + var app = loopback(); + app.set('port', 1); + app.listen(0).on('listening', function() { + expect(app.get('port'), 'port') .to.not.equal(0).and.not.equal(1); + done(); + }); + } + ); + + it('uses app config when no parameter is supplied', function(done) { + var app = loopback(); + // Http listens on all interfaces by default + // Custom host serves as an indicator whether + // the value was used by app.listen + app.set('host', '127.0.0.1'); + app.listen() + .on('listening', function() { + expect(this.address().address).to.equal('127.0.0.1'); + done(); + }); + }); + }); + describe('app.get("/", loopback.status())', function () { it('should return the status of the application', function (done) { var app = loopback();