From addb6402e3ffaa0ed914cdec973bb533d513ce3a Mon Sep 17 00:00:00 2001 From: fengmk2 Date: Sat, 12 Mar 2016 13:43:11 +0800 Subject: [PATCH 1/6] test: run on more node versions --- .travis.yml | 11 +++++++---- lib/agent.js | 4 +--- package.json | 16 +++++++++------- 3 files changed, 17 insertions(+), 14 deletions(-) diff --git a/.travis.yml b/.travis.yml index e9f45a0..63f90f6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,8 +1,11 @@ +sudo: false language: node_js node_js: - '0.10' - - '0.11' - '0.12' - - 'iojs-1' -script: "npm run test-travis" -after_script: "npm install coveralls@2 && cat ./coverage/lcov.info | coveralls" + - '4.3.2' + - '4' + - '5.3.0' + - '5' +script: 'npm run ci' +after_script: 'npm i codecov && codecov' diff --git a/lib/agent.js b/lib/agent.js index 11cdf95..1e04b68 100644 --- a/lib/agent.js +++ b/lib/agent.js @@ -1,6 +1,4 @@ -/**! - * agentkeepalive - lib/agent.js - * +/** * refer: * * @atimb "Real keep-alive HTTP agent": https://gist.github.com/2963672 * * https://github.com/joyent/node/blob/master/lib/http.js diff --git a/package.json b/package.json index 844e384..ea45131 100644 --- a/package.json +++ b/package.json @@ -4,15 +4,15 @@ "description": "Missing keepalive http.Agent", "main": "index.js", "files": [ - "index.js", "lib/" + "index.js", + "lib" ], "scripts": { "test": "mocha -R spec -t 5000 -r should-http test/*.test.js", - "test-cov": "node node_modules/.bin/istanbul cover node_modules/.bin/_mocha -- -t 5000 -r should-http test/*.test.js", - "test-travis": "node node_modules/.bin/istanbul cover node_modules/.bin/_mocha --report lcovonly -- -t 5000 -r should-http test/*.test.js", - "jshint": "jshint .", - "autod": "autod -w --prefix '~' && npm run cnpm", - "cnpm": "npm install --registry=https://registry.npm.taobao.org", + "test-cov": "istanbul cover node_modules/.bin/_mocha -- -t 5000 -r should-http test/*.test.js", + "ci": "npm run lint && npm run test-cov", + "lint": "jshint .", + "autod": "autod -w --prefix '~'", "contributors": "contributors -f plain -o AUTHORS" }, "repository": { @@ -24,8 +24,10 @@ }, "keywords": [ "http", + "https", "agent", - "keepalive" + "keepalive", + "agentkeepalive" ], "dependencies": { From f588a95f31205479a53f6bc4d2a994866b6b3432 Mon Sep 17 00:00:00 2001 From: fengmk2 Date: Sat, 12 Mar 2016 13:45:06 +0800 Subject: [PATCH 2/6] fix: handle idle socket error - closes #25 - closes #28 --- lib/_http_agent.js | 26 ++++++++++++++++---------- test/agent.test.js | 46 ++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 58 insertions(+), 14 deletions(-) diff --git a/lib/_http_agent.js b/lib/_http_agent.js index c1ec7a0..70c9c3a 100644 --- a/lib/_http_agent.js +++ b/lib/_http_agent.js @@ -19,7 +19,7 @@ // OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE // USE OR OTHER DEALINGS IN THE SOFTWARE. -// copy from https://github.com/joyent/node/blob/master/lib/_http_agent.js +// copy from https://github.com/nodejs/node/blob/v4.x/lib/_http_agent.js 'use strict'; @@ -71,6 +71,7 @@ function Agent(options) { self.keepAliveMsecs = self.options.keepAliveMsecs || 1000; self.keepAlive = self.options.keepAlive || false; // free keep-alive socket timeout. By default free socket do not have a timeout. + // keepAliveTimeout should be rename to `freeSocketKeepAliveTimeout` self.keepAliveTimeout = self.options.keepAliveTimeout || 0; // working socket timeout. By default working socket do not have a timeout. self.timeout = self.options.timeout || 0; @@ -116,6 +117,11 @@ function Agent(options) { self.removeSocket(socket, options); freeSockets.push(socket); + // Add a default error handler to avoid Unhandled 'error' event throw on idle socket + // https://github.com/node-modules/agentkeepalive/issues/25 + // https://github.com/nodejs/node/pull/4482 (fixed in >= 4.4.0 and >= 5.4.0) + socket.once('error', freeSocketErrorListener); + // set free keepalive timer socket.setTimeout(self.keepAliveTimeout); } @@ -130,6 +136,13 @@ function Agent(options) { util.inherits(Agent, EventEmitter); exports.Agent = Agent; +function freeSocketErrorListener(err) { + var socket = this; + debug('SOCKET ERROR on FREE socket:', err.message, err.stack); + socket.destroy(); + socket.emit('agentRemove'); +} + Agent.defaultMaxSockets = Infinity; Agent.prototype.createConnection = net.createConnection; @@ -176,6 +189,8 @@ Agent.prototype.addRequest = function(req, options) { var socket = this.freeSockets[name].shift(); debug('have free socket'); + socket.removeListener('error', freeSocketErrorListener); + // restart the default timer socket.setTimeout(this.timeout); @@ -257,14 +272,6 @@ Agent.prototype.createSocket = function(req, options) { // set the default timer s.setTimeout(self.timeout); - // Add a default error handler to avoid Unhandled 'error' event throw - // https://github.com/node-modules/agentkeepalive/issues/25 - function onError(err) { - debug('CLIENT socket onError: %s', err); - self.emit('error', err); - } - s.on('error', onError); - function onRemove() { // We need this function for cases like HTTP 'upgrade' // (defined by WebSockets) where we need to remove a socket from the @@ -274,7 +281,6 @@ Agent.prototype.createSocket = function(req, options) { s.removeListener('close', onClose); s.removeListener('free', onFree); s.removeListener('agentRemove', onRemove); - s.removeListener('error', onError); // remove timer s.setTimeout(0, onTimeout); } diff --git a/test/agent.test.js b/test/agent.test.js index 4cdf6a4..0f837c5 100644 --- a/test/agent.test.js +++ b/test/agent.test.js @@ -1,6 +1,4 @@ -/*! - * agentkeepalive - test/agent.test.js - * +/** * Copyright(c) 2012 - 2013 fengmk2 * Copyright(c) node-modules * MIT Licensed @@ -19,7 +17,7 @@ require('should-http'); var pedding = require('pedding'); var Agent = require('../'); -describe('agent.test.js', function () { +describe('test/agent.test.js', function () { var agentkeepalive = new Agent({ keepAliveTimeout: 1000, @@ -810,4 +808,44 @@ describe('agent.test.js', function () { }); }); + describe('mock idle socket error', function() { + it('should idle socket emit error event', function(done) { + var agent = new Agent(); + + var options = { + host: 'www.taobao.com', + port: 80, + path: '/', + agent: agent + }; + + var socketKey = agent.getName(options); + var req = http.get(options, function(res) { + var size = 0; + res.on('data', function(chunk) { + size += chunk.length; + }); + res.on('end', function() { + size.should.above(0); + Object.keys(agent.freeSockets).should.length(0); + process.nextTick(function() { + should.exist(agent.freeSockets[socketKey]); + agent.freeSockets[socketKey].should.length(1); + setTimeout(function() { + // agent should catch idle socket error event + agent.freeSockets[socketKey][0].emit('error', new Error('mock read ECONNRESET')); + + setTimeout(function() { + // error socket should be destroy and remove + Object.keys(agent.freeSockets).should.length(0); + done(); + }, 10); + }, 10); + }); + }); + res.resume(); + }); + req.on('error', done); + }); + }); }); From ee67611776277ba79936a35cef8e9c1174b201af Mon Sep 17 00:00:00 2001 From: fengmk2 Date: Sat, 12 Mar 2016 13:53:53 +0800 Subject: [PATCH 3/6] chore: use codecov --- README.md | 9 +++------ package.json | 17 +++++++++-------- 2 files changed, 12 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index 709f66c..c135925 100644 --- a/README.md +++ b/README.md @@ -2,8 +2,7 @@ [![NPM version][npm-image]][npm-url] [![build status][travis-image]][travis-url] -[![Test coverage][coveralls-image]][coveralls-url] -[![Gittip][gittip-image]][gittip-url] +[![Test coverage][codecov-image]][codecov-url] [![David deps][david-image]][david-url] [![node version][node-image]][node-url] [![npm download][download-image]][download-url] @@ -12,10 +11,8 @@ [npm-url]: https://npmjs.org/package/agentkeepalive [travis-image]: https://img.shields.io/travis/node-modules/agentkeepalive.svg?style=flat [travis-url]: https://travis-ci.org/node-modules/agentkeepalive -[coveralls-image]: https://img.shields.io/coveralls/node-modules/agentkeepalive.svg?style=flat -[coveralls-url]: https://coveralls.io/r/node-modules/agentkeepalive?branch=master -[gittip-image]: https://img.shields.io/gittip/fengmk2.svg?style=flat -[gittip-url]: https://www.gittip.com/fengmk2/ +[codecov-image]: https://codecov.io/github/node-modules/agentkeepalive/coverage.svg?branch=master +[codecov-url]: https://codecov.io/github/node-modules/agentkeepalive?branch=master [david-image]: https://img.shields.io/david/node-modules/agentkeepalive.svg?style=flat [david-url]: https://david-dm.org/node-modules/agentkeepalive [node-image]: https://img.shields.io/badge/node.js-%3E=_0.11-green.svg?style=flat-square diff --git a/package.json b/package.json index ea45131..f672379 100644 --- a/package.json +++ b/package.json @@ -29,19 +29,20 @@ "keepalive", "agentkeepalive" ], - "dependencies": { - - }, + "dependencies": {}, "devDependencies": { "autod": "*", "contributors": "*", "istanbul": "*", "mocha": "*", - "pedding": "~1.0.0", - "should": "~4.0.4", - "should-http": "~0.0.2" + "pedding": "1", + "should": "4", + "should-http": "~0.0.2", + "jshint": "^2.9.1" + }, + "engines": { + "node": ">= 0.10.0" }, - "engines": { "node": ">= 0.10.0" }, "author": "fengmk2 (http://fengmk2.com)", "license": "MIT" -} +} \ No newline at end of file From 27a884e590568192592091ec78ed02949a8c41e1 Mon Sep 17 00:00:00 2001 From: fengmk2 Date: Sat, 12 Mar 2016 13:57:40 +0800 Subject: [PATCH 4/6] refactor: make sure only one error listener --- lib/_http_agent.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/_http_agent.js b/lib/_http_agent.js index 70c9c3a..f66c9c9 100644 --- a/lib/_http_agent.js +++ b/lib/_http_agent.js @@ -120,7 +120,9 @@ function Agent(options) { // Add a default error handler to avoid Unhandled 'error' event throw on idle socket // https://github.com/node-modules/agentkeepalive/issues/25 // https://github.com/nodejs/node/pull/4482 (fixed in >= 4.4.0 and >= 5.4.0) - socket.once('error', freeSocketErrorListener); + if (socket.listeners('error').length === 0) { + socket.once('error', freeSocketErrorListener); + } // set free keepalive timer socket.setTimeout(self.keepAliveTimeout); From e541fdd35127782e80630bc1dd40e4f6c65a70da Mon Sep 17 00:00:00 2001 From: fengmk2 Date: Sat, 12 Mar 2016 14:02:58 +0800 Subject: [PATCH 5/6] test: add appveyor ci build --- .travis.yml | 2 +- README.md | 3 +++ appveyor.yml | 28 ++++++++++++++++++++++++++++ package.json | 7 ++++--- 4 files changed, 36 insertions(+), 4 deletions(-) create mode 100644 appveyor.yml diff --git a/.travis.yml b/.travis.yml index 63f90f6..bc6c502 100644 --- a/.travis.yml +++ b/.travis.yml @@ -8,4 +8,4 @@ node_js: - '5.3.0' - '5' script: 'npm run ci' -after_script: 'npm i codecov && codecov' +after_script: 'npm run codecov' diff --git a/README.md b/README.md index c135925..4f3592b 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,7 @@ [![NPM version][npm-image]][npm-url] [![build status][travis-image]][travis-url] +[![appveyor build status][appveyor-image]][appveyor-url] [![Test coverage][codecov-image]][codecov-url] [![David deps][david-image]][david-url] [![node version][node-image]][node-url] @@ -11,6 +12,8 @@ [npm-url]: https://npmjs.org/package/agentkeepalive [travis-image]: https://img.shields.io/travis/node-modules/agentkeepalive.svg?style=flat [travis-url]: https://travis-ci.org/node-modules/agentkeepalive +[appveyor-image]: https://ci.appveyor.com/api/projects/status/k7ct4s47di6m5uy2?svg=true +[appveyor-url]: https://ci.appveyor.com/project/fengmk2/agentkeepalive [codecov-image]: https://codecov.io/github/node-modules/agentkeepalive/coverage.svg?branch=master [codecov-url]: https://codecov.io/github/node-modules/agentkeepalive?branch=master [david-image]: https://img.shields.io/david/node-modules/agentkeepalive.svg?style=flat diff --git a/appveyor.yml b/appveyor.yml new file mode 100644 index 0000000..64d6983 --- /dev/null +++ b/appveyor.yml @@ -0,0 +1,28 @@ +environment: + global: + npm_registry: https://registry.npmjs.com + + matrix: + - nodejs_version: "0.10" + - nodejs_version: "0.12" + - nodejs_version: "4.3.2" + - nodejs_version: "4" + - nodejs_version: "5.3.0" + - nodejs_version: "5" + +# Install scripts. (runs after repo cloning) +install: + # Get the latest stable version of Node.js or io.js + - ps: Install-Product node $env:nodejs_version + # install modules + - npm i + +# Post-install test scripts. +test_script: + # Output useful info for debugging. + - node --version + - npm --version + - npm run ci + +# Don't actually build. +build: off diff --git a/package.json b/package.json index f672379..b9faf29 100644 --- a/package.json +++ b/package.json @@ -9,11 +9,12 @@ ], "scripts": { "test": "mocha -R spec -t 5000 -r should-http test/*.test.js", - "test-cov": "istanbul cover node_modules/.bin/_mocha -- -t 5000 -r should-http test/*.test.js", + "test-cov": "istanbul cover node_modules/mocha/bin/_mocha -- -t 5000 -r should-http test/*.test.js", "ci": "npm run lint && npm run test-cov", "lint": "jshint .", "autod": "autod -w --prefix '~'", - "contributors": "contributors -f plain -o AUTHORS" + "contributors": "contributors -f plain -o AUTHORS", + "codecov": "npm i codecov && codecov" }, "repository": { "type": "git", @@ -45,4 +46,4 @@ }, "author": "fengmk2 (http://fengmk2.com)", "license": "MIT" -} \ No newline at end of file +} From 2fbb3a73bad2726c3b0496597ea23fefa50d85c1 Mon Sep 17 00:00:00 2001 From: fengmk2 Date: Sat, 12 Mar 2016 14:31:37 +0800 Subject: [PATCH 6/6] test: add Circle ci --- README.md | 5 ++++- circle.yml | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 circle.yml diff --git a/README.md b/README.md index 4f3592b..5b98168 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,8 @@ [![NPM version][npm-image]][npm-url] [![build status][travis-image]][travis-url] -[![appveyor build status][appveyor-image]][appveyor-url] +[![Circle status][circle-image]][circle-url] +[![Appveyor status][appveyor-image]][appveyor-url] [![Test coverage][codecov-image]][codecov-url] [![David deps][david-image]][david-url] [![node version][node-image]][node-url] @@ -12,6 +13,8 @@ [npm-url]: https://npmjs.org/package/agentkeepalive [travis-image]: https://img.shields.io/travis/node-modules/agentkeepalive.svg?style=flat [travis-url]: https://travis-ci.org/node-modules/agentkeepalive +[circle-image]: https://circleci.com/gh/node-modules/agentkeepalive.svg?style=svg +[circle-url]: https://circleci.com/gh/node-modules/agentkeepalive [appveyor-image]: https://ci.appveyor.com/api/projects/status/k7ct4s47di6m5uy2?svg=true [appveyor-url]: https://ci.appveyor.com/project/fengmk2/agentkeepalive [codecov-image]: https://codecov.io/github/node-modules/agentkeepalive/coverage.svg?branch=master diff --git a/circle.yml b/circle.yml new file mode 100644 index 0000000..1daf26c --- /dev/null +++ b/circle.yml @@ -0,0 +1,19 @@ +machine: + node: + version: '4' + +dependencies: + override: + - nvm ls + +test: + override: + - nvm i 0.10 && rm -rf node_modules && npm i && npm run ci && npm run codecov + - nvm i 0.12 && rm -rf node_modules && npm i && npm run ci && npm run codecov + - nvm i 4.3.2 && rm -rf node_modules && npm i && npm run ci && npm run codecov + - nvm i 4 && rm -rf node_modules && npm i && npm run ci && npm run codecov + - nvm i 5.3.0 && rm -rf node_modules && npm i && npm run ci && npm run codecov + - nvm i 5 && rm -rf node_modules && npm i && npm run ci && npm run codecov + +# https://circleci.com/docs/language-nodejs +# https://discuss.circleci.com/t/testing-multiple-versions-of-node/542