(function() { 'use strict'; if (!global.cloudcmd) return console.log( '# server.js' + '\n' + '# -----------' + '\n' + '# Module is part of Cloud Commander,' + '\n' + '# easy to use web server.' + '\n' + '# http://cloudcmd.io' + '\n'); var main = global.cloudcmd.main, DIR = main.DIR, URL = main.url, Path = main.path, Minify = main.minify, CloudFunc = main.cloudfunc, AppCache = main.appcache, Socket = main.socket, Console = main.console, Terminal = main.terminal, join = main.srvrequire('join'), http = main.http, https = main.https, Util = main.util, express = main.express, expressApp, emptyHandler = function(req, res, next) { Util.exec(next); }, Rest, Route; join = join && Util.exec.with(join, beforeJoin) || emptyHandler; /* базовая инициализация */ function init(pAppCachProcessing) { var config = main.config; /* создаём файл app cache */ if (config.appcache && AppCache && config.server) Util.exec( pAppCachProcessing); } /** * start server function * @param pConfig * @param pProcessing {index, appcache, rest} */ function start(options) { var redirectServer, port, ip, ssl, sslPort, HTTP = 'http://', HTTPS = 'https://', config = main.config; if (!options) options = {}; Rest = options.rest; Route = options.route; init(options.appcache); port = process.env.PORT || /* c9 */ process.env.app_port || /* nodester */ process.env.VCAP_APP_PORT || /* cloudfoundry */ config.port, ip = process.env.IP || /* c9 */ config.ip || '0.0.0.0', ssl = options.ssl, sslPort = config.sslPort; /* server mode or testing mode */ if (!config.server) Util.log('Cloud Commander testing mode'); else if (!ssl) createServer(port, ip, HTTP); else { createRedirect(port, ip, HTTPS, sslPort); createServer(sslPort, ip, HTTP, ssl, function() { Util.log('Could not use https port: ' + sslPort); redirectServer.close(); Util.log('* Redirection http -> https removed'); createServer(port, ip); }); } } function createRedirect(port, ip, protocol, sslPort) { var server = function(req, res) { var url, host = req.headers.host, parsed = URL.parse(host), hostName = parsed.protocol; url = protocol + hostName + sslPort + req.url; main.redirect({ response: res, url: url }); }; Util.log('* Redirection http -> https is setted up'); logServer(port, ip, protocol); http.createServer(server) .listen(port, ip); } function createServer(port, ip, protocol, ssl, callback) { var server, app, funcs = [ Rest, Route, join, controller ], respondApp = Util.exec.with(respond, funcs); expressApp = express.getApp(funcs); app = expressApp || respondApp; if (ssl) server = https.createServer(ssl, app); else server = http.createServer(app); server.on('error', function(error) { Util.log(error); Util.exec(callback, error); }); server.listen(port, ip); logServer(port, ip, protocol); addSockets(server); } function logServer(port, ip, http) { Util.log('* Server running at ' + http + ip + ':' + port); } function addSockets(server) { var listen, msg, config = main.config, status = 'off'; if (config.socket && Socket) { listen = Socket.listen(server); if (listen) { status = 'on'; Console.init(); Terminal.init(); } } msg = CloudFunc.formatMsg('sockets', '', status); Util.log(msg); } function respond(funcs, req, res) { funcs = funcs.map(function(func) { return Util.exec.with(func, req, res); }); Util.exec.series(funcs); } /** * Главная функция, через которую проихсодит * взаимодействие, обмен данными с клиентом * @param req - запрос клиента (Request) * @param res - ответ сервера (Response) */ function controller(req, res) { var check, result, config = main.config, isMin = config.minify, parsedUrl = URL.parse(req.url), query = parsedUrl.search || '', path = main.getPathName(req), name = path; if (!expressApp) Util.log(req.method + ' ' + path + query); /* watching is file changed */ if (config.appcache) AppCache.watch(name); name = Path.join(DIR, name); check = checkExt(name); result = isMin && check; Util.exec.if(!result, function(error, params) { var sendName = params && params.name || name; main.sendFile({ name : sendName, cache : config.cache, gzip : true, request : req, response : res }); }, function(callback) { Minify.optimize(name, { callback : callback, returnName : true }); }); } function minify(name, callback) { Minify.optimize(name, { callback : callback }); } function beforeJoin(names, callback) { var i, name, check, minName, func, funcs = [], dir = DIR, config = main.config, n = names.length; for (i = 0; i < n; i++) { name = Path.join(dir, names[i]); names[i] = name; if (config.minify) { check = checkExt(name); if (check) { minName = Minify.getName(name); if (name !== minName) names[i] = minName; } funcs.push(Util.exec.with(minify, name)); } } func = Util.exec.ret(callback, names); Util.exec.if(!config.minify, func, function(callback) { Util.exec.parallel(funcs, callback); }); } function checkExt(name) { var ret; ret = Util.checkExt(name, ['js', 'css', 'html']); return ret; } exports.start = start; })();