2018-08-31 19:59:54 +00:00
|
|
|
const fs = require('../../core/fs.js');
|
2018-07-26 17:13:18 +00:00
|
|
|
var {canonicalHost} = require('../../utils/host.js');
|
2017-12-18 14:37:16 +00:00
|
|
|
var utils = require('../../utils/utils.js');
|
|
|
|
var Server = require('./server.js');
|
2018-09-04 12:34:37 +00:00
|
|
|
const opn = require('opn');
|
2017-12-18 14:37:16 +00:00
|
|
|
|
2018-08-31 19:59:54 +00:00
|
|
|
require('ejs');
|
|
|
|
const Templates = {
|
|
|
|
embark_building_placeholder: require('./templates/embark-building-placeholder.html.ejs')
|
|
|
|
};
|
2017-12-18 14:37:16 +00:00
|
|
|
|
2018-08-31 19:59:54 +00:00
|
|
|
class WebServer {
|
2018-09-30 22:56:33 +00:00
|
|
|
constructor(embark, options) {
|
2017-12-29 23:29:56 +00:00
|
|
|
this.embark = embark;
|
2017-12-18 14:37:16 +00:00
|
|
|
this.logger = embark.logger;
|
|
|
|
this.events = embark.events;
|
2018-09-17 22:51:46 +00:00
|
|
|
this.buildDir = embark.config.buildDir;
|
2018-07-12 13:02:16 +00:00
|
|
|
this.plugins = options.plugins;
|
2017-12-19 14:50:29 +00:00
|
|
|
this.webServerConfig = embark.config.webServerConfig;
|
|
|
|
if (!this.webServerConfig.enabled) {
|
2017-12-18 14:37:16 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-09-17 22:56:05 +00:00
|
|
|
this.host = this.webServerConfig.host;
|
2018-09-17 23:13:21 +00:00
|
|
|
this.port = parseInt(this.webServerConfig.port, 10);
|
2018-07-13 07:50:57 +00:00
|
|
|
this.enableCatchAll = this.webServerConfig.enableCatchAll === true;
|
2018-08-27 20:22:53 +00:00
|
|
|
this.enableCatchAll = false; // FIXME when true, some Requests end up failing (eg: process-logs)
|
2017-12-18 14:37:16 +00:00
|
|
|
|
2018-10-11 13:03:58 +00:00
|
|
|
this.events.request('processes:register', 'webserver', {
|
|
|
|
launchFn: (cb) => { this.server.start(cb) },
|
|
|
|
stopFn: (cb) => { this.server.stop(cb) }
|
|
|
|
});
|
|
|
|
|
2018-05-08 21:49:46 +00:00
|
|
|
this.events.emit("status", __("Starting Server"));
|
2017-12-19 14:50:29 +00:00
|
|
|
|
2018-08-31 20:01:18 +00:00
|
|
|
this.server = new Server({
|
2018-10-09 16:44:32 +00:00
|
|
|
logger: this.logger,
|
2018-08-31 19:51:18 +00:00
|
|
|
buildDir: this.buildDir,
|
2018-08-31 20:01:18 +00:00
|
|
|
events: this.events,
|
|
|
|
host: this.host,
|
2018-10-02 21:19:21 +00:00
|
|
|
logger: this.logger,
|
2018-09-17 23:47:19 +00:00
|
|
|
port: this.port,
|
2018-10-01 08:53:30 +00:00
|
|
|
plugins: this.plugins,
|
2018-09-17 23:47:19 +00:00
|
|
|
openBrowser: this.webServerConfig.openBrowser
|
2018-08-31 20:01:18 +00:00
|
|
|
});
|
|
|
|
|
2018-10-01 09:10:17 +00:00
|
|
|
this.listenToCommands();
|
|
|
|
this.registerConsoleCommands();
|
|
|
|
|
2018-09-07 18:54:15 +00:00
|
|
|
this.events.on('webserver:config:change', () => {
|
|
|
|
this.embark.config.webServerConfig = null;
|
|
|
|
this.embark.config.loadWebServerConfigFile();
|
|
|
|
this.webServerConfig = this.embark.config.webServerConfig;
|
|
|
|
this.host = this.webServerConfig.host;
|
|
|
|
this.port = this.webServerConfig.port;
|
|
|
|
this.server.host = this.host;
|
|
|
|
this.server.port = this.port;
|
|
|
|
|
|
|
|
this.testPort(() => {
|
2018-10-11 13:03:58 +00:00
|
|
|
this.events.request('processes:stop', 'webserver', _err => {
|
|
|
|
this.events.request('processes:launch', 'webserver', (_err, message, port) => {
|
2018-09-07 18:54:15 +00:00
|
|
|
this.logger.info(message);
|
|
|
|
this.port = port;
|
|
|
|
this.events.request('open-browser', () => {});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2018-08-23 18:28:44 +00:00
|
|
|
this.testPort(() => {
|
2018-10-11 13:03:58 +00:00
|
|
|
this.events.request('processes:launch', 'webserver', (_err, message, port) => {
|
2018-08-23 19:11:43 +00:00
|
|
|
this.logger.info(message);
|
|
|
|
this.port = port;
|
|
|
|
this.setServiceCheck();
|
|
|
|
});
|
2018-08-23 18:14:10 +00:00
|
|
|
});
|
2017-12-19 14:50:29 +00:00
|
|
|
}
|
|
|
|
|
2018-08-23 18:28:44 +00:00
|
|
|
testPort(done) {
|
2018-09-17 22:54:31 +00:00
|
|
|
if (this.port === 0) {
|
|
|
|
this.logger.warn(__('Assigning an available port'));
|
|
|
|
this.server.port = 0;
|
|
|
|
return done();
|
|
|
|
}
|
2018-08-23 18:28:44 +00:00
|
|
|
utils.pingEndpoint(this.host, this.port, 'http', 'http', '', (err) => {
|
|
|
|
if (err) { // Port is ok
|
|
|
|
return done();
|
|
|
|
}
|
2018-08-23 19:11:43 +00:00
|
|
|
this.logger.warn(__('Webserver already running on port %s. Assigning an available port', this.port));
|
|
|
|
this.port = 0;
|
|
|
|
this.server.port = 0;
|
|
|
|
done();
|
2018-08-23 18:28:44 +00:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2017-12-19 14:50:29 +00:00
|
|
|
setServiceCheck() {
|
2018-08-23 19:11:43 +00:00
|
|
|
const self = this;
|
2017-12-18 14:37:16 +00:00
|
|
|
|
2018-06-01 15:58:11 +00:00
|
|
|
this.events.request("services:register", 'Webserver', function (cb) {
|
2018-08-23 19:11:43 +00:00
|
|
|
let url = 'http://' + canonicalHost(self.host) + ':' + self.port;
|
2017-12-19 14:50:29 +00:00
|
|
|
utils.checkIsAvailable(url, function (available) {
|
2018-05-08 21:49:46 +00:00
|
|
|
let devServer = __('Webserver') + ' (' + url + ')';
|
2017-12-19 14:50:29 +00:00
|
|
|
let serverStatus = (available ? 'on' : 'off');
|
|
|
|
return cb({name: devServer, status: serverStatus});
|
2017-12-18 14:37:16 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
|
2017-12-19 14:50:29 +00:00
|
|
|
this.events.on('check:wentOffline:Webserver', () => {
|
2018-05-08 21:49:46 +00:00
|
|
|
this.logger.info(__("Webserver is offline"));
|
2017-12-18 14:37:16 +00:00
|
|
|
});
|
2017-12-19 14:50:29 +00:00
|
|
|
}
|
2017-12-18 14:37:16 +00:00
|
|
|
|
2017-12-19 14:50:29 +00:00
|
|
|
listenToCommands() {
|
2018-09-04 12:35:53 +00:00
|
|
|
this.events.setCommandHandler('build-placeholder', (cb) => this.buildPlaceholderPage(cb));
|
2018-09-04 12:34:37 +00:00
|
|
|
this.events.setCommandHandler('open-browser', (cb) => this.openBrowser(cb));
|
2018-10-11 13:03:58 +00:00
|
|
|
this.events.setCommandHandler('start-webserver', (cb) => this.events.request('processes:launch', 'webserver', cb));
|
|
|
|
this.events.setCommandHandler('stop-webserver', (cb) => this.events.request('processes:stop', 'webserver', cb));
|
2018-09-28 19:11:26 +00:00
|
|
|
this.events.setCommandHandler('logs:webserver:turnOn', (cb) => this.server.enableLogging(cb));
|
|
|
|
this.events.setCommandHandler('logs:webserver:turnOff', (cb) => this.server.disableLogging(cb));
|
2017-12-18 14:37:16 +00:00
|
|
|
}
|
|
|
|
|
2017-12-29 23:29:56 +00:00
|
|
|
registerConsoleCommands() {
|
|
|
|
const self = this;
|
2017-12-29 23:33:11 +00:00
|
|
|
self.embark.registerConsoleCommand((cmd, _options) => {
|
2018-08-08 12:42:45 +00:00
|
|
|
return {
|
2018-09-04 12:32:31 +00:00
|
|
|
match: () => cmd === 'webserver start',
|
|
|
|
process: (cb) => self.events.request('start-webserver', cb)
|
2018-08-10 14:54:21 +00:00
|
|
|
};
|
2017-12-29 23:29:56 +00:00
|
|
|
});
|
|
|
|
|
2018-08-08 12:42:45 +00:00
|
|
|
self.embark.registerConsoleCommand((cmd, _options) => {
|
|
|
|
return {
|
2018-09-04 12:32:31 +00:00
|
|
|
match: () => cmd === 'webserver stop',
|
|
|
|
process: (cb) => self.events.request('stop-webserver', cb)
|
|
|
|
};
|
|
|
|
});
|
|
|
|
|
2018-09-04 12:35:02 +00:00
|
|
|
self.embark.registerConsoleCommand((cmd, _options) => {
|
|
|
|
return {
|
|
|
|
match: () => cmd === 'browser open',
|
|
|
|
process: (cb) => self.events.request('open-browser', cb)
|
2018-08-08 12:42:45 +00:00
|
|
|
};
|
|
|
|
});
|
2018-09-28 19:11:26 +00:00
|
|
|
|
|
|
|
self.embark.registerConsoleCommand((cmd, _options) => {
|
|
|
|
return {
|
|
|
|
match: () => cmd === 'log webserver on',
|
|
|
|
process: (cb) => self.events.request('logs:webserver:turnOn', cb)
|
|
|
|
};
|
|
|
|
});
|
|
|
|
|
|
|
|
self.embark.registerConsoleCommand((cmd, _options) => {
|
|
|
|
return {
|
|
|
|
match: () => cmd === 'log webserver off',
|
|
|
|
process: (cb) => self.events.request('logs:webserver:turnOff', cb)
|
|
|
|
};
|
|
|
|
});
|
2018-08-08 12:42:45 +00:00
|
|
|
}
|
2018-08-31 19:59:54 +00:00
|
|
|
|
|
|
|
buildPlaceholderPage(cb) {
|
|
|
|
let html = Templates.embark_building_placeholder({buildingMsg: __('Embark is building, please wait...')});
|
2018-09-04 12:36:21 +00:00
|
|
|
fs.mkdirpSync(this.buildDir); // create buildDir if it does not exist
|
2018-08-31 19:59:54 +00:00
|
|
|
fs.writeFile(utils.joinPath(this.buildDir, 'index.html'), html, cb);
|
|
|
|
}
|
2018-09-04 12:34:37 +00:00
|
|
|
|
|
|
|
openBrowser(cb) {
|
|
|
|
const _cb = () => { cb(); };
|
|
|
|
return opn(
|
|
|
|
`http://${canonicalHost(this.server.hostname)}:${this.server.port}`,
|
|
|
|
{wait: false}
|
|
|
|
).then(_cb, _cb); // fail silently, e.g. in a docker container
|
|
|
|
}
|
2017-12-18 14:37:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
module.exports = WebServer;
|