1

I wish to put a timeout on my responses. I tried the following:

var timeout = express.timeout // express v3 and below

app.use(timeout(120000));
app.use(haltOnTimedout);

function haltOnTimedout(req, res, next){
  if (!req.timedout) next();
}

The problem is that there is some requests which are takes more then 120000 ms (download of big files), and it fine. I want to timeout only requests that no information was transferred on the stream between my application (the server) and the client.

My code above closes all the connection which takes more then 120000 ms.

Dhanuka
  • 2,826
  • 5
  • 27
  • 38
MIDE11
  • 3,140
  • 7
  • 31
  • 53

2 Answers2

3

You can set timeout on the message itself (it will be called if no data is transfered)

req.connection.setTimeout(120000, function () { res.status(500).end(); });

https://nodejs.org/api/http.html#http_message_settimeout_msecs_callback

EDIT:

I've added the 500 status code

B3rn475
  • 1,057
  • 5
  • 14
  • On closer reflection of the question, this is the correct answer. If you remove your use of the `timeout()` middleware and set a connection timeout on the request instead then the connection will only be dropped if inactive for too long. You could even wrap this in a pass-through route so all requests have the same connection timeout. – seanhodges May 28 '15 at 08:56
  • It seems that this is also close connection that the response takes more then X ms, and not takes into consideration the inactive propety. In addition, it gives the following error:`Object # has no method 'end'` – MIDE11 May 29 '15 at 10:39
  • This is how I defined it:` app.post("/getDocument", function(req, res) { try { req.connection.setTimeout(200, function () { logger.info("Connection time out"); req.end(); });` – MIDE11 May 29 '15 at 10:41
  • Sorry there was a typo. it was res.end(); not req.end(); – B3rn475 May 29 '15 at 20:55
  • 1
    Thanks, It seems the correct answer. But another issue has raised: When it time out, the function is still continue to execute, and it fails on: `Error: Can't set headers after they are sent.` How can I avoid it? – MIDE11 May 31 '15 at 07:26
  • I notice to another issue: When I put timeout of `120000`, the request is closed after 170000 ms (with 500 status code). But when I get rid of this line, the file downloading is completed after 642381 sc. It doesn't make sense that no data is transfer for 120000 ms, and then continue, right? What is the problem here? – MIDE11 May 31 '15 at 08:06
  • It depends on the status of the request. If you have started writing on it (even with headers) you cannot change the status code. This is really application specific. – B3rn475 Jun 01 '15 at 08:24
0

just updated your original example for what works for me.

app.use( timeout( 120000 ) );
app.use( haltOnTimedout );

let haltOnTimedout = ( err, req, res, next ) => {

    if ( !req.timedout ) next();

    // handle timeout / kill process 

};

Basically we tapping into the express error handling : https://expressjs.com/en/guide/error-handling.html