Skip to content

Commit a8e3f2b

Browse files
authored
feat: allow configuring Node.js HTTP server
1 parent d23061c commit a8e3f2b

File tree

4 files changed

+62
-1
lines changed

4 files changed

+62
-1
lines changed

src/server/main.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@ import { finalHandler } from './factories/final_handler.js'
3737
import { writeResponse } from './factories/write_response.js'
3838
import { asyncLocalStorage } from '../http_context/local_storage.js'
3939
import { middlewareHandler } from './factories/middleware_handler.js'
40+
import lodash from '@poppinss/utils/lodash'
41+
import { NodeConfig } from '../types/node.js'
4042

4143
/**
4244
* The HTTP server implementation to handle incoming requests and respond using the
@@ -294,6 +296,18 @@ export class Server {
294296
* Set the HTTP server instance used to listen for requests.
295297
*/
296298
setNodeServer(server: HttpServer | HttpsServer) {
299+
const nodeServerOptions: (keyof NodeConfig)[] = [
300+
'keepAliveTimeout',
301+
'headersTimeout',
302+
'requestTimeout',
303+
'timeout',
304+
]
305+
306+
Object.assign<HttpServer | HttpsServer, Partial<NodeConfig>>(
307+
server,
308+
lodash.pick<NodeConfig>(this.#config, nodeServerOptions)
309+
)
310+
297311
this.#nodeHttpServer = server
298312
}
299313

src/types/node.ts

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
export type NodeConfig = {
2+
/**
3+
* The number of milliseconds of inactivity a server needs to wait for additional incoming data, after
4+
* it has finished writing the last response, before a socket will be destroyed
5+
* @default 5000
6+
*/
7+
keepAliveTimeout?: number
8+
9+
/**
10+
* Limit the amount of time the parser will wait to receive the complete HTTP headers
11+
* @default 60000
12+
*/
13+
headersTimeout?: number
14+
15+
/**
16+
* Sets the timeout value in milliseconds for receiving the entire request from the client
17+
* @default 300000
18+
*/
19+
requestTimeout?: number
20+
21+
/**
22+
* The number of milliseconds of inactivity before a socket is presumed to have timed out
23+
* @default 0
24+
*/
25+
timeout?: number
26+
}

src/types/server.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import type { QSParserConfig } from './qs.js'
1414
import type { RequestConfig } from './request.js'
1515
import type { ResponseConfig } from './response.js'
1616
import type { HttpContext } from '../http_context/main.js'
17+
import type { NodeConfig } from './node.js'
1718

1819
/**
1920
* Normalized HTTP error used by the exception
@@ -83,7 +84,8 @@ export type ErrorHandlerAsAClass = Constructor<ServerErrorHandler>
8384
* Config accepted by the HTTP server
8485
*/
8586
export type ServerConfig = RequestConfig &
86-
ResponseConfig & {
87+
ResponseConfig &
88+
NodeConfig & {
8789
/**
8890
* Whether or not to create an async local storage store for
8991
* the HTTP context.

tests/server.spec.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,25 @@ test.group('Server', () => {
6464

6565
await supertest(httpServer).get('/').expect(200)
6666
}).waitForDone()
67+
68+
test('pass config to node http server', ({ assert }) => {
69+
const keepAliveTimeout = 61000
70+
const app = new AppFactory().create(BASE_URL, () => {})
71+
const server = new ServerFactory()
72+
.merge({
73+
app,
74+
config: {
75+
keepAliveTimeout,
76+
},
77+
})
78+
.create()
79+
server.use([])
80+
81+
const httpServer = createServer(() => {})
82+
server.setNodeServer(httpServer)
83+
84+
assert.strictEqual(httpServer.keepAliveTimeout, keepAliveTimeout)
85+
})
6786
})
6887

6988
test.group('Server | Response handling', () => {

0 commit comments

Comments
 (0)