From 3e3636bf22616387ede53d6c74c025eebd1f0231 Mon Sep 17 00:00:00 2001 From: Tejas Shah Date: Fri, 20 Jan 2017 18:12:40 -0800 Subject: [PATCH 1/5] Added option to specify host address to bind servers to --- CHANGELOG.md | 1 + README.md | 8 ++++++-- index.js | 38 +++++++++++++++++++++++++++----------- 3 files changed, 34 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 32f8198..51e75d5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ### 2.3.2 (Next) +* [#36](https://github.com/alexa-js/alexa-app-server/pull/36): Added option to specify host address to bind servers to - [@tejashah88](https://github.com/tejashah88). * [#35](https://github.com/alexa-js/alexa-app-server/pull/35): Error occurs when `verify` and `debug` are both set to true - [@tejashah88](https://github.com/tejashah88). * [#34](https://github.com/alexa-js/alexa-app-server/pull/34): Added tests for fail cases and schemas/utterances - [@tejashah88](https://github.com/tejashah88). * [#34](https://github.com/alexa-js/alexa-app-server/pull/34): Fixed bug while trying to retrieve schema/utterances with GET request - [@tejashah88](https://github.com/tejashah88). diff --git a/README.md b/README.md index 52d6836..edd68a7 100644 --- a/README.md +++ b/README.md @@ -93,12 +93,16 @@ require('alexa-app-server').start({ // root of your web server. app_root: "/alexa/", - // The directory containing server-side processing modules (see below) + // The directory containing server-side processing modules (see below). server_dir: "server", - // The port the server should bind to + // The port the server should bind to. port: 80, + // The host address in which the server should bind to. If not specified, + // this argument will be ignored. + host_address: undefined, + // By default, GET requests to Alexa App endpoints will show the debugger // UI. This can be disabled. If 'verify' and 'debug' are both set to true, // an error will be thrown. diff --git a/index.js b/index.js index f767599..a1d01d9 100644 --- a/index.js +++ b/index.js @@ -84,6 +84,7 @@ var appServer = function(config) { if (config.verify) { self.express.use(endpoint, alexaVerifierMiddleware()); } + self.express.post(endpoint, function(req, res) { var json = req.body, response_json; @@ -126,6 +127,7 @@ var appServer = function(config) { self.error("Error loading app [" + main + "]: " + e); } }); + return self.apps; }; @@ -149,11 +151,13 @@ var appServer = function(config) { self.start = function() { // Instantiate up the server + //TODO: add i18n support (i18n-node might be a good look) self.express = express(); + //TODO: change this to make sure it doesn't affect other non-Alexa services/apps self.express.use(bodyParser.urlencoded({ extended: true })); //We need the rawBody for request verification - self.express.use(function(req, res, next) { + self.express.use(function(req, res, next) { //TODO: change code to possibly use bodyParser.json() // mark the request body as already having been parsed so it's ignored by // other body parser middlewares req._body = true; @@ -220,31 +224,43 @@ var appServer = function(config) { if (privateKey != undefined && certificate != undefined) { var credentials = { key: privateKey, cert: certificate }; - try { //The line below can fail it the certs were generated incorrectly. But we can continue startup without HTTPS - self.httpsInstance = https.createServer(credentials, self.express).listen(config.httpsPort); //create the HTTPS server - self.log("Listening on HTTPS port " + config.httpsPort); + try { // These two lines below can fail it the certs were generated incorrectly. But we can continue startup without HTTPS + var httpsServer = https.createServer(credentials, self.express); // create the HTTPS server + + //TODO: write tests to verify bindings to HTTPS port and host address + //TODO: add separate option to specify specific host address for HTTPS server to bind to ??? + if (typeof config.host_address === 'string') { + self.httpsInstance = httpsServer.listen(config.httpsPort, config.host_address); + self.log("Listening on HTTPS port " + config.httpsPort + " on address " + config.host_address); + } else { + self.httpsInstance = httpsServer.listen(config.httpsPort); + self.log("Listening on HTTPS port " + config.httpsPort); + } } catch (error) { self.error("Failed to listen via HTTPS Error: " + error); } } else { self.error("Failed to load privateKey or certificate from /sslcert. HTTPS will not be enabled"); - } - } else { self.error("privateKey: '" + config.privateKey + "' or certificate: '" + config.certificate + "' do not exist in /sslcert. HTTPS will not be enabled"); - } } else { self.error("privatekey, httpsPort, or certificate paramater not set in config. HTTPS will not be enabled"); - } - } + // Start the server listening config.port = config.port || process.env.port || 80; - self.httpInstance = self.express.listen(config.port); - self.log("Listening on HTTP port " + config.port); + + //TODO: write tests to verify bindings to port and host address + if (typeof config.host_address === 'string') { + self.httpInstance = self.express.listen(config.port, config.host_address); + self.log("Listening on HTTP port " + config.port + " on address " + config.host_address); + } else { + self.httpInstance = self.express.listen(config.port); + self.log("Listening on HTTP port " + config.port); + } // Run the post() method if defined if (typeof config.post == "function") { From 465d49f6c6762ef75b5398d45b8a300f1a5a3843 Mon Sep 17 00:00:00 2001 From: Tejas Shah Date: Fri, 20 Jan 2017 18:25:00 -0800 Subject: [PATCH 2/5] Added tests to verify server bindings with a given host address --- index.js | 2 - test/test-examples-server-custom-bindings.js | 41 ++++++++++++++++++++ 2 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 test/test-examples-server-custom-bindings.js diff --git a/index.js b/index.js index a1d01d9..6a1cf20 100644 --- a/index.js +++ b/index.js @@ -227,7 +227,6 @@ var appServer = function(config) { try { // These two lines below can fail it the certs were generated incorrectly. But we can continue startup without HTTPS var httpsServer = https.createServer(credentials, self.express); // create the HTTPS server - //TODO: write tests to verify bindings to HTTPS port and host address //TODO: add separate option to specify specific host address for HTTPS server to bind to ??? if (typeof config.host_address === 'string') { self.httpsInstance = httpsServer.listen(config.httpsPort, config.host_address); @@ -253,7 +252,6 @@ var appServer = function(config) { // Start the server listening config.port = config.port || process.env.port || 80; - //TODO: write tests to verify bindings to port and host address if (typeof config.host_address === 'string') { self.httpInstance = self.express.listen(config.port, config.host_address); self.log("Listening on HTTP port " + config.port + " on address " + config.host_address); diff --git a/test/test-examples-server-custom-bindings.js b/test/test-examples-server-custom-bindings.js new file mode 100644 index 0000000..3797707 --- /dev/null +++ b/test/test-examples-server-custom-bindings.js @@ -0,0 +1,41 @@ +/*jshint expr: true*/ +"use strict"; +var chai = require("chai"); +var expect = chai.expect; +chai.config.includeStack = true; +var request = require("supertest-as-promised"); +var alexaAppServer = require("../index"); + +describe("Alexa App Server with Examples & Custon Server Bindings", function() { + var testServer; + + afterEach(function() { + testServer.stop(); + }); + + it("mounts hello world app (HTTP only)", function() { + testServer = alexaAppServer.start({ + port: 3000, + host_address: "127.0.0.1", + server_root: 'examples' + }); + return request(testServer.express) + .get('/alexa/helloworld') + .expect(200); + }); + + it("mounts hello world app (HTTP & HTTPS)", function() { + testServer = alexaAppServer.start({ + port: 3000, + host_address: "127.0.0.1", + server_root: 'examples', + httpsPort: 6000, + privateKey: 'private-key.pem', + certificate: 'cert.cer' + }); + + return request(testServer.express) + .get('/alexa/helloworld') + .expect(200); + }); +}); \ No newline at end of file From 4e8481800c246cb4a77520472d558d20d042f0fa Mon Sep 17 00:00:00 2001 From: Tejas Shah Date: Fri, 20 Jan 2017 18:29:07 -0800 Subject: [PATCH 3/5] forgot to enable https for second part of host address binding test --- test/test-examples-server-custom-bindings.js | 1 + 1 file changed, 1 insertion(+) diff --git a/test/test-examples-server-custom-bindings.js b/test/test-examples-server-custom-bindings.js index 3797707..8dae124 100644 --- a/test/test-examples-server-custom-bindings.js +++ b/test/test-examples-server-custom-bindings.js @@ -29,6 +29,7 @@ describe("Alexa App Server with Examples & Custon Server Bindings", function() { port: 3000, host_address: "127.0.0.1", server_root: 'examples', + httpsEnabled: true, httpsPort: 6000, privateKey: 'private-key.pem', certificate: 'cert.cer' From 3bd2476bc6f73e11fea6c45149e8464dde623109 Mon Sep 17 00:00:00 2001 From: Tejas Shah Date: Sun, 22 Jan 2017 22:47:49 -0800 Subject: [PATCH 4/5] fixing nitpicks: `host_address` => `host` and changed some log msgs for starting the server --- README.md | 2 +- index.js | 12 ++++++------ test/test-examples-server-custom-bindings.js | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index edd68a7..87d80c7 100644 --- a/README.md +++ b/README.md @@ -101,7 +101,7 @@ require('alexa-app-server').start({ // The host address in which the server should bind to. If not specified, // this argument will be ignored. - host_address: undefined, + host: undefined, // By default, GET requests to Alexa App endpoints will show the debugger // UI. This can be disabled. If 'verify' and 'debug' are both set to true, diff --git a/index.js b/index.js index 6a1cf20..31cd04a 100644 --- a/index.js +++ b/index.js @@ -228,9 +228,9 @@ var appServer = function(config) { var httpsServer = https.createServer(credentials, self.express); // create the HTTPS server //TODO: add separate option to specify specific host address for HTTPS server to bind to ??? - if (typeof config.host_address === 'string') { - self.httpsInstance = httpsServer.listen(config.httpsPort, config.host_address); - self.log("Listening on HTTPS port " + config.httpsPort + " on address " + config.host_address); + if (typeof config.host === 'string') { + self.httpsInstance = httpsServer.listen(config.httpsPort, config.host); + self.log("Listening on https://" + config.host + ":" + config.httpsPort); } else { self.httpsInstance = httpsServer.listen(config.httpsPort); self.log("Listening on HTTPS port " + config.httpsPort); @@ -252,9 +252,9 @@ var appServer = function(config) { // Start the server listening config.port = config.port || process.env.port || 80; - if (typeof config.host_address === 'string') { - self.httpInstance = self.express.listen(config.port, config.host_address); - self.log("Listening on HTTP port " + config.port + " on address " + config.host_address); + if (typeof config.host === 'string') { + self.httpInstance = self.express.listen(config.port, config.host); + self.log("Listening on http://" + config.host + ":" + config.port); } else { self.httpInstance = self.express.listen(config.port); self.log("Listening on HTTP port " + config.port); diff --git a/test/test-examples-server-custom-bindings.js b/test/test-examples-server-custom-bindings.js index 8dae124..6488ebe 100644 --- a/test/test-examples-server-custom-bindings.js +++ b/test/test-examples-server-custom-bindings.js @@ -27,7 +27,7 @@ describe("Alexa App Server with Examples & Custon Server Bindings", function() { it("mounts hello world app (HTTP & HTTPS)", function() { testServer = alexaAppServer.start({ port: 3000, - host_address: "127.0.0.1", + host: "127.0.0.1", server_root: 'examples', httpsEnabled: true, httpsPort: 6000, From 76fec615a515ace163edd765f22f5ad4d764e7b1 Mon Sep 17 00:00:00 2001 From: Tejas Shah Date: Mon, 23 Jan 2017 19:10:11 -0800 Subject: [PATCH 5/5] fixing nitpicks pt. 2 --- index.js | 20 +++++++++++++------- test/test-examples-server-custom-bindings.js | 16 ++++++++++------ 2 files changed, 23 insertions(+), 13 deletions(-) diff --git a/index.js b/index.js index 31cd04a..b3d606e 100644 --- a/index.js +++ b/index.js @@ -151,13 +151,18 @@ var appServer = function(config) { self.start = function() { // Instantiate up the server - //TODO: add i18n support (i18n-node might be a good look) + // TODO: add i18n support (i18n-node might be a good look) + // Issue #12: https://github.com/alexa-js/alexa-app-server/issues/12 self.express = express(); - //TODO: change this to make sure it doesn't affect other non-Alexa services/apps + + // TODO: change this to make sure it doesn't affect other non-Alexa services/apps + // Issue #35: https://github.com/alexa-js/alexa-app-server/issues/35 self.express.use(bodyParser.urlencoded({ extended: true })); - //We need the rawBody for request verification - self.express.use(function(req, res, next) { //TODO: change code to possibly use bodyParser.json() + // We need the rawBody for request verification + // TODO: change code to possibly use bodyParser.json() + // Issue #21: https://github.com/alexa-js/alexa-app-server/issues/21 + self.express.use(function(req, res, next) { // mark the request body as already having been parsed so it's ignored by // other body parser middlewares req._body = true; @@ -212,11 +217,11 @@ var appServer = function(config) { if (config.httpsEnabled == true) { self.log("httpsEnabled is true. Reading HTTPS config"); - if (config.privateKey != undefined && config.certificate != undefined && config.httpsPort != undefined) { //Ensure that all of the needed properties are set + if (config.privateKey != undefined && config.certificate != undefined && config.httpsPort != undefined) { // Ensure that all of the needed properties are set var privateKeyFile = server_root + '/sslcert/' + config.privateKey; var certificateFile = server_root + '/sslcert/' + config.certificate; - if (fs.existsSync(privateKeyFile) && fs.existsSync(certificateFile)) { //Make sure the key and cert exist. + if (fs.existsSync(privateKeyFile) && fs.existsSync(certificateFile)) { // Make sure the key and cert exist. var privateKey = fs.readFileSync(privateKeyFile, 'utf8'); var certificate = fs.readFileSync(certificateFile, 'utf8'); @@ -227,7 +232,8 @@ var appServer = function(config) { try { // These two lines below can fail it the certs were generated incorrectly. But we can continue startup without HTTPS var httpsServer = https.createServer(credentials, self.express); // create the HTTPS server - //TODO: add separate option to specify specific host address for HTTPS server to bind to ??? + // TODO: add separate option to specify specific host address for HTTPS server to bind to ??? + // Issue #38: https://github.com/alexa-js/alexa-app-server/issues/38 if (typeof config.host === 'string') { self.httpsInstance = httpsServer.listen(config.httpsPort, config.host); self.log("Listening on https://" + config.host + ":" + config.httpsPort); diff --git a/test/test-examples-server-custom-bindings.js b/test/test-examples-server-custom-bindings.js index 6488ebe..c59b00a 100644 --- a/test/test-examples-server-custom-bindings.js +++ b/test/test-examples-server-custom-bindings.js @@ -6,25 +6,29 @@ chai.config.includeStack = true; var request = require("supertest-as-promised"); var alexaAppServer = require("../index"); -describe("Alexa App Server with Examples & Custon Server Bindings", function() { +// used so that testing https requests will work properly +process.env.NODE_TLS_REJECT_UNAUTHORIZED = '0'; + +describe("Alexa App Server with Examples & Custom Server Bindings", function() { var testServer; afterEach(function() { testServer.stop(); }); - it("mounts hello world app (HTTP only)", function() { + it("mounts hello world app (HTTP only) and bind to the specified address", function() { testServer = alexaAppServer.start({ port: 3000, - host_address: "127.0.0.1", + host: "127.0.0.1", server_root: 'examples' }); - return request(testServer.express) + + return request("http://127.0.0.1:3000") .get('/alexa/helloworld') .expect(200); }); - it("mounts hello world app (HTTP & HTTPS)", function() { + it("mounts hello world app (HTTP & HTTPS) and bind to the specified address", function() { testServer = alexaAppServer.start({ port: 3000, host: "127.0.0.1", @@ -35,7 +39,7 @@ describe("Alexa App Server with Examples & Custon Server Bindings", function() { certificate: 'cert.cer' }); - return request(testServer.express) + return request("https://127.0.0.1:6000") .get('/alexa/helloworld') .expect(200); });