diff --git a/docs/pages/product/configuration/reference/environment-variables.mdx b/docs/pages/product/configuration/reference/environment-variables.mdx index 0a1320c211afe..613215219f9b9 100644 --- a/docs/pages/product/configuration/reference/environment-variables.mdx +++ b/docs/pages/product/configuration/reference/environment-variables.mdx @@ -1136,6 +1136,26 @@ Until v0.35, the default value was `schema`. It can be also set using the [`schema_path` configuration option](/product/configuration/reference/config#schema_path). +## `CUBEJS_SERVER_HEADERS_TIMEOUT` + +The number of milliseconds to limit the amount of time the parser will wait +to receive the complete HTTP headers. +If the timeout expires, the server responds with status 408 without +forwarding the request to the request listener and then closes the connection. + +| Possible Values | Default in Development | Default in Production | +| ----------------------------------------- | ------------------------ | ------------------------ | +| A valid number or string representing one | NodeJS's version default | NodeJS's version default | + +## `CUBEJS_SERVER_KEEP_ALIVE_TIMEOUT` + +The number of milliseconds of inactivity a server needs to wait for additional incoming data, +after it has finished writing the last response, before a socket will be destroyed. + +| Possible Values | Default in Development | Default in Production | +| ----------------------------------------- | ------------------------ | ------------------------ | +| A valid number or string representing one | NodeJS's version default | NodeJS's version default | + ## `CUBEJS_SQL_USER` A username required to access the [SQL API][ref-sql-api]. diff --git a/packages/cubejs-backend-shared/src/env.ts b/packages/cubejs-backend-shared/src/env.ts index 9ce3789cbb409..f3f37fd0c7d39 100644 --- a/packages/cubejs-backend-shared/src/env.ts +++ b/packages/cubejs-backend-shared/src/env.ts @@ -144,6 +144,10 @@ const variables: Record any> = { webSockets: () => get('CUBEJS_WEB_SOCKETS') .default('false') .asBoolStrict(), + serverHeadersTimeout: () => get('CUBEJS_SERVER_HEADERS_TIMEOUT') + .asInt(), + serverKeepAliveTimeout: () => get('CUBEJS_SERVER_KEEP_ALIVE_TIMEOUT') + .asInt(), rollupOnlyMode: () => get('CUBEJS_ROLLUP_ONLY') .default('false') .asBoolStrict(), diff --git a/packages/cubejs-server-core/src/core/optionsValidate.ts b/packages/cubejs-server-core/src/core/optionsValidate.ts index cadc3e5f77c64..4d71408ea06c3 100644 --- a/packages/cubejs-server-core/src/core/optionsValidate.ts +++ b/packages/cubejs-server-core/src/core/optionsValidate.ts @@ -52,6 +52,8 @@ const schemaOptions = Joi.object().keys({ cors: corsOptions, }), gracefulShutdown: Joi.number().min(0).integer(), + serverHeadersTimeout: Joi.number(), + serverKeepAliveTimeout: Joi.number(), // Additional from WebSocketServerOptions processSubscriptionsInterval: Joi.number(), webSocketsBasePath: Joi.string(), diff --git a/packages/cubejs-server/src/server.ts b/packages/cubejs-server/src/server.ts index 3c35a931212e7..064e5bbefa626 100644 --- a/packages/cubejs-server/src/server.ts +++ b/packages/cubejs-server/src/server.ts @@ -36,6 +36,8 @@ export interface CreateOptions extends CoreCreateOptions, WebSocketServerOptions webSockets?: boolean; http?: HttpOptions; gracefulShutdown?: number; + serverKeepAliveTimeout?: number; + serverHeadersTimeout?: number; } type RequireOne = { @@ -47,7 +49,7 @@ type RequireOne = { export class CubejsServer { protected readonly core: CubeCore; - protected readonly config: RequireOne; + protected readonly config: RequireOne; protected server: GracefulHttpServer | null = null; @@ -64,6 +66,8 @@ export class CubejsServer { sqlPort: config.sqlPort || getEnv('sqlPort'), pgSqlPort: config.pgSqlPort || getEnv('pgSqlPort'), gatewayPort: config.gatewayPort || getEnv('nativeApiGatewayPort'), + serverHeadersTimeout: config.serverHeadersTimeout ?? getEnv('serverHeadersTimeout'), + serverKeepAliveTimeout: config.serverKeepAliveTimeout ?? getEnv('serverKeepAliveTimeout'), http: { ...config.http, cors: { @@ -114,6 +118,14 @@ export class CubejsServer { await this.sqlServer.init(this.config); } + if (this.config.serverKeepAliveTimeout) { + this.server.keepAliveTimeout = this.config.serverKeepAliveTimeout; + } + + if (this.config.serverHeadersTimeout) { + this.server.headersTimeout = this.config.serverHeadersTimeout; + } + const PORT = getEnv('port'); await this.server.listen(PORT);