From f57d1061a5c71335ded6218c724c2ab2aa1be759 Mon Sep 17 00:00:00 2001 From: Martin Vanco Date: Wed, 5 Feb 2025 12:00:36 +0100 Subject: [PATCH 1/4] feat: configure node http server timeouts --- src/server/main.ts | 25 +++++++++++++++++++++++++ src/types/server.ts | 30 ++++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) diff --git a/src/server/main.ts b/src/server/main.ts index 8afc49c..11f237c 100644 --- a/src/server/main.ts +++ b/src/server/main.ts @@ -294,6 +294,31 @@ export class Server { * Set the HTTP server instance used to listen for requests. */ setNodeServer(server: HttpServer | HttpsServer) { + if (this.#config.nodeHttpServer) { + const { + keepAliveTimeout, + headersTimeout, + requestTimeout, + timeout, + } = this.#config.nodeHttpServer + + if (typeof keepAliveTimeout === 'number') { + server.keepAliveTimeout = keepAliveTimeout + } + + if (typeof headersTimeout === 'number') { + server.headersTimeout = headersTimeout + } + + if (typeof requestTimeout === 'number') { + server.requestTimeout = requestTimeout + } + + if (typeof timeout === 'number') { + server.timeout = timeout + } + } + this.#nodeHttpServer = server } diff --git a/src/types/server.ts b/src/types/server.ts index ad036f0..87e2cbe 100644 --- a/src/types/server.ts +++ b/src/types/server.ts @@ -96,4 +96,34 @@ export type ServerConfig = RequestConfig & * Config for query string parser */ qs: QSParserConfig + + /** + * Node.js HTTP server options + */ + nodeHttpServer?: { + /** + * 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 + * @default 5000 + */ + keepAliveTimeout?: number + + /** + * Limit the amount of time the parser will wait to receive the complete HTTP headers + * @default 60000 + */ + headersTimeout?: number + + /** + * Sets the timeout value in milliseconds for receiving the entire request from the client + * @default 300000 + */ + requestTimeout?: number + + /** + * The number of milliseconds of inactivity before a socket is presumed to have timed out + * @default 0 + */ + timeout?: number + } } From 3acf16386a5d41df1c357b430ae62194683c05dd Mon Sep 17 00:00:00 2001 From: adamcikado Date: Thu, 20 Feb 2025 10:34:48 +0000 Subject: [PATCH 2/4] refactor: node http server types --- src/server/main.ts | 28 +++++----------------------- src/types/node.ts | 26 ++++++++++++++++++++++++++ src/types/server.ts | 28 ++-------------------------- tests/server.spec.ts | 19 +++++++++++++++++++ 4 files changed, 52 insertions(+), 49 deletions(-) create mode 100644 src/types/node.ts diff --git a/src/server/main.ts b/src/server/main.ts index 11f237c..13ad644 100644 --- a/src/server/main.ts +++ b/src/server/main.ts @@ -294,29 +294,11 @@ export class Server { * Set the HTTP server instance used to listen for requests. */ setNodeServer(server: HttpServer | HttpsServer) { - if (this.#config.nodeHttpServer) { - const { - keepAliveTimeout, - headersTimeout, - requestTimeout, - timeout, - } = this.#config.nodeHttpServer - - if (typeof keepAliveTimeout === 'number') { - server.keepAliveTimeout = keepAliveTimeout - } - - if (typeof headersTimeout === 'number') { - server.headersTimeout = headersTimeout - } - - if (typeof requestTimeout === 'number') { - server.requestTimeout = requestTimeout - } - - if (typeof timeout === 'number') { - server.timeout = timeout - } + if (this.#config.node) { + Object.assign>( + server, + this.#config.node + ) } this.#nodeHttpServer = server diff --git a/src/types/node.ts b/src/types/node.ts new file mode 100644 index 0000000..33471a7 --- /dev/null +++ b/src/types/node.ts @@ -0,0 +1,26 @@ +export type NodeConfig = { + /** + * 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 + * @default 5000 + */ + keepAliveTimeout?: number + + /** + * Limit the amount of time the parser will wait to receive the complete HTTP headers + * @default 60000 + */ + headersTimeout?: number + + /** + * Sets the timeout value in milliseconds for receiving the entire request from the client + * @default 300000 + */ + requestTimeout?: number + + /** + * The number of milliseconds of inactivity before a socket is presumed to have timed out + * @default 0 + */ + timeout?: number +} diff --git a/src/types/server.ts b/src/types/server.ts index 87e2cbe..4161a81 100644 --- a/src/types/server.ts +++ b/src/types/server.ts @@ -14,6 +14,7 @@ import type { QSParserConfig } from './qs.js' import type { RequestConfig } from './request.js' import type { ResponseConfig } from './response.js' import type { HttpContext } from '../http_context/main.js' +import type { NodeConfig } from './node.js' /** * Normalized HTTP error used by the exception @@ -100,30 +101,5 @@ export type ServerConfig = RequestConfig & /** * Node.js HTTP server options */ - nodeHttpServer?: { - /** - * 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 - * @default 5000 - */ - keepAliveTimeout?: number - - /** - * Limit the amount of time the parser will wait to receive the complete HTTP headers - * @default 60000 - */ - headersTimeout?: number - - /** - * Sets the timeout value in milliseconds for receiving the entire request from the client - * @default 300000 - */ - requestTimeout?: number - - /** - * The number of milliseconds of inactivity before a socket is presumed to have timed out - * @default 0 - */ - timeout?: number - } + node?: NodeConfig } diff --git a/tests/server.spec.ts b/tests/server.spec.ts index 8c4f5af..5ce4810 100644 --- a/tests/server.spec.ts +++ b/tests/server.spec.ts @@ -64,6 +64,25 @@ test.group('Server', () => { await supertest(httpServer).get('/').expect(200) }).waitForDone() + + test('pass config to node http server', ({ assert }) => { + const keepAliveTimeout = 61000 + const app = new AppFactory().create(BASE_URL, () => {}) + const server = new ServerFactory() + .merge({ + app, + config: { + node: { keepAliveTimeout }, + }, + }) + .create() + server.use([]) + + const httpServer = createServer(() => {}) + server.setNodeServer(httpServer) + + assert.strictEqual(httpServer.keepAliveTimeout, keepAliveTimeout) + }) }) test.group('Server | Response handling', () => { From 57721fc8722fc030149be294b6d8513fce2fdfd0 Mon Sep 17 00:00:00 2001 From: Martin Vanco Date: Mon, 24 Feb 2025 11:17:09 +0100 Subject: [PATCH 3/4] fix: node server options --- src/server/main.ts | 19 +++++++++++++------ src/types/server.ts | 8 ++------ 2 files changed, 15 insertions(+), 12 deletions(-) diff --git a/src/server/main.ts b/src/server/main.ts index 13ad644..ee7e369 100644 --- a/src/server/main.ts +++ b/src/server/main.ts @@ -37,6 +37,8 @@ import { finalHandler } from './factories/final_handler.js' import { writeResponse } from './factories/write_response.js' import { asyncLocalStorage } from '../http_context/local_storage.js' import { middlewareHandler } from './factories/middleware_handler.js' +import lodash from '@poppinss/utils/lodash' +import { NodeConfig } from '../types/node.js' /** * The HTTP server implementation to handle incoming requests and respond using the @@ -294,12 +296,17 @@ export class Server { * Set the HTTP server instance used to listen for requests. */ setNodeServer(server: HttpServer | HttpsServer) { - if (this.#config.node) { - Object.assign>( - server, - this.#config.node - ) - } + const nodeServerOptions: (keyof NodeConfig)[] = [ + 'keepAliveTimeout', + 'headersTimeout', + 'requestTimeout', + 'timeout', + ] + + Object.assign>( + server, + lodash.pick(this.#config, nodeServerOptions) + ) this.#nodeHttpServer = server } diff --git a/src/types/server.ts b/src/types/server.ts index 4161a81..b750f7a 100644 --- a/src/types/server.ts +++ b/src/types/server.ts @@ -84,7 +84,8 @@ export type ErrorHandlerAsAClass = Constructor * Config accepted by the HTTP server */ export type ServerConfig = RequestConfig & - ResponseConfig & { + ResponseConfig & + NodeConfig & { /** * Whether or not to create an async local storage store for * the HTTP context. @@ -97,9 +98,4 @@ export type ServerConfig = RequestConfig & * Config for query string parser */ qs: QSParserConfig - - /** - * Node.js HTTP server options - */ - node?: NodeConfig } From c05779f938adebd245ce8d57c126a52982f762f5 Mon Sep 17 00:00:00 2001 From: Martin Vanco Date: Tue, 25 Feb 2025 08:53:49 +0100 Subject: [PATCH 4/4] fix: test --- tests/server.spec.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/server.spec.ts b/tests/server.spec.ts index 5ce4810..d4d8611 100644 --- a/tests/server.spec.ts +++ b/tests/server.spec.ts @@ -72,7 +72,7 @@ test.group('Server', () => { .merge({ app, config: { - node: { keepAliveTimeout }, + keepAliveTimeout, }, }) .create()