Skip to content

Commit 5cdfe8e

Browse files
committed
Add tests and docs for using the agent, agentClass and agentOptions
Forever option defaults to using http(s).Agent in node 0.12+
1 parent bb57809 commit 5cdfe8e

4 files changed

Lines changed: 114 additions & 21 deletions

File tree

‎README.md‎

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -772,7 +772,11 @@ The first argument can be either a `url` or an `options` object. The only requir
772772

773773
---
774774

775-
- `pool` - An object describing which agents to use for the request. If this option is omitted the request will use the global agent (as long as [your options allow for it](request.js#L747)). Otherwise, request will search the pool for your custom agent. If no custom agent is found, a new agent will be created and added to the pool.
775+
- `agent` - `http(s).Agent` instance to use
776+
- `agentClass` - alternatively specify your agent's class name
777+
- `agentOptions` - and pass its options. **Note:** for HTTPS see [tls API doc for TLS/SSL options](http://nodejs.org/api/tls.html#tls_tls_connect_options_callback) and the [documentation above](#using-optionsagentoptions).
778+
- `forever` - set to `true` to use the [forever-agent](https://github.com/request/forever-agent) **Use only with node 0.10-**
779+
- `pool` - An object describing which agents to use for the request. If this option is omitted the request will use the global agent (as long as your options allow for it). Otherwise, request will search the pool for your custom agent. If no custom agent is found, a new agent will be created and added to the pool. **Note:** `pool` is used only when the `agent` option is not specified.
776780
- A `maxSockets` property can also be provided on the `pool` object to set the max number of sockets for all agents created (ex: `pool: {maxSockets: Infinity}`).
777781
- Note that if you are sending multiple requests in a loop and creating
778782
multiple new `pool` objects, `maxSockets` will not work as intended. To
@@ -783,10 +787,12 @@ The first argument can be either a `url` or an `options` object. The only requir
783787
request to respond before aborting the request. Note that if the underlying
784788
TCP connection cannot be established, the OS-wide TCP connection timeout will
785789
overrule the `timeout` option ([the default in Linux is around 20 seconds](http://www.sekuda.com/overriding_the_default_linux_kernel_20_second_tcp_socket_connect_timeout)).
790+
791+
---
792+
786793
- `localAddress` - Local interface to bind for network connections.
787794
- `proxy` - An HTTP proxy to be used. Supports proxy Auth with Basic Auth, identical to support for the `url` parameter (by embedding the auth info in the `uri`)
788795
- `strictSSL` - If `true`, requires SSL certificates be valid. **Note:** to use your own certificate authority, you need to specify an agent that was created with that CA as an option.
789-
- `agentOptions` - Object containing user agent options. See documentation above. **Note:** [see tls API doc for TLS/SSL options](http://nodejs.org/api/tls.html#tls_tls_connect_options_callback).
790796
- `tunnel` - controls the behavior of
791797
[HTTP `CONNECT` tunneling](https://en.wikipedia.org/wiki/HTTP_tunnel#HTTP_CONNECT_tunneling)
792798
as follows:
@@ -803,9 +809,6 @@ The first argument can be either a `url` or an `options` object. The only requir
803809
---
804810

805811
- `time` - If `true`, the request-response cycle (including all redirects) is timed at millisecond resolution, and the result provided on the response's `elapsedTime` property.
806-
807-
---
808-
809812
- `har` - A [HAR 1.2 Request Object](http://www.softwareishard.com/blog/har-12-spec/#request), will be processed from HAR format into options overwriting matching values *(see the [HAR 1.2 section](#support-for-har-1.2) for details)*
810813

811814
The callback argument gets 3 arguments:

‎lib/helpers.js‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,11 +54,21 @@ function copy (obj) {
5454
return o
5555
}
5656

57+
function version () {
58+
var numbers = process.version.replace('v', '').split('.')
59+
return {
60+
major: parseInt(numbers[0], 10),
61+
minor: parseInt(numbers[1], 10),
62+
patch: parseInt(numbers[2], 10)
63+
}
64+
}
65+
5766
exports.isFunction = isFunction
5867
exports.paramsHaveRequestBody = paramsHaveRequestBody
5968
exports.safeStringify = safeStringify
6069
exports.md5 = md5
6170
exports.isReadStream = isReadStream
6271
exports.toBase64 = toBase64
6372
exports.copy = copy
73+
exports.version = version
6474
exports.defer = deferMethod()

‎request.js‎

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@ var safeStringify = helpers.safeStringify
3131
, toBase64 = helpers.toBase64
3232
, defer = helpers.defer
3333
, copy = helpers.copy
34+
, version = helpers.version
3435
, globalCookieJar = cookies.jar()
3536

3637

@@ -477,7 +478,17 @@ Request.prototype.init = function (options) {
477478
if (options.agentClass) {
478479
self.agentClass = options.agentClass
479480
} else if (options.forever) {
480-
self.agentClass = protocol === 'http:' ? ForeverAgent : ForeverAgent.SSL
481+
var v = version()
482+
// use ForeverAgent in node 0.10- only
483+
if (v.major === 0 && v.minor <= 10) {
484+
self.agentClass = protocol === 'http:' ? ForeverAgent : ForeverAgent.SSL
485+
} else {
486+
console.warn('The forever option defaults to using http(s).Agent in 0.12+')
487+
self.agent = new self.httpModule.Agent({
488+
keepAlive: true,
489+
maxSockets: (options.pool && options.pool.maxSockets) || Infinity
490+
})
491+
}
481492
} else {
482493
self.agentClass = self.httpModule.Agent
483494
}

‎tests/test-agent.js‎

Lines changed: 84 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,103 @@
11
'use strict'
22

33
var request = require('../index')
4-
, http = require('http')
5-
, tape = require('tape')
4+
, version = require('../lib/helpers').version
5+
, http = require('http')
6+
, ForeverAgent = require('forever-agent')
7+
, tape = require('tape')
68

7-
var s = http.createServer(function(req, res) {
9+
var s = http.createServer(function (req, res) {
810
res.statusCode = 200
9-
res.end('ok')
11+
res.end()
1012
})
1113

12-
tape('setup', function(t) {
14+
tape('setup', function (t) {
1315
s.listen(6767, function() {
1416
t.end()
1517
})
1618
})
1719

18-
tape('should work with forever agent', function(t) {
19-
var r = request.forever({maxSockets: 1})
20+
function httpAgent (t, options, req) {
21+
var r = (req || request)(options, function (_err, res, body) {
2022

21-
r({
22-
url: 'http://localhost:6767',
23-
headers: { 'Connection':'Close' }
24-
}, function(err, resp, body) {
25-
t.equal(err, null)
26-
t.equal(body, 'ok')
27-
t.end()
23+
t.ok(r.agent instanceof http.Agent, 'is http.Agent')
24+
t.equal(r.agent.options.keepAlive, true, 'is keepAlive')
25+
t.equal(Object.keys(r.agent.sockets).length, 1, '1 socket name')
26+
27+
var name = (typeof r.agent.getName === 'function')
28+
? r.agent.getName({port:6767})
29+
: 'localhost:6767' // node 0.10-
30+
t.equal(r.agent.sockets[name].length, 1, '1 open socket')
31+
32+
var socket = r.agent.sockets[name][0]
33+
socket.on('close', function () {
34+
t.equal(Object.keys(r.agent.sockets).length, 0, '0 open sockets')
35+
t.end()
36+
})
37+
socket.end()
38+
})
39+
}
40+
41+
function foreverAgent (t, options, req) {
42+
var r = (req || request)(options, function (_err, res, body) {
43+
44+
t.ok(r.agent instanceof ForeverAgent, 'is ForeverAgent')
45+
t.equal(Object.keys(r.agent.sockets).length, 1, '1 socket name')
46+
47+
var name = 'localhost:6767' // node 0.10-
48+
t.equal(r.agent.sockets[name].length, 1, '1 open socket')
49+
50+
var socket = r.agent.sockets[name][0]
51+
socket.on('close', function () {
52+
t.equal(Object.keys(r.agent.sockets[name]).length, 0, '0 open sockets')
53+
t.end()
54+
})
55+
socket.end()
56+
})
57+
}
58+
59+
// http.Agent
60+
61+
tape('options.agent', function (t) {
62+
httpAgent(t, {
63+
uri: 'http://localhost:6767',
64+
agent: new http.Agent({keepAlive: true})
2865
})
2966
})
3067

31-
tape('cleanup', function(t) {
68+
tape('options.agentClass + options.agentOptions', function (t) {
69+
httpAgent(t, {
70+
uri: 'http://localhost:6767',
71+
agentClass: http.Agent,
72+
agentOptions: {keepAlive: true}
73+
})
74+
})
75+
76+
// forever-agent
77+
78+
tape('options.forever = true', function (t) {
79+
var v = version()
80+
var options = {
81+
uri: 'http://localhost:6767',
82+
forever: true
83+
}
84+
85+
if (v.major === 0 && v.minor <= 10) {foreverAgent(t, options)}
86+
else {httpAgent(t, options)}
87+
})
88+
89+
tape('forever() method', function (t) {
90+
var v = version()
91+
var options = {
92+
uri: 'http://localhost:6767'
93+
}
94+
var r = request.forever({maxSockets: 1})
95+
96+
if (v.major === 0 && v.minor <= 10) {foreverAgent(t, options, r)}
97+
else {httpAgent(t, options, r)}
98+
})
99+
100+
tape('cleanup', function (t) {
32101
s.close(function() {
33102
t.end()
34103
})

0 commit comments

Comments
 (0)