Skip to content

Commit

Permalink
feat: use socket custom freeSocketKeepAliveTimeout first (#59)
Browse files Browse the repository at this point in the history
  • Loading branch information
fengmk2 authored and dead-horse committed Feb 27, 2018
1 parent 138eda8 commit bc7cadb
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 8 deletions.
2 changes: 1 addition & 1 deletion .travis.yml
Expand Up @@ -4,8 +4,8 @@ node_js:
- '4.3.2'
- '4'
- '6'
- '7'
- '8'
- '9'
install:
- npm i npminstall && npminstall
script:
Expand Down
4 changes: 2 additions & 2 deletions appveyor.yml
Expand Up @@ -3,8 +3,8 @@ environment:
- nodejs_version: '4.3.2'
- nodejs_version: '4'
- nodejs_version: '6'
- nodejs_version: '7'
- nodejs_version: '8'
- nodejs_version: '9'

install:
- ps: Install-Product node $env:nodejs_version
Expand All @@ -13,6 +13,6 @@ install:
test_script:
- node --version
- npm --version
- npm run ci
- npm run test

build: off
12 changes: 8 additions & 4 deletions lib/_http_agent.js
Expand Up @@ -119,7 +119,10 @@ function Agent(options) {
socket.once('error', freeSocketErrorListener);
}
// set free keepalive timer
socket.setTimeout(self.freeSocketKeepAliveTimeout);
// try to use socket custom freeSocketKeepAliveTimeout first
const freeSocketKeepAliveTimeout = socket.freeSocketKeepAliveTimeout || self.freeSocketKeepAliveTimeout;
socket.setTimeout(freeSocketKeepAliveTimeout);
debug(`push to free socket queue and wait for ${freeSocketKeepAliveTimeout}ms`);
// [patch end]
}
} else {
Expand Down Expand Up @@ -179,13 +182,14 @@ function handleSocketCreation(req) {
}
// [patch end]

Agent.prototype.addRequest = function addRequest(req, options) {
Agent.prototype.addRequest = function addRequest(req, options, port/*legacy*/,
localAddress/*legacy*/) {
// Legacy API: addRequest(req, host, port, localAddress)
if (typeof options === 'string') {
options = {
host: options,
port: arguments[2],
localAddress: arguments[3]
port,
localAddress
};
}

Expand Down
2 changes: 1 addition & 1 deletion package.json
Expand Up @@ -45,7 +45,7 @@
"node": ">= 4.0.0"
},
"ci": {
"version": "4.3.2, 4, 6, 7, 8"
"version": "4.3.2, 4, 6, 8, 9"
},
"author": "fengmk2 <fengmk2@gmail.com> (https://fengmk2.com)",
"license": "MIT"
Expand Down
73 changes: 73 additions & 0 deletions test/server_timeout.test.js
@@ -0,0 +1,73 @@
'use strict';

const assert = require('assert');
const http = require('http');
const Agent = require('..');

describe('test/server_timeout.test.js', () => {
let port;
let server;
before(done => {
server = http.createServer((req, res) => {
if (server.keepAliveTimeout) {
res.setHeader('Keep-Alive', `timeout=${parseInt(server.keepAliveTimeout / 1000)}`);
}
res.end('Hello World, ' + req.connection.remotePort);
});
server.on('clientError', (err, socket) => {
socket.end('HTTP/1.1 400 Bad Request\r\n\r\n');
});
server.keepAliveTimeout = 1000;
server.listen(0, err => {
port = server.address().port;
done(err);
});
});

it('should handle Keep-Alive header and not throw reset error', done => {
const keepaliveAgent = new Agent({
keepAlive: true,
});

let count = 0;
function request() {
count++;
const req = http.request({
method: 'GET',
port,
path: '/',
agent: keepaliveAgent,
}, res => {
assert(res.statusCode === 200);
const chunks = [];
res.on('data', data => {
chunks.push(data);
});
res.on('end', () => {
const text = Buffer.concat(chunks).toString();
console.log('[%s] status: %s, text: %s, headers: %j', count, text, res.statusCode, res.headers);
assert(res.headers.connection === 'keep-alive');
assert(res.headers['keep-alive'] === 'timeout=1');
const m = /^timeout=(\d+?)/.exec(res.headers['keep-alive']);
if (m) {
const keepAliveTimeout = parseInt(m[1]) * 1000 - 500;
if (keepAliveTimeout > 0) {
res.socket.freeSocketKeepAliveTimeout = keepAliveTimeout;
}
}
if (count > 5) {
done();
}
});
});
req.on('error', err => {
console.error('[%s] error: %s', count, err);
done(err);
});
req.end();
}

setInterval(request, server.keepAliveTimeout);
request();
});
});

0 comments on commit bc7cadb

Please sign in to comment.