parent
29fa09bb6f
commit
f027fad862
|
@ -209,9 +209,6 @@ Specify the position of the subdomain the URL with the token `{s}`.
|
||||||
|
|
||||||
`server.host:`:: *Default: "localhost"* This setting specifies the host of the back end server.
|
`server.host:`:: *Default: "localhost"* This setting specifies the host of the back end server.
|
||||||
|
|
||||||
`server.keepaliveTimeout:`:: *Default: "120000"* The number of milliseconds to wait for additional data before restarting
|
|
||||||
the `server.socketTimeout` counter.
|
|
||||||
|
|
||||||
`server.maxPayloadBytes:`:: *Default: 1048576* The maximum payload size in bytes for incoming server requests.
|
`server.maxPayloadBytes:`:: *Default: 1048576* The maximum payload size in bytes for incoming server requests.
|
||||||
|
|
||||||
`server.name:`:: *Default: "your-hostname"* A human-readable display name that identifies this Kibana instance.
|
`server.name:`:: *Default: "your-hostname"* A human-readable display name that identifies this Kibana instance.
|
||||||
|
@ -220,9 +217,6 @@ the `server.socketTimeout` counter.
|
||||||
|
|
||||||
`server.ssl.enabled:`:: *Default: "false"* Enables SSL for outgoing requests from the Kibana server to the browser. When set to `true`, `server.ssl.certificate` and `server.ssl.key` are required
|
`server.ssl.enabled:`:: *Default: "false"* Enables SSL for outgoing requests from the Kibana server to the browser. When set to `true`, `server.ssl.certificate` and `server.ssl.key` are required
|
||||||
|
|
||||||
`server.socketTimeout:`:: *Default: "120000"* The number of milliseconds to wait before closing an
|
|
||||||
inactive socket.
|
|
||||||
|
|
||||||
`server.ssl.cert:`:: Path to the PEM-format SSL certificate. This file enables
|
`server.ssl.cert:`:: Path to the PEM-format SSL certificate. This file enables
|
||||||
SSL for outgoing requests from the Kibana server to the browser.
|
SSL for outgoing requests from the Kibana server to the browser.
|
||||||
deprecated[5.3.0,Replaced by `server.ssl.certificate`]
|
deprecated[5.3.0,Replaced by `server.ssl.certificate`]
|
||||||
|
|
|
@ -14,13 +14,11 @@ Object {
|
||||||
"autoListen": true,
|
"autoListen": true,
|
||||||
"cors": false,
|
"cors": false,
|
||||||
"host": "localhost",
|
"host": "localhost",
|
||||||
"keepaliveTimeout": 120000,
|
|
||||||
"maxPayload": ByteSizeValue {
|
"maxPayload": ByteSizeValue {
|
||||||
"valueInBytes": 1048576,
|
"valueInBytes": 1048576,
|
||||||
},
|
},
|
||||||
"port": 5601,
|
"port": 5601,
|
||||||
"rewriteBasePath": false,
|
"rewriteBasePath": false,
|
||||||
"socketTimeout": 120000,
|
|
||||||
"ssl": Object {
|
"ssl": Object {
|
||||||
"cipherSuites": Array [
|
"cipherSuites": Array [
|
||||||
"ECDHE-RSA-AES128-GCM-SHA256",
|
"ECDHE-RSA-AES128-GCM-SHA256",
|
||||||
|
|
|
@ -24,7 +24,7 @@ import { sample } from 'lodash';
|
||||||
import { DevConfig } from '../dev';
|
import { DevConfig } from '../dev';
|
||||||
import { Logger } from '../logging';
|
import { Logger } from '../logging';
|
||||||
import { HttpConfig } from './http_config';
|
import { HttpConfig } from './http_config';
|
||||||
import { createServer, getListenerOptions, getServerOptions } from './http_tools';
|
import { createServer, getServerOptions } from './http_tools';
|
||||||
|
|
||||||
const alphabet = 'abcdefghijklmnopqrztuvwxyz'.split('');
|
const alphabet = 'abcdefghijklmnopqrztuvwxyz'.split('');
|
||||||
|
|
||||||
|
@ -62,8 +62,7 @@ export class BasePathProxyServer {
|
||||||
this.log.debug('starting basepath proxy server');
|
this.log.debug('starting basepath proxy server');
|
||||||
|
|
||||||
const serverOptions = getServerOptions(this.httpConfig);
|
const serverOptions = getServerOptions(this.httpConfig);
|
||||||
const listenerOptions = getListenerOptions(this.httpConfig);
|
this.server = createServer(serverOptions);
|
||||||
this.server = createServer(serverOptions, listenerOptions);
|
|
||||||
|
|
||||||
// Register hapi plugin that adds proxying functionality. It can be configured
|
// Register hapi plugin that adds proxying functionality. It can be configured
|
||||||
// through the route configuration object (see { handler: { proxy: ... } }).
|
// through the route configuration object (see { handler: { proxy: ... } }).
|
||||||
|
|
|
@ -127,16 +127,6 @@ describe('with TLS', () => {
|
||||||
expect(config.ssl.certificateAuthorities).toBe('/authority/');
|
expect(config.ssl.certificateAuthorities).toBe('/authority/');
|
||||||
});
|
});
|
||||||
|
|
||||||
test('can specify socket timeouts', () => {
|
|
||||||
const obj = {
|
|
||||||
keepaliveTimeout: 1e5,
|
|
||||||
socketTimeout: 5e5,
|
|
||||||
};
|
|
||||||
const { keepaliveTimeout, socketTimeout } = HttpConfig.schema.validate(obj);
|
|
||||||
expect(keepaliveTimeout).toBe(1e5);
|
|
||||||
expect(socketTimeout).toBe(5e5);
|
|
||||||
});
|
|
||||||
|
|
||||||
test('can specify several `certificateAuthorities`', () => {
|
test('can specify several `certificateAuthorities`', () => {
|
||||||
const httpSchema = HttpConfig.schema;
|
const httpSchema = HttpConfig.schema;
|
||||||
const obj = {
|
const obj = {
|
||||||
|
|
|
@ -61,12 +61,6 @@ const createHttpSchema = schema.object(
|
||||||
}),
|
}),
|
||||||
rewriteBasePath: schema.boolean({ defaultValue: false }),
|
rewriteBasePath: schema.boolean({ defaultValue: false }),
|
||||||
ssl: SslConfig.schema,
|
ssl: SslConfig.schema,
|
||||||
keepaliveTimeout: schema.number({
|
|
||||||
defaultValue: 120000,
|
|
||||||
}),
|
|
||||||
socketTimeout: schema.number({
|
|
||||||
defaultValue: 120000,
|
|
||||||
}),
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
validate: config => {
|
validate: config => {
|
||||||
|
@ -99,8 +93,6 @@ export class HttpConfig {
|
||||||
|
|
||||||
public autoListen: boolean;
|
public autoListen: boolean;
|
||||||
public host: string;
|
public host: string;
|
||||||
public keepaliveTimeout: number;
|
|
||||||
public socketTimeout: number;
|
|
||||||
public port: number;
|
public port: number;
|
||||||
public cors: boolean | { origin: string[] };
|
public cors: boolean | { origin: string[] };
|
||||||
public maxPayload: ByteSizeValue;
|
public maxPayload: ByteSizeValue;
|
||||||
|
@ -121,8 +113,6 @@ export class HttpConfig {
|
||||||
this.basePath = config.basePath;
|
this.basePath = config.basePath;
|
||||||
this.rewriteBasePath = config.rewriteBasePath;
|
this.rewriteBasePath = config.rewriteBasePath;
|
||||||
this.publicDir = env.staticFilesDir;
|
this.publicDir = env.staticFilesDir;
|
||||||
this.keepaliveTimeout = config.keepaliveTimeout;
|
|
||||||
this.socketTimeout = config.socketTimeout;
|
|
||||||
this.ssl = new SslConfig(config.ssl);
|
this.ssl = new SslConfig(config.ssl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ import { Server, ServerOptions } from 'hapi';
|
||||||
import { modifyUrl } from '../../utils';
|
import { modifyUrl } from '../../utils';
|
||||||
import { Logger } from '../logging';
|
import { Logger } from '../logging';
|
||||||
import { HttpConfig } from './http_config';
|
import { HttpConfig } from './http_config';
|
||||||
import { createServer, getListenerOptions, getServerOptions } from './http_tools';
|
import { createServer, getServerOptions } from './http_tools';
|
||||||
import { Router } from './router';
|
import { Router } from './router';
|
||||||
|
|
||||||
export interface HttpServerInfo {
|
export interface HttpServerInfo {
|
||||||
|
@ -52,8 +52,7 @@ export class HttpServer {
|
||||||
this.log.debug('starting http server');
|
this.log.debug('starting http server');
|
||||||
|
|
||||||
const serverOptions = getServerOptions(config);
|
const serverOptions = getServerOptions(config);
|
||||||
const listenerOptions = getListenerOptions(config);
|
this.server = createServer(serverOptions);
|
||||||
this.server = createServer(serverOptions, listenerOptions);
|
|
||||||
|
|
||||||
this.setupBasePathRewrite(this.server, config);
|
this.setupBasePathRewrite(this.server, config);
|
||||||
|
|
||||||
|
|
|
@ -19,15 +19,7 @@
|
||||||
|
|
||||||
import { Request, ResponseToolkit } from 'hapi';
|
import { Request, ResponseToolkit } from 'hapi';
|
||||||
import Joi from 'joi';
|
import Joi from 'joi';
|
||||||
import supertest from 'supertest';
|
|
||||||
|
|
||||||
import { logger } from '../logging/__mocks__';
|
|
||||||
|
|
||||||
import { ByteSizeValue } from '@kbn/config-schema';
|
|
||||||
import { HttpConfig } from './http_config';
|
|
||||||
import { HttpServer } from './http_server';
|
|
||||||
import { defaultValidationErrorHandler, HapiValidationError } from './http_tools';
|
import { defaultValidationErrorHandler, HapiValidationError } from './http_tools';
|
||||||
import { Router } from './router';
|
|
||||||
|
|
||||||
const emptyOutput = {
|
const emptyOutput = {
|
||||||
statusCode: 400,
|
statusCode: 400,
|
||||||
|
@ -65,37 +57,3 @@ describe('defaultValidationErrorHandler', () => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
describe('timeouts', () => {
|
|
||||||
const server = new HttpServer(logger.get());
|
|
||||||
|
|
||||||
test('returns 408 on timeout error', async () => {
|
|
||||||
const router = new Router('');
|
|
||||||
router.get({ path: '/a', validate: false }, async (req, res) => {
|
|
||||||
await new Promise(resolve => setTimeout(resolve, 2000));
|
|
||||||
return res.ok({});
|
|
||||||
});
|
|
||||||
router.get({ path: '/b', validate: false }, async (req, res) => res.ok({}));
|
|
||||||
server.registerRouter(router);
|
|
||||||
|
|
||||||
const config = {
|
|
||||||
socketTimeout: 1000,
|
|
||||||
host: '127.0.0.1',
|
|
||||||
maxPayload: new ByteSizeValue(1024),
|
|
||||||
ssl: {},
|
|
||||||
} as HttpConfig;
|
|
||||||
|
|
||||||
const { server: innerServer } = await server.start(config);
|
|
||||||
await supertest(innerServer.listener)
|
|
||||||
.get('/a')
|
|
||||||
.expect(408);
|
|
||||||
await supertest(innerServer.listener)
|
|
||||||
.get('/b')
|
|
||||||
.expect(200);
|
|
||||||
});
|
|
||||||
|
|
||||||
afterAll(async () => {
|
|
||||||
await server.stop();
|
|
||||||
logger.mockClear();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
|
@ -78,30 +78,11 @@ export function getServerOptions(config: HttpConfig, { configureTLS = true } = {
|
||||||
return options;
|
return options;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getListenerOptions(config: HttpConfig) {
|
export function createServer(options: ServerOptions) {
|
||||||
return {
|
const server = new Server(options);
|
||||||
keepaliveTimeout: config.keepaliveTimeout,
|
|
||||||
socketTimeout: config.socketTimeout,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
interface ListenerOptions {
|
// Revert to previous 120 seconds keep-alive timeout in Node < 8.
|
||||||
keepaliveTimeout: number;
|
server.listener.keepAliveTimeout = 120e3;
|
||||||
socketTimeout: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export function createServer(serverOptions: ServerOptions, listenerOptions: ListenerOptions) {
|
|
||||||
const server = new Server(serverOptions);
|
|
||||||
|
|
||||||
server.listener.keepAliveTimeout = listenerOptions.keepaliveTimeout;
|
|
||||||
server.listener.setTimeout(listenerOptions.socketTimeout);
|
|
||||||
server.listener.on('timeout', socket => {
|
|
||||||
if (socket.writable) {
|
|
||||||
socket.end(Buffer.from('HTTP/1.1 408 Request Timeout\r\n\r\n', 'ascii'));
|
|
||||||
} else {
|
|
||||||
socket.destroy();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
server.listener.on('clientError', (err, socket) => {
|
server.listener.on('clientError', (err, socket) => {
|
||||||
if (socket.writable) {
|
if (socket.writable) {
|
||||||
socket.end(Buffer.from('HTTP/1.1 400 Bad Request\r\n\r\n', 'ascii'));
|
socket.end(Buffer.from('HTTP/1.1 400 Bad Request\r\n\r\n', 'ascii'));
|
||||||
|
|
|
@ -22,7 +22,7 @@ import { format as formatUrl } from 'url';
|
||||||
|
|
||||||
import { Logger } from '../logging';
|
import { Logger } from '../logging';
|
||||||
import { HttpConfig } from './http_config';
|
import { HttpConfig } from './http_config';
|
||||||
import { createServer, getListenerOptions, getServerOptions } from './http_tools';
|
import { createServer, getServerOptions } from './http_tools';
|
||||||
|
|
||||||
export class HttpsRedirectServer {
|
export class HttpsRedirectServer {
|
||||||
private server?: Server;
|
private server?: Server;
|
||||||
|
@ -42,13 +42,10 @@ export class HttpsRedirectServer {
|
||||||
// Redirect server is configured in the same way as any other HTTP server
|
// Redirect server is configured in the same way as any other HTTP server
|
||||||
// within the platform with the only exception that it should always be a
|
// within the platform with the only exception that it should always be a
|
||||||
// plain HTTP server, so we just ignore `tls` part of options.
|
// plain HTTP server, so we just ignore `tls` part of options.
|
||||||
this.server = createServer(
|
this.server = createServer({
|
||||||
{
|
...getServerOptions(config, { configureTLS: false }),
|
||||||
...getServerOptions(config, { configureTLS: false }),
|
port: config.ssl.redirectHttpFromPort,
|
||||||
port: config.ssl.redirectHttpFromPort,
|
});
|
||||||
},
|
|
||||||
getListenerOptions(config)
|
|
||||||
);
|
|
||||||
|
|
||||||
this.server.ext('onRequest', (request: Request, responseToolkit: ResponseToolkit) => {
|
this.server.ext('onRequest', (request: Request, responseToolkit: ResponseToolkit) => {
|
||||||
return responseToolkit
|
return responseToolkit
|
||||||
|
|
|
@ -6,11 +6,9 @@ Object {
|
||||||
"basePath": "/abc",
|
"basePath": "/abc",
|
||||||
"cors": false,
|
"cors": false,
|
||||||
"host": "host",
|
"host": "host",
|
||||||
"keepaliveTimeout": 5000,
|
|
||||||
"maxPayload": 1000,
|
"maxPayload": 1000,
|
||||||
"port": 1234,
|
"port": 1234,
|
||||||
"rewriteBasePath": false,
|
"rewriteBasePath": false,
|
||||||
"socketTimeout": 2000,
|
|
||||||
"ssl": Object {
|
"ssl": Object {
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
"keyPassphrase": "some-phrase",
|
"keyPassphrase": "some-phrase",
|
||||||
|
@ -25,11 +23,9 @@ Object {
|
||||||
"basePath": "/abc",
|
"basePath": "/abc",
|
||||||
"cors": false,
|
"cors": false,
|
||||||
"host": "host",
|
"host": "host",
|
||||||
"keepaliveTimeout": 5000,
|
|
||||||
"maxPayload": 1000,
|
"maxPayload": 1000,
|
||||||
"port": 1234,
|
"port": 1234,
|
||||||
"rewriteBasePath": false,
|
"rewriteBasePath": false,
|
||||||
"socketTimeout": 2000,
|
|
||||||
"ssl": Object {
|
"ssl": Object {
|
||||||
"certificate": "cert",
|
"certificate": "cert",
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
|
@ -44,11 +40,9 @@ Object {
|
||||||
"basePath": "/abc",
|
"basePath": "/abc",
|
||||||
"cors": false,
|
"cors": false,
|
||||||
"host": "host",
|
"host": "host",
|
||||||
"keepaliveTimeout": 5000,
|
|
||||||
"maxPayload": 1000,
|
"maxPayload": 1000,
|
||||||
"port": 1234,
|
"port": 1234,
|
||||||
"rewriteBasePath": false,
|
"rewriteBasePath": false,
|
||||||
"socketTimeout": 2000,
|
|
||||||
"ssl": Object {
|
"ssl": Object {
|
||||||
"certificate": "deprecated-cert",
|
"certificate": "deprecated-cert",
|
||||||
"enabled": true,
|
"enabled": true,
|
||||||
|
@ -63,11 +57,9 @@ Object {
|
||||||
"basePath": "/abc",
|
"basePath": "/abc",
|
||||||
"cors": false,
|
"cors": false,
|
||||||
"host": "host",
|
"host": "host",
|
||||||
"keepaliveTimeout": 5000,
|
|
||||||
"maxPayload": 1000,
|
"maxPayload": 1000,
|
||||||
"port": 1234,
|
"port": 1234,
|
||||||
"rewriteBasePath": false,
|
"rewriteBasePath": false,
|
||||||
"socketTimeout": 2000,
|
|
||||||
"ssl": Object {
|
"ssl": Object {
|
||||||
"certificate": "cert",
|
"certificate": "cert",
|
||||||
"enabled": false,
|
"enabled": false,
|
||||||
|
|
|
@ -70,8 +70,6 @@ describe('#get', () => {
|
||||||
host: 'host',
|
host: 'host',
|
||||||
maxPayloadBytes: 1000,
|
maxPayloadBytes: 1000,
|
||||||
port: 1234,
|
port: 1234,
|
||||||
keepaliveTimeout: 5000,
|
|
||||||
socketTimeout: 2000,
|
|
||||||
rewriteBasePath: false,
|
rewriteBasePath: false,
|
||||||
ssl: { enabled: true, keyPassphrase: 'some-phrase', someNewValue: 'new' },
|
ssl: { enabled: true, keyPassphrase: 'some-phrase', someNewValue: 'new' },
|
||||||
someNotSupportedValue: 'val',
|
someNotSupportedValue: 'val',
|
||||||
|
@ -86,8 +84,6 @@ describe('#get', () => {
|
||||||
host: 'host',
|
host: 'host',
|
||||||
maxPayloadBytes: 1000,
|
maxPayloadBytes: 1000,
|
||||||
port: 1234,
|
port: 1234,
|
||||||
keepaliveTimeout: 5000,
|
|
||||||
socketTimeout: 2000,
|
|
||||||
rewriteBasePath: false,
|
rewriteBasePath: false,
|
||||||
ssl: { enabled: false, certificate: 'cert', key: 'key' },
|
ssl: { enabled: false, certificate: 'cert', key: 'key' },
|
||||||
someNotSupportedValue: 'val',
|
someNotSupportedValue: 'val',
|
||||||
|
@ -102,8 +98,6 @@ describe('#get', () => {
|
||||||
host: 'host',
|
host: 'host',
|
||||||
maxPayloadBytes: 1000,
|
maxPayloadBytes: 1000,
|
||||||
port: 1234,
|
port: 1234,
|
||||||
keepaliveTimeout: 5000,
|
|
||||||
socketTimeout: 2000,
|
|
||||||
rewriteBasePath: false,
|
rewriteBasePath: false,
|
||||||
ssl: { enabled: true, cert: 'deprecated-cert', key: 'key' },
|
ssl: { enabled: true, cert: 'deprecated-cert', key: 'key' },
|
||||||
someNotSupportedValue: 'val',
|
someNotSupportedValue: 'val',
|
||||||
|
@ -118,8 +112,6 @@ describe('#get', () => {
|
||||||
host: 'host',
|
host: 'host',
|
||||||
maxPayloadBytes: 1000,
|
maxPayloadBytes: 1000,
|
||||||
port: 1234,
|
port: 1234,
|
||||||
keepaliveTimeout: 5000,
|
|
||||||
socketTimeout: 2000,
|
|
||||||
rewriteBasePath: false,
|
rewriteBasePath: false,
|
||||||
ssl: { certificate: 'cert', key: 'key' },
|
ssl: { certificate: 'cert', key: 'key' },
|
||||||
someNotSupportedValue: 'val',
|
someNotSupportedValue: 'val',
|
||||||
|
|
|
@ -66,8 +66,6 @@ export class LegacyObjectToConfigAdapter extends ObjectToConfigAdapter {
|
||||||
host: configValue.host,
|
host: configValue.host,
|
||||||
maxPayload: configValue.maxPayloadBytes,
|
maxPayload: configValue.maxPayloadBytes,
|
||||||
port: configValue.port,
|
port: configValue.port,
|
||||||
keepaliveTimeout: configValue.keepaliveTimeout,
|
|
||||||
socketTimeout: configValue.socketTimeout,
|
|
||||||
rewriteBasePath: configValue.rewriteBasePath,
|
rewriteBasePath: configValue.rewriteBasePath,
|
||||||
ssl: configValue.ssl && LegacyObjectToConfigAdapter.transformSSL(configValue.ssl),
|
ssl: configValue.ssl && LegacyObjectToConfigAdapter.transformSSL(configValue.ssl),
|
||||||
};
|
};
|
||||||
|
|
|
@ -119,8 +119,6 @@ export default () => Joi.object({
|
||||||
name: Joi.string().default(os.hostname()),
|
name: Joi.string().default(os.hostname()),
|
||||||
host: Joi.string().hostname().default('localhost'),
|
host: Joi.string().hostname().default('localhost'),
|
||||||
port: Joi.number().default(5601),
|
port: Joi.number().default(5601),
|
||||||
keepaliveTimeout: Joi.number().default(120000),
|
|
||||||
socketTimeout: Joi.number().default(120000),
|
|
||||||
maxPayloadBytes: Joi.number().default(1048576),
|
maxPayloadBytes: Joi.number().default(1048576),
|
||||||
autoListen: Joi.boolean().default(true),
|
autoListen: Joi.boolean().default(true),
|
||||||
defaultRoute: Joi.string().default('/app/kibana').regex(/^\//, `start with a slash`),
|
defaultRoute: Joi.string().default('/app/kibana').regex(/^\//, `start with a slash`),
|
||||||
|
|
Loading…
Reference in a new issue