ui/server/proxies/api.js

139 lines
3.4 KiB
JavaScript

/* 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);
}