|
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 | varparser=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 | functiononParserExecute(server,socket,parser,state,ret){ |
480 | 484 | socket._unrefTimer(); |
| 485 | +conststart=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 | +constserverTimeout=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 | functionparserOnIncoming(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