diff --git a/package.json b/package.json index 41a5e92..a3dd389 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": { diff --git a/src/index.coffee b/src/index.coffee index 06a1bd1..fa96d3e 100644 --- a/src/index.coffee +++ b/src/index.coffee @@ -7,9 +7,8 @@ fs = require("fs") connect = require("connect") liveReload = require("connect-livereload") tiny_lr = require("tiny-lr") -opt = {} -server = undefined lr = undefined +apps = [] http2 = undefined try @@ -17,60 +16,73 @@ try 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: -> - app = connect() - @middleware().forEach (middleware) -> + @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 = [] + @app = undefined + @run() + + run: -> + @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 - if opt.https? - server = (http2 || 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' - app + @app.use middleware + + if @https + @server = (http2 || 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); ) @@ -78,45 +90,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(opt.livereload) - 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(@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' @@ -124,12 +136,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 = []