@@ -40,6 +40,7 @@ const {
4040 continueExpression,
4141 chunkExpression,
4242 kIncomingMessage,
43+ kRequestTimeout,
4344 HTTPParser,
4445 isLenient,
4546 _checkInvalidHeaderChar : checkInvalidHeaderChar ,
@@ -57,6 +58,7 @@ const {
5758} = require ( 'internal/async_hooks' ) ;
5859const { IncomingMessage } = require ( '_http_incoming' ) ;
5960const {
61+ ERR_HTTP_REQUEST_TIMEOUT ,
6062 ERR_HTTP_HEADERS_SENT ,
6163 ERR_HTTP_INVALID_STATUS_CODE ,
6264 ERR_INVALID_ARG_TYPE ,
@@ -72,6 +74,7 @@ const {
7274 DTRACE_HTTP_SERVER_RESPONSE
7375} = require ( 'internal/dtrace' ) ;
7476const { observerCounts, constants } = internalBinding ( 'performance' ) ;
77+ const { setTimeout, clearTimeout } = require ( 'timers' ) ;
7578const { NODE_PERFORMANCE_ENTRY_TYPE_HTTP } = constants ;
7679
7780const kServerResponse = Symbol ( 'ServerResponse' ) ;
@@ -143,6 +146,7 @@ const STATUS_CODES = {
143146 511 : 'Network Authentication Required' // RFC 6585 6
144147} ;
145148
149+ const kOnMessageBegin = HTTPParser . kOnMessageBegin | 0 ;
146150const kOnExecute = HTTPParser . kOnExecute | 0 ;
147151const kOnTimeout = HTTPParser . kOnTimeout | 0 ;
148152
@@ -360,6 +364,7 @@ function Server(options, requestListener) {
360364 this . keepAliveTimeout = 5000 ;
361365 this . maxHeadersCount = null ;
362366 this . headersTimeout = 60 * 1000 ; // 60 seconds
367+ this . requestTimeout = 0 ; // 120 seconds
363368}
364369ObjectSetPrototypeOf ( Server . prototype , net . Server . prototype ) ;
365370ObjectSetPrototypeOf ( Server , net . Server ) ;
@@ -481,6 +486,16 @@ function connectionListenerInternal(server, socket) {
481486 parser [ kOnTimeout ] =
482487 onParserTimeout . bind ( undefined , server , socket ) ;
483488
489+ // When receiving new requests on the same socket (pipelining or keep alive)
490+ // make sure the requestTimeout is active.
491+ parser [ kOnMessageBegin ] =
492+ setRequestTimeout . bind ( undefined , server , socket ) ;
493+
494+ // This protects from DOS attack where an attacker establish the connection
495+ // without sending any data on applications where server.timeout is left to
496+ // the default value of zero.
497+ setRequestTimeout ( server , socket ) ;
498+
484499 socket . _paused = false ;
485500}
486501
@@ -567,6 +582,11 @@ function socketOnData(server, socket, parser, state, d) {
567582 onParserExecuteCommon ( server , socket , parser , state , ret , d ) ;
568583}
569584
585+ function onRequestTimeout ( socket ) {
586+ socket [ kRequestTimeout ] = undefined ;
587+ socketOnError . call ( socket , new ERR_HTTP_REQUEST_TIMEOUT ( ) ) ;
588+ }
589+
570590function onParserExecute ( server , socket , parser , state , ret ) {
571591 // When underlying `net.Socket` instance is consumed - no
572592 // `data` events are emitted, and thus `socket.setTimeout` fires the
@@ -589,6 +609,10 @@ const badRequestResponse = Buffer.from(
589609 `HTTP/1.1 400 ${ STATUS_CODES [ 400 ] } ${ CRLF } ` +
590610 `Connection: close${ CRLF } ${ CRLF } ` , 'ascii'
591611) ;
612+ const requestTimeoutResponse = Buffer . from (
613+ `HTTP/1.1 408 ${ STATUS_CODES [ 408 ] } ${ CRLF } ` +
614+ `Connection: close${ CRLF } ${ CRLF } ` , 'ascii'
615+ ) ;
592616const requestHeaderFieldsTooLargeResponse = Buffer . from (
593617 `HTTP/1.1 431 ${ STATUS_CODES [ 431 ] } ${ CRLF } ` +
594618 `Connection: close${ CRLF } ${ CRLF } ` , 'ascii'
@@ -600,8 +624,20 @@ function socketOnError(e) {
600624
601625 if ( ! this . server . emit ( 'clientError' , e , this ) ) {
602626 if ( this . writable && this . bytesWritten === 0 ) {
603- const response = e . code === 'HPE_HEADER_OVERFLOW' ?
604- requestHeaderFieldsTooLargeResponse : badRequestResponse ;
627+ let response ;
628+
629+ switch ( e . code ) {
630+ case 'HPE_HEADER_OVERFLOW' :
631+ response = requestHeaderFieldsTooLargeResponse ;
632+ break ;
633+ case 'ERR_HTTP_REQUEST_TIMEOUT' :
634+ response = requestTimeoutResponse ;
635+ break ;
636+ default :
637+ response = badRequestResponse ;
638+ break ;
639+ }
640+
605641 this . write ( response ) ;
606642 }
607643 this . destroy ( e ) ;
@@ -641,11 +677,20 @@ function onParserExecuteCommon(server, socket, parser, state, ret, d) {
641677 const bodyHead = d . slice ( ret , d . length ) ;
642678
643679 socket . readableFlowing = null ;
680+
681+ // Clear the requestTimeout after upgrading the connection.
682+ clearRequestTimeout ( req ) ;
683+
644684 server . emit ( eventName , req , socket , bodyHead ) ;
645685 } else {
646686 // Got CONNECT method, but have no handler.
647687 socket . destroy ( ) ;
648688 }
689+ } else {
690+ // When receiving new requests on the same socket (pipelining or keep alive)
691+ // make sure the requestTimeout is active.
692+ parser [ kOnMessageBegin ] =
693+ setRequestTimeout . bind ( undefined , server , socket ) ;
649694 }
650695
651696 if ( socket . _paused && socket . parser ) {
@@ -671,6 +716,32 @@ function clearIncoming(req) {
671716 }
672717}
673718
719+ function setRequestTimeout ( server , socket ) {
720+ // Set the request timeout handler.
721+ if (
722+ ! socket [ kRequestTimeout ] &&
723+ server . requestTimeout && server . requestTimeout > 0
724+ ) {
725+ debug ( 'requestTimeout timer set' ) ;
726+ socket [ kRequestTimeout ] =
727+ setTimeout ( onRequestTimeout , server . requestTimeout , socket ) . unref ( ) ;
728+ }
729+ }
730+
731+ function clearRequestTimeout ( req ) {
732+ if ( ! req ) {
733+ req = this ;
734+ }
735+
736+ if ( ! req [ kRequestTimeout ] ) {
737+ return ;
738+ }
739+
740+ debug ( 'requestTimeout timer cleared' ) ;
741+ clearTimeout ( req [ kRequestTimeout ] ) ;
742+ req [ kRequestTimeout ] = undefined ;
743+ }
744+
674745function resOnFinish ( req , res , socket , state , server ) {
675746 // Usually the first incoming element should be our request. it may
676747 // be that in the case abortIncoming() was called that the incoming
@@ -685,6 +756,14 @@ function resOnFinish(req, res, socket, state, server) {
685756 if ( ! req . _consuming && ! req . _readableState . resumeScheduled )
686757 req . _dump ( ) ;
687758
759+ // Make sure the requestTimeout is cleared before finishing.
760+ // This might occur if the application has sent a response
761+ // without consuming the request body, which would have alredy
762+ // cleared the timer.
763+ // clearRequestTimeout can be executed even if the timer is not active,
764+ // so this is safe.
765+ clearRequestTimeout ( req ) ;
766+
688767 res . detachSocket ( socket ) ;
689768 clearIncoming ( req ) ;
690769 process . nextTick ( emitCloseNT , res ) ;
@@ -779,6 +858,8 @@ function parserOnIncoming(server, socket, state, req, keepAlive) {
779858 res . end ( ) ;
780859 }
781860 } else {
861+ req . on ( 'end' , clearRequestTimeout ) ;
862+
782863 server . emit ( 'request' , req , res ) ;
783864 }
784865 return 0 ; // No special treatment.
0 commit comments