/* eslint-env node */ const path = require('path'); const HttpProxy = require('http-proxy'); const config = require('../../config/environment')(process.env.EMBER_ENV).APP; module.exports = function(app, options) { var httpServer = options.httpServer; const proxy = HttpProxy.createProxyServer({ ws: true, xfwd: false, target: config.apiServer, secure: false, followRedirects: true, }); proxy.on('error', onProxyError); // WebSocket for Rancher httpServer.on('upgrade', (req, socket, head) => { if ( req.url.startsWith('/_lr/') ) { return; } let targetHost = config.apiServer.replace(/^https?:\/\//, ''); let host = req.headers['host']; let port; if ( socket.ssl ) { req.headers['x-forwarded-proto'] = 'https'; port = 443; } else { req.headers['x-forwarded-proto'] = 'http'; port = 80; } if ( host ) { idx = host.lastIndexOf(':'); if ( ( host.startsWith('[') && host.includes(']:') || !host.startsWith('[') ) && idx > 0 ){ port = host.substr(idx+1); host = host.substr(0, host.lastIndexOf(':')); } } req.headers['x-forwarded-host'] = host; req.headers['x-forwarded-port'] = port; req.headers['host'] = targetHost; req.headers['origin'] = config.apiServer; req.socket.servername = targetHost; proxyLog('WS', req); try { proxy.ws(req, socket, head); } catch (err) { proxyLog(err); } }); let map = { 'Project': config.projectEndpoint.replace(config.projectToken, ''), 'Cluster': config.clusterEndpoint.replace(config.clusterToken, ''), 'Global': config.apiEndpoint, 'Public': config.publicApiEndpoint, 'Magic': config.magicEndpoint, 'Telemetry': config.telemetryEndpoint, 'K8s': '/k8s', 'Meta': '/meta', 'Swagger': '/swaggerapi', 'Version': '/version', 'Apiui': '/api-ui', 'Samlauth': '/v1-saml', } app.use('/', function(req, res, next) { if ( (req.headers['user-agent']||'').toLowerCase().includes('mozilla') ) { next(); } else { proxyLog('Root', req); req.headers['X-Forwarded-Proto'] = req.protocol; proxy.web(req, res); } }), console.log('Proxying APIs to', config.apiServer); Object.keys(map).forEach(function(label) { let base = map[label]; app.use(base, function(req, res, next) { if ( req.url === '/' ) { req.url = ''; } // include root path in proxied request req.url = path.join(base, req.url); req.headers['X-Forwarded-Proto'] = req.protocol; // don't include the original host header req.headers['X-Forwarded-Host'] = req.headers['host']; delete req.headers['host']; proxyLog(label, req); proxy.web(req, res); }); }); } function onProxyError(err, req, res) { console.log('Proxy Error on '+ req.method + ' to', req.url, err); var error = { type: 'error', status: 500, code: 'ProxyError', message: 'Error connecting to proxy', detail: err.toString() } if ( req.upgrade ) { res.end(); } else { res.writeHead(500, {'Content-Type': 'application/json'}); res.end(JSON.stringify(error)); } } function proxyLog(label, req) { console.log(`[${ label }]`, req.method, req.url); } function proxyError(label, req, err) { console.error(`[${ label }][${ req._source }]`, req.method, req.url, err); }