blob: ae40b4fe9434c8b8e8ab4924f23369262af06b3e [file] [log] [blame]
var path = require("path");
var http = require("http");
var httpProxy = require('http-proxy');
var send = require('send');
var urlLib = require('url');
var _ = require('lodash');
var dist_dir = process.env.DIST || __dirname + '/dist/release/';
module.exports = function (options) {
// Options
var setContentSecurityPolicy = options.contentSecurityPolicy;
var port = options.port;
var proxyUrl = options.couchdb;
function sendFile (req, res, filePath) {
return send(req, filePath)
.on('error', function (err) {
if (err.status === 404) {
console.error('Could not locate', filePath);
} else {
console.error('ERROR', filePath, err);
}
res.setHeader("Content-Type", "text/javascript");
res.statusCode = 404;
res.end(JSON.stringify({error: err.message}));
})
.pipe(res);
}
var fileTypes = ['.js', '.css', '.png', '.swf', '.eot', '.woff', '.svg', '.ttf', '.swf'];
function isFile (url) {
return _.includes(fileTypes, path.extname(url));
}
// create proxy to couch for all couch requests
this.proxy = httpProxy.createServer({
secure: false,
changeOrigin: true,
target: proxyUrl
});
this.server = http.createServer((req, res) => {
var isDocLink = /_utils\/docs/.test(req.url);
var url = req.url.split(/\?v=|\?noCache/)[0].replace('_utils', '');
var accept = [];
if (req.headers.accept) {
accept = req.headers.accept.split(',');
}
if (setContentSecurityPolicy) {
var headerValue = "default-src 'self'; child-src 'self' data: blob:; img-src 'self' data:; font-src 'self'; " +
"script-src 'self' 'unsafe-eval'; style-src 'self' 'unsafe-inline';";
res.setHeader('Content-Security-Policy', headerValue);
}
if (url === '/' && accept[0] !== 'application/json') {
// serve main index file from here
return sendFile(req, res, path.join(dist_dir, 'index.html'));
} else if (isFile(url) && !isDocLink) {
return sendFile(req, res, path.join(dist_dir, url));
}
// This sets the Host header in the proxy so that one can use external
// CouchDB instances and not have the Host set to 'localhost'
var urlObj = urlLib.parse(req.url);
req.headers.host = urlObj.host;
this.proxy.web(req, res);
}).listen(port, '0.0.0.0');
this.proxy.on('error', () => {
// don't explode on cancelled requests
});
//Remove Secure on the cookie if the proxy is communicating to a CouchDB instance
// via https.
this.proxy.on('proxyRes', (proxyRes) => {
if (proxyRes.headers['set-cookie']) {
proxyRes.headers['set-cookie'][0] = proxyRes.headers["set-cookie"][0].replace('Secure', '');
}
});
var logo = [
[""],
[" ______ _ "],
["| ____| | | "],
["| |__ __ _ _ _ __ __ | |_ ___ _ __ "],
["| __| / _` | | | | | \\ \\/ / | __| / _ \\ | '_ \\ "],
["| | | (_| | | |_| | > < | |_ | (_) | | | | |"],
["|_| \\__,_| \\__,_| /_/\\_\\ \\__| \\___/ |_| |_|"],
[""]
];
_.each(logo, function (line) {
// eslint-disable-next-line no-console
console.log(line.toString());
});
// eslint-disable-next-line no-console
console.log('Listening on ' + port);
this.close = () => {
this.server.close();
this.proxy.close();
};
return this;
};