2017-04-23 20:02:26 +02:00
|
|
|
'use strict';
|
|
|
|
|
2017-05-20 12:33:23 +02:00
|
|
|
const express = require('express');
|
|
|
|
const Error = require('http-errors');
|
|
|
|
const compression = require('compression');
|
|
|
|
const Auth = require('./auth');
|
|
|
|
const Logger = require('./logger');
|
|
|
|
const Config = require('./config');
|
|
|
|
const Middleware = require('./middleware');
|
|
|
|
const Cats = require('./status-cats');
|
|
|
|
const Storage = require('./storage');
|
2014-02-01 09:08:48 +01:00
|
|
|
|
2013-06-08 03:16:28 +02:00
|
|
|
module.exports = function(config_hash) {
|
2017-04-23 20:02:26 +02:00
|
|
|
Logger.setup(config_hash.logs);
|
2014-12-22 18:58:25 +01:00
|
|
|
|
2017-05-20 12:33:23 +02:00
|
|
|
const config = new Config(config_hash);
|
|
|
|
const storage = new Storage(config);
|
|
|
|
const auth = new Auth(config);
|
|
|
|
const app = express();
|
2014-11-12 12:14:37 +01:00
|
|
|
|
|
|
|
// run in production mode by default, just in case
|
|
|
|
// it shouldn't make any difference anyway
|
2017-04-23 20:02:26 +02:00
|
|
|
app.set('env', process.env.NODE_ENV || 'production');
|
2014-11-12 12:14:37 +01:00
|
|
|
|
2017-05-20 11:13:08 +02:00
|
|
|
const error_reporting_middleware = function(req, res, next) {
|
2014-11-12 12:14:37 +01:00
|
|
|
res.report_error = res.report_error || function(err) {
|
|
|
|
if (err.status && err.status >= 400 && err.status < 600) {
|
|
|
|
if (!res.headersSent) {
|
2017-04-23 20:02:26 +02:00
|
|
|
res.status(err.status);
|
|
|
|
next({error: err.message || 'unknown error'});
|
2014-11-12 12:14:37 +01:00
|
|
|
}
|
|
|
|
} else {
|
2017-04-23 20:02:26 +02:00
|
|
|
Logger.logger.error( {err: err}
|
|
|
|
, 'unexpected error: @{!err.message}\n@{err.stack}');
|
2014-11-12 12:14:37 +01:00
|
|
|
if (!res.status || !res.send) {
|
2017-04-23 20:02:26 +02:00
|
|
|
Logger.logger.error('this is an error in express.js, please report this');
|
|
|
|
res.destroy();
|
2014-11-12 12:14:37 +01:00
|
|
|
} else if (!res.headersSent) {
|
2017-04-23 20:02:26 +02:00
|
|
|
res.status(500);
|
|
|
|
next({error: 'internal server error'});
|
2014-11-12 12:14:37 +01:00
|
|
|
} else {
|
|
|
|
// socket should be already closed
|
|
|
|
}
|
|
|
|
}
|
2017-04-23 20:02:26 +02:00
|
|
|
};
|
|
|
|
next();
|
2017-05-20 11:13:08 +02:00
|
|
|
};
|
2014-11-12 12:14:37 +01:00
|
|
|
|
2017-04-23 20:02:26 +02:00
|
|
|
app.use(Middleware.log);
|
|
|
|
app.use(error_reporting_middleware);
|
2014-11-12 12:14:37 +01:00
|
|
|
app.use(function(req, res, next) {
|
2017-04-23 20:02:26 +02:00
|
|
|
res.setHeader('X-Powered-By', config.user_agent);
|
|
|
|
next();
|
|
|
|
});
|
|
|
|
app.use(Cats.middleware);
|
|
|
|
app.use(compression());
|
2013-05-31 08:26:11 +02:00
|
|
|
|
2014-11-12 17:45:40 +01:00
|
|
|
app.get('/favicon.ico', function(req, res, next) {
|
2017-04-23 20:02:26 +02:00
|
|
|
req.url = '/-/static/favicon.png';
|
|
|
|
next();
|
|
|
|
});
|
2014-11-12 17:18:30 +01:00
|
|
|
|
2014-11-12 12:14:37 +01:00
|
|
|
// hook for tests only
|
|
|
|
if (config._debug) {
|
2014-11-25 01:22:05 +01:00
|
|
|
app.get('/-/_debug', function(req, res, next) {
|
2017-04-23 20:02:26 +02:00
|
|
|
let do_gc = typeof(global.gc) !== 'undefined';
|
2017-05-20 12:33:23 +02:00
|
|
|
if (do_gc) {
|
|
|
|
global.gc();
|
|
|
|
}
|
2014-11-13 19:32:31 +01:00
|
|
|
next({
|
2017-04-23 20:02:26 +02:00
|
|
|
pid: process.pid,
|
|
|
|
main: process.mainModule.filename,
|
|
|
|
conf: config.self_path,
|
|
|
|
mem: process.memoryUsage(),
|
|
|
|
gc: do_gc,
|
|
|
|
});
|
|
|
|
});
|
2014-11-12 12:14:37 +01:00
|
|
|
}
|
|
|
|
|
2017-04-23 20:02:26 +02:00
|
|
|
app.use(require('./index-api')(config, auth, storage));
|
2014-11-13 18:13:37 +01:00
|
|
|
|
2014-11-16 14:32:46 +01:00
|
|
|
if (config.web && config.web.enable === false) {
|
2015-01-26 10:27:41 +01:00
|
|
|
app.get('/', function(req, res, next) {
|
2017-04-23 20:02:26 +02:00
|
|
|
next( Error[404]('web interface is disabled in the config file') );
|
|
|
|
});
|
2014-11-12 17:45:40 +01:00
|
|
|
} else {
|
2017-04-23 20:02:26 +02:00
|
|
|
app.use(require('./index-web')(config, auth, storage));
|
2014-11-12 17:45:40 +01:00
|
|
|
}
|
|
|
|
|
2014-11-13 17:15:50 +01:00
|
|
|
app.get('/*', function(req, res, next) {
|
2017-04-23 20:02:26 +02:00
|
|
|
next( Error[404]('file not found') );
|
|
|
|
});
|
2014-11-12 12:14:37 +01:00
|
|
|
|
2014-11-13 17:15:50 +01:00
|
|
|
app.use(function(err, req, res, next) {
|
2017-05-20 12:33:23 +02:00
|
|
|
if (Object.prototype.toString.call(err) !== '[object Error]') {
|
|
|
|
return next(err);
|
|
|
|
}
|
|
|
|
if (err.code === 'ECONNABORT' && res.statusCode === 304) {
|
|
|
|
return next();
|
|
|
|
}
|
2014-11-13 17:15:50 +01:00
|
|
|
if (typeof(res.report_error) !== 'function') {
|
|
|
|
// in case of very early error this middleware may not be loaded before error is generated
|
|
|
|
// fixing that
|
2017-04-23 20:02:26 +02:00
|
|
|
error_reporting_middleware(req, res, function() {});
|
2014-11-13 17:15:50 +01:00
|
|
|
}
|
2017-04-23 20:02:26 +02:00
|
|
|
res.report_error(err);
|
|
|
|
});
|
2014-11-13 17:15:50 +01:00
|
|
|
|
2017-04-23 20:02:26 +02:00
|
|
|
app.use(Middleware.final);
|
2014-11-13 19:32:31 +01:00
|
|
|
|
2017-04-23 20:02:26 +02:00
|
|
|
return app;
|
|
|
|
};
|
2013-05-31 08:26:11 +02:00
|
|
|
|