UNPKG

kibana-123

Version:

Kibana is an open source (Apache Licensed), browser based analytics and search dashboard for Elasticsearch. Kibana is a snap to setup and start using. Kibana strives to be easy to get started with, while also being flexible and powerful, just like Elastic

132 lines (111 loc) 3.85 kB
import { Server } from 'hapi'; import { notFound } from 'boom'; import { merge, sample } from 'lodash'; import { format as formatUrl } from 'url'; import { map, fromNode } from 'bluebird'; import { Agent as HttpsAgent } from 'https'; import { readFileSync } from 'fs'; import Config from '../../server/config/config'; import setupConnection from '../../server/http/setup_connection'; import registerHapiPlugins from '../../server/http/register_hapi_plugins'; import setupLogging from '../../server/logging'; import { DEV_SSL_CERT_PATH } from '../dev_ssl'; const alphabet = 'abcdefghijklmnopqrztuvwxyz'.split(''); export default class BasePathProxy { constructor(clusterManager, userSettings) { this.clusterManager = clusterManager; this.server = new Server(); const config = Config.withDefaultSchema(userSettings); this.targetPort = config.get('dev.basePathProxyTarget'); this.basePath = config.get('server.basePath'); const { cert } = config.get('server.ssl'); if (cert) { const httpsAgentConfig = {}; if (cert === DEV_SSL_CERT_PATH && config.get('server.host') !== 'localhost') { httpsAgentConfig.rejectUnauthorized = false; } else { httpsAgentConfig.ca = readFileSync(cert); } this.proxyAgent = new HttpsAgent(httpsAgentConfig); } if (!this.basePath) { this.basePath = `/${sample(alphabet, 3).join('')}`; config.set('server.basePath', this.basePath); } const ONE_GIGABYTE = 1024 * 1024 * 1024; config.set('server.maxPayloadBytes', ONE_GIGABYTE); setupLogging(null, this.server, config); setupConnection(null, this.server, config); registerHapiPlugins(null, this.server, config); this.setupRoutes(); } setupRoutes() { const { clusterManager, server, basePath, targetPort } = this; server.route({ method: 'GET', path: '/', handler(req, reply) { return reply.redirect(basePath); } }); server.route({ method: '*', path: `${basePath}/{kbnPath*}`, config: { pre: [ (req, reply) => { map(clusterManager.workers, worker => { if (worker.type === 'server' && !worker.listening && !worker.crashed) { return fromNode(cb => { const done = () => { worker.removeListener('listening', done); worker.removeListener('crashed', done); cb(); }; worker.on('listening', done); worker.on('crashed', done); }); } }) .return(undefined) .nodeify(reply); } ], }, handler: { proxy: { passThrough: true, xforward: true, agent: this.proxyAgent, mapUri(req, callback) { callback(null, formatUrl({ protocol: server.info.protocol, hostname: server.info.host, port: targetPort, pathname: req.params.kbnPath, query: req.query, })); } } } }); server.route({ method: '*', path: `/{oldBasePath}/{kbnPath*}`, handler(req, reply) { const {oldBasePath, kbnPath = ''} = req.params; const isGet = req.method === 'get'; const isBasePath = oldBasePath.length === 3; const isApp = kbnPath.slice(0, 4) === 'app/'; if (isGet && isBasePath && isApp) { return reply.redirect(`${basePath}/${kbnPath}`); } return reply(notFound()); } }); } async listen() { await fromNode(cb => this.server.start(cb)); this.server.log(['listening', 'info'], `basePath Proxy running at ${this.server.info.uri}${this.basePath}`); } }