@@ -37,7 +37,7 @@ const {
37
37
_checkInvalidHeaderChar : checkInvalidHeaderChar
38
38
} = require ( '_http_common' ) ;
39
39
const { OutgoingMessage } = require ( '_http_outgoing' ) ;
40
- const { outHeadersKey, ondrain } = require ( 'internal/http' ) ;
40
+ const { outHeadersKey, ondrain, nowDate } = require ( 'internal/http' ) ;
41
41
const {
42
42
defaultTriggerAsyncIdScope,
43
43
getOrSetAsyncId
@@ -303,6 +303,7 @@ function Server(options, requestListener) {
303
303
this . keepAliveTimeout = 5000 ;
304
304
this . _pendingResponseData = 0 ;
305
305
this . maxHeadersCount = null ;
306
+ this . headersTimeout = 40 * 1000 ; // 40 seconds
306
307
}
307
308
util . inherits ( Server , net . Server ) ;
308
309
@@ -341,6 +342,9 @@ function connectionListenerInternal(server, socket) {
341
342
var parser = parsers . alloc ( ) ;
342
343
parser . reinitialize ( HTTPParser . REQUEST ) ;
343
344
parser . socket = socket ;
345
+
346
+ // We are starting to wait for our headers.
347
+ parser . parsingHeadersStart = nowDate ( ) ;
344
348
socket . parser = parser ;
345
349
346
350
// Propagate headers limit from server instance to parser
@@ -478,7 +482,20 @@ function socketOnData(server, socket, parser, state, d) {
478
482
479
483
function onParserExecute ( server , socket , parser , state , ret ) {
480
484
socket . _unrefTimer ( ) ;
485
+ const start = parser . parsingHeadersStart ;
481
486
debug ( 'SERVER socketOnParserExecute %d' , ret ) ;
487
+
488
+ // If we have not parsed the headers, destroy the socket
489
+ // after server.headersTimeout to protect from DoS attacks.
490
+ // start === 0 means that we have parsed headers.
491
+ if ( start !== 0 && nowDate ( ) - start > server . headersTimeout ) {
492
+ const serverTimeout = server . emit ( 'timeout' , socket ) ;
493
+
494
+ if ( ! serverTimeout )
495
+ socket . destroy ( ) ;
496
+ return ;
497
+ }
498
+
482
499
onParserExecuteCommon ( server , socket , parser , state , ret , undefined ) ;
483
500
}
484
501
@@ -589,6 +606,9 @@ function resOnFinish(req, res, socket, state, server) {
589
606
function parserOnIncoming ( server , socket , state , req , keepAlive ) {
590
607
resetSocketTimeout ( server , socket , state ) ;
591
608
609
+ // Set to zero to communicate that we have finished parsing.
610
+ socket . parser . parsingHeadersStart = 0 ;
611
+
592
612
if ( req . upgrade ) {
593
613
req . upgrade = req . method === 'CONNECT' ||
594
614
server . listenerCount ( 'upgrade' ) > 0 ;
0 commit comments