pax_global_header00006660000000000000000000000064131067246100014512gustar00rootroot0000000000000052 comment=f2f520f335f2f2ae255d4778e908e8d38e3a4e68 timeout-1.9.0/000077500000000000000000000000001310672461000132075ustar00rootroot00000000000000timeout-1.9.0/.eslintignore000066400000000000000000000000261310672461000157100ustar00rootroot00000000000000coverage node_modules timeout-1.9.0/.eslintrc000066400000000000000000000000341310672461000150300ustar00rootroot00000000000000{ "extends": "standard" } timeout-1.9.0/.gitignore000066400000000000000000000012221310672461000151740ustar00rootroot00000000000000# 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 timeout-1.9.0/.travis.yml000066400000000000000000000016411310672461000153220ustar00rootroot00000000000000language: node_js node_js: - "0.8" - "0.10" - "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" timeout-1.9.0/HISTORY.md000066400000000000000000000050131310672461000146710ustar00rootroot000000000000001.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 ================== * deps: debug@~2.0.0 1.2.2 / 2014-08-10 ================== * deps: on-headers@~1.0.0 1.2.1 / 2014-07-22 ================== * deps: debug@1.0.4 1.2.0 / 2014-07-11 ================== * Accept string for `time` (converted by `ms`) * deps: debug@1.0.3 - Add support for multiple wildcards in namespaces 1.1.1 / 2014-06-16 ================== * deps: debug@1.0.2 1.1.0 / 2014-04-29 ================== * Add `req.timedout` property * Add `respond` option to constructor 1.0.1 / 2014-04-28 ================== * Clear timer on socket destroy * Compatible with node.js 0.8 * deps: debug@0.8.1 1.0.0 / 2014-03-05 ================== * Genesis from `connect` timeout-1.9.0/LICENSE000066400000000000000000000022241310672461000142140ustar00rootroot00000000000000(The MIT License) Copyright (c) 2014 Jonathan Ong Copyright (c) 2014-2015 Douglas Christopher Wilson Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. timeout-1.9.0/README.md000066400000000000000000000117121310672461000144700ustar00rootroot00000000000000# connect-timeout [![NPM Version][npm-image]][npm-url] [![NPM Downloads][downloads-image]][downloads-url] [![Build Status][travis-image]][travis-url] [![Test Coverage][coveralls-image]][coveralls-url] [![Gratipay][gratipay-image]][gratipay-url] 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) for how to use as a top-level middleware. 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 The `timeout` function takes an optional `options` object that may contain any of the following keys: ##### respond 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. The timeout is completely removed and will not fire for this request in the future. ### req.timedout `true` if timeout fired; `false` otherwise. ## Examples ### as top-level middleware 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 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) // Add your routes here, etc. function haltOnTimedout (req, res, next) { if (!req.timedout) next() } 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() } function savePost (post, cb) { setTimeout(function () { cb(null, ((Math.random() * 40000) >>> 0)) }, (Math.random() * 7000) >>> 0) } app.listen(3000) ``` ### connect ```javascript 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) } app.listen(3000) ``` ## License [MIT](LICENSE) [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/master.svg [travis-url]: https://travis-ci.org/expressjs/timeout [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 [downloads-url]: https://npmjs.org/package/connect-timeout [gratipay-image]: https://img.shields.io/gratipay/dougwilson.svg [gratipay-url]: https://www.gratipay.com/dougwilson/ timeout-1.9.0/index.js000066400000000000000000000032321310672461000146540ustar00rootroot00000000000000/*! * connect-timeout * Copyright(c) 2014 Jonathan Ong * Copyright(c) 2014-2015 Douglas Christopher Wilson * MIT Licensed */ 'use strict' /** * Module dependencies. * @private */ var createError = require('http-errors') var ms = require('ms') var onFinished = require('on-finished') var onHeaders = require('on-headers') /** * Module exports. * @public */ module.exports = timeout /** * Create a new timeout middleware. * * @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 */ function timeout (time, options) { var opts = options || {} var delay = typeof time === 'string' ? ms(time) : Number(time || 5000) var respond = opts.respond === undefined || opts.respond === true return function (req, res, next) { var id = setTimeout(function () { req.timedout = true req.emit('timeout', delay) }, delay) if (respond) { req.on('timeout', onTimeout(delay, next)) } req.clearTimeout = function () { clearTimeout(id) } req.timedout = false onFinished(res, function () { clearTimeout(id) }) onHeaders(res, function () { clearTimeout(id) }) next() } } /** * 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 })) } } timeout-1.9.0/package.json000066400000000000000000000024041310672461000154750ustar00rootroot00000000000000{ "name": "connect-timeout", "description": "Request timeout middleware for Connect/Express", "version": "1.9.0", "contributors": [ "Douglas Christopher Wilson ", "Jonathan Ong (http://jongleberry.com)" ], "license": "MIT", "repository": "expressjs/timeout", "dependencies": { "http-errors": "~1.6.1", "ms": "2.0.0", "on-finished": "~2.3.0", "on-headers": "~1.0.1" }, "devDependencies": { "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", "HISTORY.md", "index.js" ], "engines": { "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/" } } timeout-1.9.0/test/000077500000000000000000000000001310672461000141665ustar00rootroot00000000000000timeout-1.9.0/test/.eslintrc000066400000000000000000000000451310672461000160110ustar00rootroot00000000000000{ "env": { "mocha": true } } timeout-1.9.0/test/test.js000066400000000000000000000117531310672461000155120ustar00rootroot00000000000000 var assert = require('assert') var http = require('http') var request = require('supertest') var timeout = require('..') describe('timeout()', function () { it('should have a default timeout', function (done) { this.timeout(10000) var server = createServer() request(server) .get('/') .expect(503, done) }) it('should accept millisecond timeout', function (done) { var server = createServer(123) request(server) .get('/') .expect(503, /123ms/, done) }) it('should accept string timeout', function (done) { var server = createServer('45ms') request(server) .get('/') .expect(503, /45ms/, done) }) describe('when below the timeout', function () { it('should do nothing', function (done) { var server = createServer(null, function (req, res) { res.end('Hello') }) request(server) .get('/') .expect(200, 'Hello', done) }) }) 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') }) request(server) .get('/') .expect(503, done) }) 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(503, 'Response timeout after 100ms', 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) { assert.ok(!req.timedout) res.end(' World') }) request(server) .get('/') .expect(200, 'Hello World', done) }) }) }) describe('options', function () { it('can disable auto response', function (done) { var server = createServer({respond: false}, null, function (req, res) { res.end('Timedout ' + req.timedout) }) request(server) .get('/') .expect(200, 'Timedout true', done) }) }) describe('req.clearTimeout()', function () { it('should revert this behavior', function (done) { var server = createServer(null, function (req, res) { req.clearTimeout() }, function (req, res) { assert.ok(!req.timedout) res.end('Hello') }) request(server) .get('/') .expect(200, 'Hello', done) }) }) describe('destroy()', function () { it('req should clear timer', function (done) { var server = createServer(null, function (req, res) { req.destroy() }, function (req, res) { assert.equal(error.code, 'ECONNRESET') assert.ok(!req.timedout) done() }) var error request(server) .get('/') .end(function (err) { error = err }) }) it('res should clear timer', function (done) { var server = createServer(null, function (req, res) { res.destroy() }, function (req, res) { assert.equal(error.code, 'ECONNRESET') assert.ok(!req.timedout) done() }) var error request(server) .get('/') .end(function (err) { error = err }) }) it('socket should clear timer', function (done) { var server = createServer(null, function (req, res) { req.socket.destroy() }, function (req, res) { assert.equal(error.code, 'ECONNRESET') assert.ok(!req.timedout) done() }) var error request(server) .get('/') .end(function (err) { error = err }) }) }) describe('when request aborted', function () { it('should clear timeout', function (done) { var aborted = false var server = createServer(null, function (req, res) { req.on('aborted', function () { aborted = true }) test.abort() }, function (req, res) { assert.ok(aborted) assert.ok(!req.timedout) done() }) var test = request(server).post('/') test.write('0') }) }) }) function createServer (options, before, after) { var _ms = 100 if (typeof options !== 'object') { _ms = options options = {} } var _timeout = timeout(_ms, options) return http.createServer(function (req, res) { _timeout(req, res, function (err) { if (err) { res.statusCode = err.status || 500 res.end(err.message + ' after ' + err.timeout + 'ms') return } if (before) { before(req, res) } if (after) { setTimeout(function () { after(req, res) }, (_ms + 100)) } }) }) }