@@ -40,6 +40,7 @@ const {
4040 continueExpression,
4141 chunkExpression,
4242 kIncomingMessage,
43+ kRequestTimeout,
4344 HTTPParser,
4445 isLenient,
4546 _checkInvalidHeaderChar : checkInvalidHeaderChar ,
@@ -61,6 +62,7 @@ const {
6162 codes
6263} = require ( 'internal/errors' ) ;
6364const {
65+ ERR_HTTP_REQUEST_TIMEOUT ,
6466 ERR_HTTP_HEADERS_SENT ,
6567 ERR_HTTP_INVALID_STATUS_CODE ,
6668 ERR_HTTP_SOCKET_ENCODING ,
@@ -77,6 +79,7 @@ const {
7779 DTRACE_HTTP_SERVER_RESPONSE
7880} = require ( 'internal/dtrace' ) ;
7981const { observerCounts, constants } = internalBinding ( 'performance' ) ;
82+ const { setTimeout, clearTimeout } = require ( 'timers' ) ;
8083const { NODE_PERFORMANCE_ENTRY_TYPE_HTTP } = constants ;
8184
8285const kServerResponse = Symbol ( 'ServerResponse' ) ;
@@ -148,6 +151,7 @@ const STATUS_CODES = {
148151 511 : 'Network Authentication Required' // RFC 6585 6
149152} ;
150153
154+ const kOnMessageBegin = HTTPParser . kOnMessageBegin | 0 ;
151155const kOnExecute = HTTPParser . kOnExecute | 0 ;
152156const kOnTimeout = HTTPParser . kOnTimeout | 0 ;
153157
@@ -369,6 +373,7 @@ function Server(options, requestListener) {
369373 this . keepAliveTimeout = 5000 ;
370374 this . maxHeadersCount = null ;
371375 this . headersTimeout = 60 * 1000 ; // 60 seconds
376+ this . requestTimeout = 0 ; // 120 seconds
372377}
373378ObjectSetPrototypeOf ( Server . prototype , net . Server . prototype ) ;
374379ObjectSetPrototypeOf ( Server , net . Server ) ;
@@ -491,6 +496,16 @@ function connectionListenerInternal(server, socket) {
491496 parser [ kOnTimeout ] =
492497 onParserTimeout . bind ( undefined , server , socket ) ;
493498
499+ // When receiving new requests on the same socket (pipelining or keep alive)
500+ // make sure the requestTimeout is active.
501+ parser [ kOnMessageBegin ] =
502+ setRequestTimeout . bind ( undefined , server , socket ) ;
503+
504+ // This protects from DOS attack where an attacker establish the connection
505+ // without sending any data on applications where server.timeout is left to
506+ // the default value of zero.
507+ setRequestTimeout ( server , socket ) ;
508+
494509 socket . _paused = false ;
495510}
496511
@@ -586,6 +601,11 @@ function socketOnData(server, socket, parser, state, d) {
586601 onParserExecuteCommon ( server , socket , parser , state , ret , d ) ;
587602}
588603
604+ function onRequestTimeout ( socket ) {
605+ socket [ kRequestTimeout ] = undefined ;
606+ socketOnError . call ( socket , new ERR_HTTP_REQUEST_TIMEOUT ( ) ) ;
607+ }
608+
589609function onParserExecute ( server , socket , parser , state , ret ) {
590610 // When underlying `net.Socket` instance is consumed - no
591611 // `data` events are emitted, and thus `socket.setTimeout` fires the
@@ -608,6 +628,10 @@ const badRequestResponse = Buffer.from(
608628 `HTTP/1.1 400 ${ STATUS_CODES [ 400 ] } ${ CRLF } ` +
609629 `Connection: close${ CRLF } ${ CRLF } ` , 'ascii'
610630) ;
631+ const requestTimeoutResponse = Buffer . from (
632+ `HTTP/1.1 408 ${ STATUS_CODES [ 408 ] } ${ CRLF } ` +
633+ `Connection: close${ CRLF } ${ CRLF } ` , 'ascii'
634+ ) ;
611635const requestHeaderFieldsTooLargeResponse = Buffer . from (
612636 `HTTP/1.1 431 ${ STATUS_CODES [ 431 ] } ${ CRLF } ` +
613637 `Connection: close${ CRLF } ${ CRLF } ` , 'ascii'
@@ -619,8 +643,20 @@ function socketOnError(e) {
619643
620644 if ( ! this . server . emit ( 'clientError' , e , this ) ) {
621645 if ( this . writable && this . bytesWritten === 0 ) {
622- const response = e . code === 'HPE_HEADER_OVERFLOW' ?
623- requestHeaderFieldsTooLargeResponse : badRequestResponse ;
646+ let response ;
647+
648+ switch ( e . code ) {
649+ case 'HPE_HEADER_OVERFLOW' :
650+ response = requestHeaderFieldsTooLargeResponse ;
651+ break ;
652+ case 'ERR_HTTP_REQUEST_TIMEOUT' :
653+ response = requestTimeoutResponse ;
654+ break ;
655+ default :
656+ response = badRequestResponse ;
657+ break ;
658+ }
659+
624660 this . write ( response ) ;
625661 }
626662 this . destroy ( e ) ;
@@ -660,11 +696,20 @@ function onParserExecuteCommon(server, socket, parser, state, ret, d) {
660696 const bodyHead = d . slice ( ret , d . length ) ;
661697
662698 socket . readableFlowing = null ;
699+
700+ // Clear the requestTimeout after upgrading the connection.
701+ clearRequestTimeout ( req ) ;
702+
663703 server . emit ( eventName , req , socket , bodyHead ) ;
664704 } else {
665705 // Got CONNECT method, but have no handler.
666706 socket . destroy ( ) ;
667707 }
708+ } else {
709+ // When receiving new requests on the same socket (pipelining or keep alive)
710+ // make sure the requestTimeout is active.
711+ parser [ kOnMessageBegin ] =
712+ setRequestTimeout . bind ( undefined , server , socket ) ;
668713 }
669714
670715 if ( socket . _paused && socket . parser ) {
@@ -692,6 +737,32 @@ function clearIncoming(req) {
692737 }
693738}
694739
740+ function setRequestTimeout ( server , socket ) {
741+ // Set the request timeout handler.
742+ if (
743+ ! socket [ kRequestTimeout ] &&
744+ server . requestTimeout && server . requestTimeout > 0
745+ ) {
746+ debug ( 'requestTimeout timer set' ) ;
747+ socket [ kRequestTimeout ] =
748+ setTimeout ( onRequestTimeout , server . requestTimeout , socket ) . unref ( ) ;
749+ }
750+ }
751+
752+ function clearRequestTimeout ( req ) {
753+ if ( ! req ) {
754+ req = this ;
755+ }
756+
757+ if ( ! req [ kRequestTimeout ] ) {
758+ return ;
759+ }
760+
761+ debug ( 'requestTimeout timer cleared' ) ;
762+ clearTimeout ( req [ kRequestTimeout ] ) ;
763+ req [ kRequestTimeout ] = undefined ;
764+ }
765+
695766function resOnFinish ( req , res , socket , state , server ) {
696767 // Usually the first incoming element should be our request. it may
697768 // be that in the case abortIncoming() was called that the incoming
@@ -706,6 +777,14 @@ function resOnFinish(req, res, socket, state, server) {
706777 if ( ! req . _consuming && ! req . _readableState . resumeScheduled )
707778 req . _dump ( ) ;
708779
780+ // Make sure the requestTimeout is cleared before finishing.
781+ // This might occur if the application has sent a response
782+ // without consuming the request body, which would have alredy
783+ // cleared the timer.
784+ // clearRequestTimeout can be executed even if the timer is not active,
785+ // so this is safe.
786+ clearRequestTimeout ( req ) ;
787+
709788 res . detachSocket ( socket ) ;
710789 clearIncoming ( req ) ;
711790 process . nextTick ( emitCloseNT , res ) ;
@@ -802,6 +881,8 @@ function parserOnIncoming(server, socket, state, req, keepAlive) {
802881 res . end ( ) ;
803882 }
804883 } else {
884+ req . on ( 'end' , clearRequestTimeout ) ;
885+
805886 server . emit ( 'request' , req , res ) ;
806887 }
807888 return 0 ; // No special treatment.
0 commit comments