Skip to content

Commit ffe7144

Browse files
committed
feat: use socket custom freeSocketKeepAliveTimeout first
to support Keep-Alive header on the user land closes #58
1 parent 7c46df1 commit ffe7144

File tree

5 files changed

+77
-10
lines changed

5 files changed

+77
-10
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ node_js:
44
- '4.3.2'
55
- '4'
66
- '6'
7-
- '7'
87
- '8'
8+
- '9'
99
install:
1010
- npm i npminstall && npminstall
1111
script:

appveyor.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ environment:
33
- nodejs_version: '4.3.2'
44
- nodejs_version: '4'
55
- nodejs_version: '6'
6-
- nodejs_version: '7'
76
- nodejs_version: '8'
7+
- nodejs_version: '9'
88

99
install:
1010
- ps: Install-Product node $env:nodejs_version
@@ -13,6 +13,6 @@ install:
1313
test_script:
1414
- node --version
1515
- npm --version
16-
- npm run ci
16+
- npm run test
1717

1818
build: off

lib/_http_agent.js

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,10 @@ function Agent(options) {
119119
socket.once('error', freeSocketErrorListener);
120120
}
121121
// set free keepalive timer
122-
socket.setTimeout(self.freeSocketKeepAliveTimeout);
122+
// try to use socket custom freeSocketKeepAliveTimeout first
123+
const freeSocketKeepAliveTimeout = socket.freeSocketKeepAliveTimeout || self.freeSocketKeepAliveTimeout;
124+
socket.setTimeout(freeSocketKeepAliveTimeout);
125+
debug(`push to free socket queue and wait for ${freeSocketKeepAliveTimeout}ms`);
123126
// [patch end]
124127
}
125128
} else {
@@ -179,13 +182,14 @@ function handleSocketCreation(req) {
179182
}
180183
// [patch end]
181184

182-
Agent.prototype.addRequest = function addRequest(req, options) {
185+
Agent.prototype.addRequest = function addRequest(req, options, port/*legacy*/,
186+
localAddress/*legacy*/) {
183187
// Legacy API: addRequest(req, host, port, localAddress)
184188
if (typeof options === 'string') {
185189
options = {
186190
host: options,
187-
port: arguments[2],
188-
localAddress: arguments[3]
191+
port,
192+
localAddress
189193
};
190194
}
191195

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,8 @@
1010
"lib"
1111
],
1212
"scripts": {
13-
"test": "egg-bin test",
14-
"cov": "egg-bin cov",
13+
"test": "egg-bin test && node test/server_timeout.js",
14+
"cov": "egg-bin cov && node test/server_timeout.js",
1515
"ci": "npm run lint && npm run cov",
1616
"lint": "eslint lib test index.js",
1717
"autod": "autod"
@@ -45,7 +45,7 @@
4545
"node": ">= 4.0.0"
4646
},
4747
"ci": {
48-
"version": "4.3.2, 4, 6, 7, 8"
48+
"version": "4.3.2, 4, 6, 8, 9"
4949
},
5050
"author": "fengmk2 <fengmk2@gmail.com> (https://fengmk2.com)",
5151
"license": "MIT"

test/server_timeout.js

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
'use strict';
2+
3+
const assert = require('assert');
4+
const http = require('http');
5+
const Agent = require('..');
6+
7+
const keepaliveAgent = new Agent({
8+
keepAlive: true,
9+
});
10+
const server = http.createServer((req, res) => {
11+
if (server.keepAliveTimeout) {
12+
res.setHeader('Keep-Alive', `time=${parseInt(server.keepAliveTimeout / 1000)}`);
13+
}
14+
res.end('Hello World, ' + req.connection.remotePort);
15+
});
16+
server.on('clientError', (err, socket) => {
17+
socket.end('HTTP/1.1 400 Bad Request\r\n\r\n');
18+
});
19+
20+
const port = 3000;
21+
server.listen(port);
22+
server.keepAliveTimeout = 1000;
23+
24+
let count = 0;
25+
function request() {
26+
count++;
27+
const req = http.request({
28+
method: 'GET',
29+
port,
30+
path: '/',
31+
agent: keepaliveAgent,
32+
}, res => {
33+
assert(res.statusCode === 200);
34+
const chunks = [];
35+
res.on('data', data => {
36+
chunks.push(data);
37+
});
38+
res.on('end', () => {
39+
const text = Buffer.concat(chunks).toString();
40+
console.log('[%s] status: %s, text: %s, headers: %j', count, text, res.statusCode, res.headers);
41+
assert(res.headers.connection === 'keep-alive');
42+
assert(res.headers['keep-alive'] === 'time=1');
43+
const m = /^time=(\d+?)/.exec(res.headers['keep-alive']);
44+
if (m) {
45+
const keepAliveTimeout = parseInt(m[1]) * 1000 - 500;
46+
if (keepAliveTimeout > 0) {
47+
res.socket.freeSocketKeepAliveTimeout = keepAliveTimeout;
48+
}
49+
}
50+
if (count > 5) {
51+
process.exit(0);
52+
}
53+
});
54+
});
55+
req.on('error', err => {
56+
console.error('[%s] error: %s', count, err);
57+
throw err;
58+
});
59+
req.end();
60+
}
61+
62+
setInterval(request, server.keepAliveTimeout);
63+
request();

0 commit comments

Comments
 (0)