From 1352e3d200e7dc8bba5e35226a85992a841f2356 Mon Sep 17 00:00:00 2001 From: Justin Chase Date: Wed, 27 Jan 2016 16:38:23 -0600 Subject: [PATCH 1/4] connect.serverClose closes all servers now The problem was that certain variables were singleton to the module creating a second server was replacing them and they were not possible to get a reference to in order to clean it up properly. This change moves those variables to instance variables on the app which is stored and then they are all closed when serverClose is called. --- src/index.coffee | 142 ++++++++++++++++++++++++++--------------------- 1 file changed, 79 insertions(+), 63 deletions(-) diff --git a/src/index.coffee b/src/index.coffee index facbaab..65284b1 100644 --- a/src/index.coffee +++ b/src/index.coffee @@ -7,66 +7,77 @@ fs = require("fs") connect = require("connect") liveReload = require("connect-livereload") tiny_lr = require("tiny-lr") -opt = {} -server = undefined lr = undefined +apps = [] class ConnectApp constructor: (options) -> - opt = options - opt.port = opt.port || "8080" - opt.root = opt.root || path.dirname(module.parent.id) - opt.host = opt.host || "localhost" - opt.debug = opt.debug || false - @oldMethod("open") if opt.open - @server() - - server: -> + @port = options.port || "8080" + @root = options.root || path.dirname(module.parent.id) + @host = options.host || "localhost" + @debug = options.debug || false + @silent = options.silent || false + @https = options.https || false + @livereload = options.livereload || false + @middleware = options.middleware || undefined + @fallback = options.fallback || undefined + @oldMethod("open") if options.open + @sockets = [] + @run() + + run: -> app = connect() - @middleware().forEach (middleware) -> + app.use connect.directory(if typeof @root == "object" then @root[0] else @root) + + @handlers().forEach (middleware) -> if typeof (middleware) is "object" app.use middleware[0], middleware[1] else app.use middleware - if opt.https? - server = https.createServer - key: opt.https.key || fs.readFileSync __dirname + '/certs/server.key' - cert: opt.https.cert || fs.readFileSync __dirname + '/certs/server.crt' - ca: opt.https.ca || fs.readFileSync __dirname + '/certs/ca.crt' - passphrase: opt.https.passphrase || 'gulp' + + if @https + @server = https.createServer + key: @https.key || fs.readFileSync __dirname + '/certs/server.key' + cert: @https.cert || fs.readFileSync __dirname + '/certs/server.crt' + ca: @https.ca || fs.readFileSync __dirname + '/certs/ca.crt' + passphrase: @https.passphrase || 'gulp' app else - server = http.createServer app - app.use connect.directory(if typeof opt.root == "object" then opt.root[0] else opt.root) - server.listen opt.port, (err) => + @server = http.createServer app + + @server.listen @port, (err) => if err @log "Error on starting server: #{err}" else - @log "Server started http#{if opt.https? then 's' else ''}://#{opt.host}:#{opt.port}" + @log "Server started http#{if @https? then 's' else ''}://#{@host}:#{@port}" stoped = false; sockets = []; - server.on 'close', => + @server.on "close", => if (!stoped) stoped = true @log "Server stopped" # Log connections and request in debug - server.on "connection", (socket) => - sockets.push socket + @server.on "connection", (socket) => + @logDebug "Received incoming connection from #{socket.address().address}" + @sockets.push socket socket.on "close", => - sockets.splice sockets.indexOf(socket), 1 + @sockets.splice @sockets.indexOf(socket), 1 - server.on "request", (request, response) => + @server.on "request", (request, response) => @logDebug "Received request #{request.method} #{request.url}" + @server.on "error", (err) => + @log err.toString() + stopServer = => if (!stoped) - sockets.forEach (socket) => + @sockets.forEach (socket) => socket.destroy() - server.close() + @server.close() process.nextTick( -> process.exit(0); ) @@ -74,45 +85,45 @@ class ConnectApp process.on("SIGINT", stopServer); process.on("exit", stopServer); - if opt.livereload + if @livereload tiny_lr.Server::error = -> - if opt.https? + if @https lr = tiny_lr - key: opt.https.key || fs.readFileSync __dirname + '/certs/server.key' - cert: opt.https.cert || fs.readFileSync __dirname + '/certs/server.crt' + key: @https.key || fs.readFileSync __dirname + '/certs/server.key' + cert: @https.cert || fs.readFileSync __dirname + '/certs/server.crt' else lr = tiny_lr() - lr.listen opt.livereload.port - @log "LiveReload started on port #{opt.livereload.port}" - - middleware: -> - middleware = if opt.middleware then opt.middleware.call(this, connect, opt) else [] - if opt.livereload - opt.livereload = {} if typeof opt.livereload is "boolean" - opt.livereload.port = 35729 unless opt.livereload.port - middleware.unshift liveReload(port: opt.livereload.port) - if typeof opt.root == "object" - opt.root.forEach (path) -> - middleware.push connect.static(path) - else - middleware.push connect.static(opt.root) - if opt.fallback - middleware.push (req, res) -> - require('fs').createReadStream(opt.fallback).pipe(res); - return middleware + lr.listen @livereload.port + @log "LiveReload started on port #{@livereload.port}" + + handlers: -> + steps = if @middleware then @middleware.call(this, connect, @) else [] + if @livereload + @livereload = {} if typeof @livereload is "boolean" + @livereload.port = 35729 unless @livereload.port + steps.unshift liveReload(port: @livereload.port) + if typeof @root == "object" + @root.forEach (path) -> + steps.push connect.static(path) + else + steps.push connect.static(@root) + if @fallback + steps.push (req, res) => + require('fs').createReadStream(@fallback).pipe(res); + return steps - log: (@text) -> - if !opt.silent - util.log util.colors.green(@text) + log: (text) -> + if !@silent + util.log util.colors.green(text) - logWarning: (@text) -> - if !opt.silent - util.log util.colors.yellow(@text) + logWarning: (text) -> + if !@silent + util.log util.colors.yellow(text) - logDebug: (@text) -> - if opt.debug - util.log util.colors.blue(@text) + logDebug: (text) -> + if @debug + util.log util.colors.blue(text) oldMethod: (type) -> text = 'does not work in gulp-connect v 2.*. Please read "readme" https://github.com/AveVlad/gulp-connect' @@ -120,12 +131,17 @@ class ConnectApp when "open" then @logWarning("Option open #{text}") module.exports = - server: (options = {}) -> new ConnectApp(options) + server: (options = {}) -> + app = new ConnectApp(options) + apps.push(app) + app reload: -> es.map (file, callback) -> - if opt.livereload and typeof lr == "object" + if @livereload and typeof lr == "object" lr.changed body: files: file.path callback null, file lr: lr - serverClose: -> do server.close + serverClose: -> + apps.forEach((app) -> do app.server.close) + apps = [] From ba170473fac2f698342901c061d152eb39444f2f Mon Sep 17 00:00:00 2001 From: Justin Chase Date: Wed, 27 Jan 2016 16:59:29 -0600 Subject: [PATCH 2/4] Store app as instance variable --- src/index.coffee | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/index.coffee b/src/index.coffee index 65284b1..cd454aa 100644 --- a/src/index.coffee +++ b/src/index.coffee @@ -26,14 +26,14 @@ class ConnectApp @run() run: -> - app = connect() - app.use connect.directory(if typeof @root == "object" then @root[0] else @root) + @app = connect() + @app.use connect.directory(if typeof @root == "object" then @root[0] else @root) @handlers().forEach (middleware) -> if typeof (middleware) is "object" - app.use middleware[0], middleware[1] + @app.use middleware[0], middleware[1] else - app.use middleware + @app.use middleware if @https @server = https.createServer @@ -41,9 +41,9 @@ class ConnectApp cert: @https.cert || fs.readFileSync __dirname + '/certs/server.crt' ca: @https.ca || fs.readFileSync __dirname + '/certs/ca.crt' passphrase: @https.passphrase || 'gulp' - app + @app else - @server = http.createServer app + @server = http.createServer @app @server.listen @port, (err) => if err From 814bf299d33ec1aca1e71240d00721ae6a3186ef Mon Sep 17 00:00:00 2001 From: Justin Chase Date: Wed, 27 Jan 2016 17:03:24 -0600 Subject: [PATCH 3/4] Use fat arrow for middleware handler --- src/index.coffee | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/index.coffee b/src/index.coffee index cd454aa..20f839f 100644 --- a/src/index.coffee +++ b/src/index.coffee @@ -23,13 +23,14 @@ class ConnectApp @fallback = options.fallback || undefined @oldMethod("open") if options.open @sockets = [] + @app = undefined @run() run: -> @app = connect() @app.use connect.directory(if typeof @root == "object" then @root[0] else @root) - @handlers().forEach (middleware) -> + @handlers().forEach (middleware) => if typeof (middleware) is "object" @app.use middleware[0], middleware[1] else From 85e939b40bcd38f4cfbb8669ed9b88aa82b79ea2 Mon Sep 17 00:00:00 2001 From: Justin Chase Date: Thu, 25 Feb 2016 16:04:30 -0600 Subject: [PATCH 4/4] 3.0.0 --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c742c40..d77a6d7 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "gulp-connect", - "version": "2.3.1", + "version": "3.0.0", "description": "Gulp plugin to run a webserver (with LiveReload)", "license": "MIT", "repository": {