mirror of
https://github.com/elastic/kibana.git
synced 2025-06-28 03:01:21 -04:00
Add http.payloadTimeout
config option (#177309)
## Summary Fix https://github.com/elastic/kibana/issues/177138 - Add a `http.payloadTimeout` configuration option, to control the payload timeout - Set the default value for this option to `20s` (was `10s` previously)
This commit is contained in:
parent
9a473879af
commit
38a3b9675d
11 changed files with 46 additions and 2 deletions
|
@ -467,6 +467,11 @@ default is `true`. *Default: `deprecated`*
|
||||||
The number of milliseconds to wait before closing an
|
The number of milliseconds to wait before closing an
|
||||||
inactive socket. *Default: `"120000"`*
|
inactive socket. *Default: `"120000"`*
|
||||||
|
|
||||||
|
[[server-payloadTimeout]] `server.payloadTimeout`::
|
||||||
|
Sets the maximum time allowed for the client to transmit the request payload (body) before giving up
|
||||||
|
and responding with a Request Timeout (408) error response.
|
||||||
|
*Default: `"20000"`*
|
||||||
|
|
||||||
[[server-ssl-cert-key]] `server.ssl.certificate` and `server.ssl.key`::
|
[[server-ssl-cert-key]] `server.ssl.certificate` and `server.ssl.key`::
|
||||||
Paths to a PEM-encoded X.509 server certificate and its corresponding private key. These
|
Paths to a PEM-encoded X.509 server certificate and its corresponding private key. These
|
||||||
are used by {kib} to establish trust when receiving inbound SSL/TLS connections from users.
|
are used by {kib} to establish trust when receiving inbound SSL/TLS connections from users.
|
||||||
|
|
|
@ -73,6 +73,7 @@ Object {
|
||||||
"valueInBytes": 1048576,
|
"valueInBytes": 1048576,
|
||||||
},
|
},
|
||||||
"name": "kibana-hostname",
|
"name": "kibana-hostname",
|
||||||
|
"payloadTimeout": 20000,
|
||||||
"port": 5601,
|
"port": 5601,
|
||||||
"requestId": Object {
|
"requestId": Object {
|
||||||
"allowFromAnyIp": false,
|
"allowFromAnyIp": false,
|
||||||
|
|
|
@ -349,6 +349,14 @@ test('can specify socket timeouts', () => {
|
||||||
expect(socketTimeout).toBe(5e5);
|
expect(socketTimeout).toBe(5e5);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('can specify payload timeouts', () => {
|
||||||
|
const obj = {
|
||||||
|
payloadTimeout: 654321,
|
||||||
|
};
|
||||||
|
const { payloadTimeout } = config.schema.validate(obj);
|
||||||
|
expect(payloadTimeout).toBe(654321);
|
||||||
|
});
|
||||||
|
|
||||||
describe('with compression', () => {
|
describe('with compression', () => {
|
||||||
test('accepts valid referrer whitelist', () => {
|
test('accepts valid referrer whitelist', () => {
|
||||||
const {
|
const {
|
||||||
|
|
|
@ -26,6 +26,8 @@ import {
|
||||||
} from './security_response_headers_config';
|
} from './security_response_headers_config';
|
||||||
import { CdnConfig } from './cdn_config';
|
import { CdnConfig } from './cdn_config';
|
||||||
|
|
||||||
|
const SECOND = 1000;
|
||||||
|
|
||||||
const validBasePathRegex = /^\/.*[^\/]$/;
|
const validBasePathRegex = /^\/.*[^\/]$/;
|
||||||
|
|
||||||
const hostURISchema = schema.uri({ scheme: ['http', 'https'] });
|
const hostURISchema = schema.uri({ scheme: ['http', 'https'] });
|
||||||
|
@ -129,10 +131,13 @@ const configSchema = schema.object(
|
||||||
rewriteBasePath: schema.boolean({ defaultValue: false }),
|
rewriteBasePath: schema.boolean({ defaultValue: false }),
|
||||||
ssl: sslSchema,
|
ssl: sslSchema,
|
||||||
keepaliveTimeout: schema.number({
|
keepaliveTimeout: schema.number({
|
||||||
defaultValue: 120000,
|
defaultValue: 120 * SECOND,
|
||||||
}),
|
}),
|
||||||
socketTimeout: schema.number({
|
socketTimeout: schema.number({
|
||||||
defaultValue: 120000,
|
defaultValue: 120 * SECOND,
|
||||||
|
}),
|
||||||
|
payloadTimeout: schema.number({
|
||||||
|
defaultValue: 20 * SECOND,
|
||||||
}),
|
}),
|
||||||
compression: schema.object({
|
compression: schema.object({
|
||||||
enabled: schema.boolean({ defaultValue: true }),
|
enabled: schema.boolean({ defaultValue: true }),
|
||||||
|
@ -278,6 +283,7 @@ export class HttpConfig implements IHttpConfig {
|
||||||
public host: string;
|
public host: string;
|
||||||
public keepaliveTimeout: number;
|
public keepaliveTimeout: number;
|
||||||
public socketTimeout: number;
|
public socketTimeout: number;
|
||||||
|
public payloadTimeout: number;
|
||||||
public port: number;
|
public port: number;
|
||||||
public cors: {
|
public cors: {
|
||||||
enabled: boolean;
|
enabled: boolean;
|
||||||
|
@ -342,6 +348,7 @@ export class HttpConfig implements IHttpConfig {
|
||||||
this.publicBaseUrl = rawHttpConfig.publicBaseUrl;
|
this.publicBaseUrl = rawHttpConfig.publicBaseUrl;
|
||||||
this.keepaliveTimeout = rawHttpConfig.keepaliveTimeout;
|
this.keepaliveTimeout = rawHttpConfig.keepaliveTimeout;
|
||||||
this.socketTimeout = rawHttpConfig.socketTimeout;
|
this.socketTimeout = rawHttpConfig.socketTimeout;
|
||||||
|
this.payloadTimeout = rawHttpConfig.payloadTimeout;
|
||||||
this.rewriteBasePath = rawHttpConfig.rewriteBasePath;
|
this.rewriteBasePath = rawHttpConfig.rewriteBasePath;
|
||||||
this.ssl = new SslConfig(rawHttpConfig.ssl || {});
|
this.ssl = new SslConfig(rawHttpConfig.ssl || {});
|
||||||
this.compression = rawHttpConfig.compression;
|
this.compression = rawHttpConfig.compression;
|
||||||
|
|
|
@ -30,6 +30,9 @@ export const httpConfigSchema = schema.object(
|
||||||
socketTimeout: schema.number({
|
socketTimeout: schema.number({
|
||||||
defaultValue: 120000,
|
defaultValue: 120000,
|
||||||
}),
|
}),
|
||||||
|
payloadTimeout: schema.number({
|
||||||
|
defaultValue: 20000,
|
||||||
|
}),
|
||||||
cors: schema.object({
|
cors: schema.object({
|
||||||
enabled: schema.boolean({ defaultValue: false }),
|
enabled: schema.boolean({ defaultValue: false }),
|
||||||
allowCredentials: schema.boolean({ defaultValue: false }),
|
allowCredentials: schema.boolean({ defaultValue: false }),
|
||||||
|
@ -53,6 +56,7 @@ export class HttpConfig implements IHttpConfig {
|
||||||
shutdownTimeout: Duration;
|
shutdownTimeout: Duration;
|
||||||
keepaliveTimeout: number;
|
keepaliveTimeout: number;
|
||||||
socketTimeout: number;
|
socketTimeout: number;
|
||||||
|
payloadTimeout: number;
|
||||||
cors: ICorsConfig;
|
cors: ICorsConfig;
|
||||||
ssl: ISslConfig;
|
ssl: ISslConfig;
|
||||||
restrictInternalApis: boolean;
|
restrictInternalApis: boolean;
|
||||||
|
@ -64,6 +68,7 @@ export class HttpConfig implements IHttpConfig {
|
||||||
this.maxPayload = rawConfig.maxPayload;
|
this.maxPayload = rawConfig.maxPayload;
|
||||||
this.shutdownTimeout = rawConfig.shutdownTimeout;
|
this.shutdownTimeout = rawConfig.shutdownTimeout;
|
||||||
this.keepaliveTimeout = rawConfig.keepaliveTimeout;
|
this.keepaliveTimeout = rawConfig.keepaliveTimeout;
|
||||||
|
this.payloadTimeout = rawConfig.payloadTimeout;
|
||||||
this.socketTimeout = rawConfig.socketTimeout;
|
this.socketTimeout = rawConfig.socketTimeout;
|
||||||
this.cors = rawConfig.cors;
|
this.cors = rawConfig.cors;
|
||||||
this.ssl = new SslConfig(rawConfig.ssl);
|
this.ssl = new SslConfig(rawConfig.ssl);
|
||||||
|
|
|
@ -39,6 +39,7 @@ describe('BasePathProxyServer', () => {
|
||||||
shutdownTimeout: moment.duration(30, 'seconds'),
|
shutdownTimeout: moment.duration(30, 'seconds'),
|
||||||
keepaliveTimeout: 1000,
|
keepaliveTimeout: 1000,
|
||||||
socketTimeout: 1000,
|
socketTimeout: 1000,
|
||||||
|
payloadTimeout: 1000,
|
||||||
cors: {
|
cors: {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
allowCredentials: false,
|
allowCredentials: false,
|
||||||
|
|
|
@ -19,6 +19,7 @@ describe('server config', () => {
|
||||||
"maxPayload": ByteSizeValue {
|
"maxPayload": ByteSizeValue {
|
||||||
"valueInBytes": 1048576,
|
"valueInBytes": 1048576,
|
||||||
},
|
},
|
||||||
|
"payloadTimeout": 20000,
|
||||||
"port": 3000,
|
"port": 3000,
|
||||||
"restrictInternalApis": false,
|
"restrictInternalApis": false,
|
||||||
"shutdownTimeout": "PT30S",
|
"shutdownTimeout": "PT30S",
|
||||||
|
|
|
@ -27,6 +27,9 @@ const configSchema = schema.object(
|
||||||
keepaliveTimeout: schema.number({
|
keepaliveTimeout: schema.number({
|
||||||
defaultValue: 120000,
|
defaultValue: 120000,
|
||||||
}),
|
}),
|
||||||
|
payloadTimeout: schema.number({
|
||||||
|
defaultValue: 20000,
|
||||||
|
}),
|
||||||
shutdownTimeout: schema.duration({
|
shutdownTimeout: schema.duration({
|
||||||
defaultValue: '30s',
|
defaultValue: '30s',
|
||||||
validate: (duration) => {
|
validate: (duration) => {
|
||||||
|
@ -73,6 +76,7 @@ export class ServerConfig implements IHttpConfig {
|
||||||
keepaliveTimeout: number;
|
keepaliveTimeout: number;
|
||||||
shutdownTimeout: Duration;
|
shutdownTimeout: Duration;
|
||||||
socketTimeout: number;
|
socketTimeout: number;
|
||||||
|
payloadTimeout: number;
|
||||||
ssl: ISslConfig;
|
ssl: ISslConfig;
|
||||||
cors: ICorsConfig;
|
cors: ICorsConfig;
|
||||||
restrictInternalApis: boolean;
|
restrictInternalApis: boolean;
|
||||||
|
@ -84,6 +88,7 @@ export class ServerConfig implements IHttpConfig {
|
||||||
this.keepaliveTimeout = rawConfig.keepaliveTimeout;
|
this.keepaliveTimeout = rawConfig.keepaliveTimeout;
|
||||||
this.shutdownTimeout = rawConfig.shutdownTimeout;
|
this.shutdownTimeout = rawConfig.shutdownTimeout;
|
||||||
this.socketTimeout = rawConfig.socketTimeout;
|
this.socketTimeout = rawConfig.socketTimeout;
|
||||||
|
this.payloadTimeout = rawConfig.payloadTimeout;
|
||||||
this.ssl = new SslConfig(rawConfig.ssl);
|
this.ssl = new SslConfig(rawConfig.ssl);
|
||||||
this.cors = {
|
this.cors = {
|
||||||
enabled: false,
|
enabled: false,
|
||||||
|
|
|
@ -25,6 +25,7 @@ const createConfig = (parts: Partial<IHttpConfig>): IHttpConfig => ({
|
||||||
port: 5601,
|
port: 5601,
|
||||||
socketTimeout: 120000,
|
socketTimeout: 120000,
|
||||||
keepaliveTimeout: 120000,
|
keepaliveTimeout: 120000,
|
||||||
|
payloadTimeout: 20000,
|
||||||
shutdownTimeout: moment.duration(30, 'seconds'),
|
shutdownTimeout: moment.duration(30, 'seconds'),
|
||||||
maxPayload: ByteSizeValue.parse('1048576b'),
|
maxPayload: ByteSizeValue.parse('1048576b'),
|
||||||
...parts,
|
...parts,
|
||||||
|
@ -122,4 +123,12 @@ describe('getServerOptions', () => {
|
||||||
headers: ['Accept', 'Authorization', 'Content-Type', 'If-None-Match', 'kbn-xsrf'],
|
headers: ['Accept', 'Authorization', 'Content-Type', 'If-None-Match', 'kbn-xsrf'],
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
it('properly configures `routes.payload.timeout`', () => {
|
||||||
|
const httpConfig = createConfig({
|
||||||
|
payloadTimeout: 9007,
|
||||||
|
});
|
||||||
|
|
||||||
|
expect(getServerOptions(httpConfig).routes!.payload!.timeout).toEqual(9007);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
|
@ -35,6 +35,7 @@ export function getServerOptions(config: IHttpConfig, { configureTLS = true } =
|
||||||
cors,
|
cors,
|
||||||
payload: {
|
payload: {
|
||||||
maxBytes: config.maxPayload.getValueInBytes(),
|
maxBytes: config.maxPayload.getValueInBytes(),
|
||||||
|
timeout: config.payloadTimeout,
|
||||||
},
|
},
|
||||||
validate: {
|
validate: {
|
||||||
failAction: defaultValidationErrorHandler,
|
failAction: defaultValidationErrorHandler,
|
||||||
|
|
|
@ -15,6 +15,7 @@ export interface IHttpConfig {
|
||||||
maxPayload: ByteSizeValue;
|
maxPayload: ByteSizeValue;
|
||||||
keepaliveTimeout: number;
|
keepaliveTimeout: number;
|
||||||
socketTimeout: number;
|
socketTimeout: number;
|
||||||
|
payloadTimeout: number;
|
||||||
cors: ICorsConfig;
|
cors: ICorsConfig;
|
||||||
ssl: ISslConfig;
|
ssl: ISslConfig;
|
||||||
shutdownTimeout: Duration;
|
shutdownTimeout: Duration;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue