@@ -37,7 +37,7 @@ const {
3737 _checkInvalidHeaderChar : checkInvalidHeaderChar
3838} = require ( '_http_common' ) ;
3939const { OutgoingMessage } = require ( '_http_outgoing' ) ;
40- const { outHeadersKey, ondrain } = require ( 'internal/http' ) ;
40+ const { outHeadersKey, ondrain, nowDate } = require ( 'internal/http' ) ;
4141const {
4242 defaultTriggerAsyncIdScope,
4343 getOrSetAsyncId
@@ -303,6 +303,7 @@ function Server(options, requestListener) {
303303 this . keepAliveTimeout = 5000 ;
304304 this . _pendingResponseData = 0 ;
305305 this . maxHeadersCount = null ;
306+ this . headersTimeout = 40 * 1000 ; // 40 seconds
306307}
307308util . inherits ( Server , net . Server ) ;
308309
@@ -341,6 +342,9 @@ function connectionListenerInternal(server, socket) {
341342 var parser = parsers . alloc ( ) ;
342343 parser . reinitialize ( HTTPParser . REQUEST ) ;
343344 parser . socket = socket ;
345+
346+ // We are starting to wait for our headers.
347+ parser . parsingHeadersStart = nowDate ( ) ;
344348 socket . parser = parser ;
345349
346350 // Propagate headers limit from server instance to parser
@@ -478,7 +482,20 @@ function socketOnData(server, socket, parser, state, d) {
478482
479483function onParserExecute ( server , socket , parser , state , ret ) {
480484 socket . _unrefTimer ( ) ;
485+ const start = parser . parsingHeadersStart ;
481486 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+
482499 onParserExecuteCommon ( server , socket , parser , state , ret , undefined ) ;
483500}
484501
@@ -589,6 +606,9 @@ function resOnFinish(req, res, socket, state, server) {
589606function parserOnIncoming ( server , socket , state , req , keepAlive ) {
590607 resetSocketTimeout ( server , socket , state ) ;
591608
609+ // Set to zero to communicate that we have finished parsing.
610+ socket . parser . parsingHeadersStart = 0 ;
611+
592612 if ( req . upgrade ) {
593613 req . upgrade = req . method === 'CONNECT' ||
594614 server . listenerCount ( 'upgrade' ) > 0 ;
0 commit comments