Skip to content

Commit

Permalink
feat: support Keep-Alive Header (#275)
Browse files Browse the repository at this point in the history
  • Loading branch information
fengmk2 authored Feb 28, 2018
1 parent 6237d09 commit d6e7c58
Show file tree
Hide file tree
Showing 6 changed files with 105 additions and 4 deletions.
21 changes: 21 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,28 @@ node_js:
- '4'
- '6'
- '8'
- '9'
env:
- AGENT_VERSION=2
- AGENT_VERSION=3
matrix:
exclude:
- node_js: '0.10'
env: AGENT_VERSION=3
- node_js: '0.12'
env: AGENT_VERSION=3
- node_js: '4'
env: AGENT_VERSION=2
- node_js: '6'
env: AGENT_VERSION=2
- node_js: '8'
env: AGENT_VERSION=2
- node_js: '9'
env: AGENT_VERSION=2
before_install:
- sed -i.bak '/"agentkeepalive":/d' package.json
script:
- eval "npm i agentkeepalive@$AGENT_VERSION"
- npm run ci
after_script:
- npm i codecov && codecov
2 changes: 1 addition & 1 deletion LICENSE.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
This software is licensed under the MIT License.

Copyright(c) 2011 - 2014 fengmk2 and other contributors.
Copyright(c) 2015 - 2017 node-modules and other contributors.
Copyright(c) 2015 - present node-modules and other contributors.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
5 changes: 3 additions & 2 deletions appveyor.yml
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
environment:
matrix:
- nodejs_version: '0.10'
- nodejs_version: '0.12'
# - nodejs_version: '0.10'
# - nodejs_version: '0.12'
- nodejs_version: '4'
- nodejs_version: '6'
- nodejs_version: '8'
- nodejs_version: '9'

install:
- ps: Install-Product node $env:nodejs_version
Expand Down
20 changes: 20 additions & 0 deletions lib/urllib.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,9 @@ var TEXT_DATA_TYPES = [

var PROTO_RE = /^https?:\/\//i;

// Keep-Alive: timeout=5, max=100
var KEEP_ALIVE_RE = /^timeout=(\d+)/i;

/**
* Handle all http request, both http and https support well.
*
Expand Down Expand Up @@ -455,6 +458,23 @@ exports.requestWithCallback = function requestWithCallback(url, args, callback)
err.res = response;
}

// only support agentkeepalive module for now
if (agent && agent.keepAlive && agent.freeSocketKeepAliveTimeout > 0 &&
statusCode >= 200 && headers.connection === 'keep-alive' && headers['keep-alive']) {
// adjust freeSocketKeepAliveTimeout on the socket
var m = KEEP_ALIVE_RE.exec(headers['keep-alive']);
if (m) {
var seconds = parseInt(m[1]);
if (seconds > 0) {
// network delay 500ms
var serverKeepAliveTimeout = seconds * 1000 - 500;
if (serverKeepAliveTimeout < agent.freeSocketKeepAliveTimeout) {
res.socket.freeSocketKeepAliveTimeout = serverKeepAliveTimeout;
}
}
}
}

cb(err, data, args.streaming ? res : response);

if (args.emitter) {
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
"utility": "^1.12.0"
},
"devDependencies": {
"agentkeepalive": "^2.2.0",
"agentkeepalive": "^3.4.0",
"autod": "*",
"bluebird": "*",
"busboy": "^0.2.14",
Expand Down
59 changes: 59 additions & 0 deletions test/keep-alive-header.test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
'use strict';

var assert = require('assert');
var http = require('http');
var Agent = require('agentkeepalive');
var urllib = require('..');

describe('test/keep-alive-header.test.js', function() {
var port;
var server;
var timer;
before(function(done) {
server = http.createServer(function(req, res) {
if (server.keepAliveTimeout) {
res.setHeader('Keep-Alive', 'timeout=' + parseInt(server.keepAliveTimeout / 1000));
}
res.end('Hello World, ' + req.connection.remotePort);
});
server.on('clientError', function(err, socket) {
socket.end('HTTP/1.1 400 Bad Request\r\n\r\n');
});
server.keepAliveTimeout = 1000;
server.listen(0, function(err) {
port = server.address().port;
done(err);
});
});
after(function() {
clearInterval(timer);
});

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

var count = 0;
function request() {
count++;
urllib.request('http://127.0.0.1:' + port + '/foo', {
method: 'GET',
agent: keepaliveAgent,
dataType: 'text',
}, function(err, text, res) {
assert(!err);
assert(res.status === 200);
console.log('[%s] status: %s, text: %s, headers: %j', count, text, res.status, res.headers);
assert(res.headers.connection === 'keep-alive');
assert(res.headers['keep-alive'] === 'timeout=1');
if (count > 5) {
done();
}
});
}

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

0 comments on commit d6e7c58

Please sign in to comment.