Commit 9ff67fb1 authored by Bastien ROUCARIÈS's avatar Bastien ROUCARIÈS

New upstream version 1.9.0

parent 64808f9c
coverage
node_modules
{
"extends": "standard"
}
# Compiled source #
###################
*.com
*.class
*.dll
*.exe
*.o
*.so
# Packages #
############
# it's better to unpack these files and commit the raw source
# git has its own built in compression methods
*.7z
*.dmg
*.gz
*.iso
*.jar
*.rar
*.tar
*.zip
# Logs and databases #
######################
*.log
*.sql
*.sqlite
# OS generated files #
######################
.DS_Store*
ehthumbs.db
Icon?
Thumbs.db
# Node.js #
###########
lib-cov
*.seed
*.log
*.csv
*.dat
*.out
*.pid
*.gz
pids
logs
results
coverage
node_modules
npm-debug.log
# Git #
#######
*.orig
*.BASE.*
*.BACKUP.*
*.LOCAL.*
*.REMOTE.*
# Components #
##############
/build
/components
......@@ -2,10 +2,29 @@ language: node_js
node_js:
- "0.8"
- "0.10"
- "0.11"
matrix:
allow_failures:
- node_js: "0.11"
fast_finish: true
script: "npm run-script test-travis"
after_script: "npm install coveralls@2.10.0 && cat ./coverage/lcov.info | coveralls"
- "0.12"
- "1.8"
- "2.5"
- "3.3"
- "4.8"
- "5.12"
- "6.10"
- "7.10"
sudo: false
cache:
directories:
- node_modules
before_install:
# Setup Node.js version-specific dependencies
- "test $TRAVIS_NODE_VERSION != '0.8' || npm rm --save-dev istanbul"
- "test $(echo $TRAVIS_NODE_VERSION | cut -d. -f1) -ge 4 || npm rm --save-dev $(grep -E '\"eslint\\S*\"' package.json | cut -d'\"' -f2)"
# Update Node.js modules
- "test ! -d node_modules || npm prune"
- "test ! -d node_modules || npm rebuild"
script:
# Run test script, depending on istanbul install
- "test ! -z $(npm -ps ls istanbul) || npm test"
- "test -z $(npm -ps ls istanbul) || npm run-script test-travis"
- "test -z $(npm -ps ls eslint ) || npm run-script lint"
after_script:
- "test -e ./coverage/lcov.info && npm install coveralls@2 && cat ./coverage/lcov.info | coveralls"
1.9.0 / 2017-05-16
==================
* deps: http-errors@~1.6.1
- Make `message` property enumerable for `HttpError`s
- deps: setprototypeof@1.0.3
* deps: ms@2.0.0
1.8.0 / 2016-11-21
==================
* Remove un-used debug dependency
* deps: http-errors@~1.5.1
- Add `HttpError` export, for `err instanceof createError.HttpError`
- Use `setprototypeof` module to replace `__proto__` setting
- deps: inherits@2.0.3
- deps: statuses@'>= 1.3.1 < 2'
- perf: enable strict mode
* deps: ms@0.7.2
* deps: on-headers@~1.0.1
- perf: enable strict mode
1.7.0 / 2015-08-23
==================
* Use `on-finished` instead of override socket destroy
- Addresses memory leaking on keep alive connections
- Ensures timers always get cleaned up
* perf: enable strict mode
* perf: remove argument reassignment
* perf: use standard option existence check
1.6.2 / 2015-05-11
==================
* deps: debug@~2.2.0
- deps: ms@0.7.1
* deps: ms@0.7.1
- Prevent extraordinarily long inputs
1.6.1 / 2015-03-14
==================
* deps: debug@~2.1.3
- Fix high intensity foreground color for bold
- deps: ms@0.7.0
1.6.0 / 2015-02-15
==================
* deps: http-errors@~1.3.1
- Construct errors using defined constructors from `createError`
- Fix error names that are not identifiers
- Set a meaningful `name` property on constructed errors
1.5.0 / 2014-12-30
==================
* deps: debug@~2.1.1
* deps: http-errors@~1.2.8
- Fix stack trace from exported function
* deps: ms@0.7.0
- Add `milliseconds`
- Add `msecs`
- Add `secs`
- Add `mins`
- Add `hrs`
- Add `yrs`
1.4.0 / 2014-10-16
==================
* Create errors with `http-errors`
* deps: debug@~2.1.0
- Implement `DEBUG_FD` env variable support
1.3.0 / 2014-09-03
==================
......
(The MIT License)
Copyright (c) 2014 Jonathan Ong <me@jongleberry.com>
Copyright (c) 2014 Douglas Christopher Wilson <doug@somethingdoug.com>
Copyright (c) 2014-2015 Douglas Christopher Wilson <doug@somethingdoug.com>
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
......
......@@ -6,31 +6,55 @@
[![Test Coverage][coveralls-image]][coveralls-url]
[![Gratipay][gratipay-image]][gratipay-url]
Times out the request in `ms`, defaulting to `5000`.
Times out a request in the Connect/Express application framework.
## Install
This is a [Node.js](https://nodejs.org/en/) module available through the
[npm registry](https://www.npmjs.com/). Installation is done using the
[`npm install` command](https://docs.npmjs.com/getting-started/installing-npm-packages-locally):
```sh
$ npm install connect-timeout
```
## API
**NOTE** This module is not recommend as a "top-level" middleware (i.e. `app.use(timeout('5s'))`) unless
you take precautions to halt your own middleware processing. See [as top-level middleware](#as-top-level-middleware)
**NOTE** This module is not recommend as a "top-level" middleware (i.e.
`app.use(timeout('5s'))`) unless you take precautions to halt your own
middleware processing. See [as top-level middleware](#as-top-level-middleware)
for how to use as a top-level middleware.
### timeout(time, options)
While the library will emit a 'timeout' event when requests exceed the given
timeout, node will continue processing the slow request until it terminates.
Slow requests will continue to use CPU and memory, even if you are returning
a HTTP response in the timeout callback. For better control over CPU/memory,
you may need to find the events that are taking a long time (3rd party HTTP
requests, disk I/O, database calls) and find a way to cancel them, and/or
close the attached sockets.
### timeout(time, [options])
Returns middleware that times out in `time` milliseconds. `time` can also
be a string accepted by the [ms](https://www.npmjs.org/package/ms#readme)
module. On timeout, `req` will emit `"timeout"`.
#### Options
Returns middleware that times out in `time` milliseconds. `time` can also be a string accepted by the [ms](https://www.npmjs.org/package/ms#readme) module. On timeout, `req` will emit `"timeout"`.
The `timeout` function takes an optional `options` object that may contain
any of the following keys:
#### options
##### respond
* `respond` - If `true`, the timeout error is passed to `next()` so that you may customize the response behavior. This error has a `.timeout` property as well as `.status == 503`. This defaults to `true`.
Controls if this module will "respond" in the form of forwarding an error.
If `true`, the timeout error is passed to `next()` so that you may customize
the response behavior. This error has a `.timeout` property as well as
`.status == 503`. This defaults to `true`.
### req.clearTimeout()
Clears the timeout on the request.
Clears the timeout on the request. The timeout is completely removed and
will not fire for this request in the future.
### req.timedout
......@@ -40,102 +64,105 @@ Clears the timeout on the request.
### as top-level middleware
Because of the way middleware processing works, this once this module passes the request
to the next middleware (which it has to do in order for you to do work), it can no longer
stop the flow, so you must take care to check if the request has timedout before you
continue to act on the request.
Because of the way middleware processing works, once this module
passes the request to the next middleware (which it has to do in order
for you to do work), it can no longer stop the flow, so you must take
care to check if the request has timedout before you continue to act
on the request.
```javascript
var express = require('express');
var timeout = require('connect-timeout');
var bodyParser = require('body-parser')
var cookieParser = require('cookie-parser')
var express = require('express')
var timeout = require('connect-timeout')
// example of using this top-level; note the use of haltOnTimedout
// after every middleware; it will stop the request flow on a timeout
var app = express();
app.use(timeout('5s'));
app.use(bodyParser());
app.use(haltOnTimedout);
app.use(cookieParser());
app.use(haltOnTimedout);
var app = express()
app.use(timeout('5s'))
app.use(bodyParser())
app.use(haltOnTimedout)
app.use(cookieParser())
app.use(haltOnTimedout)
// Add your routes here, etc.
function haltOnTimedout(req, res, next){
if (!req.timedout) next();
function haltOnTimedout (req, res, next) {
if (!req.timedout) next()
}
app.listen(3000);
app.listen(3000)
```
### express 3.x
```javascript
var express = require('express');
var bodyParser = require('body-parser');
var timeout = require('connect-timeout');
var app = express();
app.post('/save', timeout('5s'), bodyParser.json(), haltOnTimedout, function(req, res, next){
savePost(req.body, function(err, id){
if (err) return next(err);
if (req.timedout) return;
res.send('saved as id ' + id);
});
});
function haltOnTimedout(req, res, next){
if (!req.timedout) next();
var express = require('express')
var bodyParser = require('body-parser')
var timeout = require('connect-timeout')
var app = express()
app.post('/save', timeout('5s'), bodyParser.json(), haltOnTimedout, function (req, res, next) {
savePost(req.body, function (err, id) {
if (err) return next(err)
if (req.timedout) return
res.send('saved as id ' + id)
})
})
function haltOnTimedout (req, res, next) {
if (!req.timedout) next()
}
function savePost(post, cb){
setTimeout(function(){
cb(null, ((Math.random()* 40000) >>> 0));
}, (Math.random()* 7000) >>> 0));
function savePost (post, cb) {
setTimeout(function () {
cb(null, ((Math.random() * 40000) >>> 0))
}, (Math.random() * 7000) >>> 0)
}
app.listen(3000);
app.listen(3000)
```
### connect
```javascript
var bodyParser = require('body-parser');
var connect = require('connect');
var timeout = require('connect-timeout');
var app = require('connect');
app.use('/save', timeout('5s'), bodyParser.json(), haltOnTimedout, function(req, res, next){
savePost(req.body, function(err, id){
if (err) return next(err);
if (req.timedout) return;
res.send('saved as id ' + id);
});
});
function haltOnTimedout(req, res, next){
if (!req.timedout) next();
var bodyParser = require('body-parser')
var connect = require('connect')
var timeout = require('connect-timeout')
var app = connect()
app.use('/save', timeout('5s'), bodyParser.json(), haltOnTimedout, function (req, res, next) {
savePost(req.body, function (err, id) {
if (err) return next(err)
if (req.timedout) return
res.send('saved as id ' + id)
})
})
function haltOnTimedout (req, res, next) {
if (!req.timedout) next()
}
function savePost(post, cb){
setTimeout(function(){
cb(null, ((Math.random()* 40000) >>> 0));
}, (Math.random()* 7000) >>> 0));
function savePost (post, cb) {
setTimeout(function () {
cb(null, ((Math.random() * 40000) >>> 0))
}, (Math.random() * 7000) >>> 0)
}
app.listen(3000);
app.listen(3000)
```
## License
[MIT](LICENSE)
[npm-image]: https://img.shields.io/npm/v/connect-timeout.svg?style=flat
[npm-image]: https://img.shields.io/npm/v/connect-timeout.svg
[npm-url]: https://npmjs.org/package/connect-timeout
[travis-image]: https://img.shields.io/travis/expressjs/timeout.svg?style=flat
[travis-image]: https://img.shields.io/travis/expressjs/timeout/master.svg
[travis-url]: https://travis-ci.org/expressjs/timeout
[coveralls-image]: https://img.shields.io/coveralls/expressjs/timeout.svg?style=flat
[coveralls-image]: https://img.shields.io/coveralls/expressjs/timeout/master.svg
[coveralls-url]: https://coveralls.io/r/expressjs/timeout?branch=master
[downloads-image]: https://img.shields.io/npm/dm/connect-timeout.svg?style=flat
[downloads-image]: https://img.shields.io/npm/dm/connect-timeout.svg
[downloads-url]: https://npmjs.org/package/connect-timeout
[gratipay-image]: https://img.shields.io/gratipay/dougwilson.svg?style=flat
[gratipay-image]: https://img.shields.io/gratipay/dougwilson.svg
[gratipay-url]: https://www.gratipay.com/dougwilson/
/*!
* connect-timeout
* Copyright(c) 2014 Jonathan Ong
* Copyright(c) 2014 Douglas Christopher Wilson
* Copyright(c) 2014-2015 Douglas Christopher Wilson
* MIT Licensed
*/
'use strict'
/**
* Module dependencies.
* @private
*/
var debug = require('debug')('connect:timeout');
var ms = require('ms');
var onHeaders = require('on-headers');
var createError = require('http-errors')
var ms = require('ms')
var onFinished = require('on-finished')
var onHeaders = require('on-headers')
/**
* Timeout:
*
* See README.md for documentation.
* Module exports.
* @public
*/
module.exports = timeout
/**
* Create a new timeout middleware.
*
* @param {Number} time
* @param {Object} options
* @return {Function} middleware
* @api public
* @param {number|string} [time=5000] The timeout as a number of milliseconds or a string for `ms`
* @param {object} [options] Additional options for middleware
* @param {boolean} [options.respond=true] Automatically emit error when timeout reached
* @return {function} middleware
* @public
*/
module.exports = function timeout(time, options) {
options = options || {};
function timeout (time, options) {
var opts = options || {}
time = typeof time === 'string'
var delay = typeof time === 'string'
? ms(time)
: Number(time || 5000);
: Number(time || 5000)
var respond = !('respond' in options) || options.respond === true;
var respond = opts.respond === undefined || opts.respond === true
return function(req, res, next) {
var destroy = req.socket.destroy;
var id = setTimeout(function(){
req.timedout = true;
req.emit('timeout', time);
}, time);
return function (req, res, next) {
var id = setTimeout(function () {
req.timedout = true
req.emit('timeout', delay)
}, delay)
if (respond) {
req.on('timeout', onTimeout(time, next));
req.on('timeout', onTimeout(delay, next))
}
req.clearTimeout = function(){
clearTimeout(id);
};
req.socket.destroy = function(){
clearTimeout(id);
destroy.call(this);
};
req.clearTimeout = function () {
clearTimeout(id)
}
req.timedout = false;
req.timedout = false
onHeaders(res, function(){
clearTimeout(id);
});
onFinished(res, function () {
clearTimeout(id)
})
next();
};
};
onHeaders(res, function () {
clearTimeout(id)
})
function generateTimeoutError(){
var err = new Error('Response timeout');
err.code = 'ETIMEDOUT';
err.status = 503;
return err;
next()
}
}
function onTimeout(time, cb){
return function(){
var err = generateTimeoutError();
err.timeout = time;
cb(err);
};
/**
* Create timeout listener function.
*
* @param {number} delay
* @param {function} cb
* @private
*/
function onTimeout (delay, cb) {
return function () {
cb(createError(503, 'Response timeout', {
code: 'ETIMEDOUT',
timeout: delay
}))
}
}
{
"name": "connect-timeout",
"description": "timeout middleware",
"version": "1.3.0",
"description": "Request timeout middleware for Connect/Express",
"version": "1.9.0",
"contributors": [
"Douglas Christopher Wilson <doug@somethingdoug.com>",
"Jonathan Ong <me@jongleberry.com> (http://jongleberry.com)"
......@@ -9,15 +9,22 @@
"license": "MIT",
"repository": "expressjs/timeout",
"dependencies": {
"debug": "~2.0.0",
"ms": "0.6.2",
"on-headers": "~1.0.0"
"http-errors": "~1.6.1",
"ms": "2.0.0",
"on-finished": "~2.3.0",
"on-headers": "~1.0.1"
},
"devDependencies": {
"istanbul": "0.3.0",
"mocha": "~1.21.4",
"should": "~4.0.4",
"supertest": "~0.13.0"
"eslint": "3.19.0",
"eslint-config-standard": "10.2.1",
"eslint-plugin-import": "2.2.0",
"eslint-plugin-markdown": "1.0.0-beta.6",
"eslint-plugin-node": "4.2.2",
"eslint-plugin-promise": "3.5.0",
"eslint-plugin-standard": "3.0.1",
"istanbul": "0.4.5",
"mocha": "2.5.3",
"supertest": "1.1.0"
},
"files": [
"LICENSE",
......@@ -28,6 +35,7 @@
"node": ">= 0.8"
},
"scripts": {
"lint": "eslint --plugin markdown --ext js,md .",
"test": "mocha --reporter spec --bail --check-leaks test/",
"test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- --reporter dot --check-leaks test/",
"test-travis": "istanbul cover node_modules/mocha/bin/_mocha --report lcovonly -- --reporter dot --check-leaks test/"
......
{
"env": {
"mocha": true
}
}
var http = require('http');
var request = require('supertest');
var should = require('should');
var timeout = require('..');
var assert = require('assert')
var http = require('http')
var request = require('supertest')
var timeout = require('..')
describe('timeout()', function(){
describe('timeout()', function () {
it('should have a default timeout', function (done) {
this.timeout(10000)
var server = createServer()
......@@ -27,9 +27,9 @@ describe('timeout()', function(){
.expect(503, /45ms/, done)
})
describe('when below the timeout', function(){
it('should do nothing', function(done){
var server = createServer(null, function(req, res){
describe('when below the timeout', function () {
it('should do nothing', function (done) {
var server = createServer(null, function (req, res) {
res.end('Hello')
})
request(server)
......@@ -38,11 +38,11 @@ describe('timeout()', function(){
})
})
describe('when above the timeout', function(){
describe('with no response made', function(){
it('should respond with 503 Request timeout', function(done){
var server = createServer(null, null, function(req, res){
req.timedout.should.be.true
describe('when above the timeout', function () {
describe('with no response made', function () {
it('should respond with 503 Request timeout', function (done) {
var server = createServer(null, null, function (req, res) {
assert.ok(req.timedout)
res.end('Hello')
})
......@@ -51,24 +51,24 @@ describe('timeout()', function(){
.expect(503, done)
})
it('should pass the error to next()', function(done){
var server = createServer(null, null, function(req, res){
req.timedout.should.be.true
it('should pass the error to next()', function (done) {
var server = createServer(null, null, function (req, res) {
assert.ok(req.timedout)
res.end('Hello')
})
request(server)
.get('/')
.expect('Response timeout after 100ms', done);
.expect(503, 'Response timeout after 100ms', done)
})
})
describe('with a partial response', function(){
it('should do nothing', function(done){
describe('with a partial response', function () {
it('should do nothing', function (done) {
var server = createServer(null,
function(req, res){ res.write('Hello') },
function(req, res){
req.timedout.should.be.false
function (req, res) { res.write('Hello') },
function (req, res) {
assert.ok(!req.timedout)
res.end(' World')
})
......@@ -79,9 +79,9 @@ describe('timeout()', function(){
})
})
describe('options', function(){
it('can disable auto response', function(done){
var server = createServer({respond: false}, null, function(req, res){
describe('options', function () {
it('can disable auto response', function (done) {
var server = createServer({respond: false}, null, function (req, res) {
res.end('Timedout ' + req.timedout)
})
......@@ -91,12 +91,12 @@ describe('timeout()', function(){
})
})
describe('req.clearTimeout()', function(){
it('should revert this behavior', function(done){
describe('req.clearTimeout()', function () {
it('should revert this behavior', function (done) {
var server = createServer(null,
function(req, res){ req.clearTimeout() },
function(req, res){
req.timedout.should.be.false
function (req, res) { req.clearTimeout() },
function (req, res) {
assert.ok(!req.timedout)
res.end('Hello')
})
......@@ -106,80 +106,79 @@ describe('timeout()', function(){
})
})