Skip to content

Commit fb365c9

Browse files
committed
Custom http agent support (#810)
1 parent bbd6b5a commit fb365c9

File tree

5 files changed

+82
-16
lines changed

5 files changed

+82
-16
lines changed

docs/configuration.asciidoc

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,20 @@ _Default:_ `false`
9090
_Default:_ `null`
9191

9292
|`agent`
93-
|`http.AgentOptions` - http agent https://nodejs.org/api/http.html#http_new_agent_options[options]. +
93+
a|`http.AgentOptions, function` - http agent https://nodejs.org/api/http.html#http_new_agent_options[options], or a function that returns an actual http agent instance. +
9494
_Default:_ `null`
95+
[source,js]
96+
----
97+
const client = new Client({
98+
node: 'http://localhost:9200',
99+
agent: { agent: 'options' }
100+
})
101+
102+
const client = new Client({
103+
node: 'http://localhost:9200',
104+
agent: () => new CustomAgent()
105+
})
106+
----
95107

96108
|`nodeFilter`
97109
a|`function` - Filters which node not to use for a request. +

index.d.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ import Transport, {
2929
nodeFilterFn,
3030
nodeSelectorFn
3131
} from './lib/Transport';
32-
import Connection, { AgentOptions } from './lib/Connection';
32+
import Connection, { AgentOptions, agentFn } from './lib/Connection';
3333
import ConnectionPool, { ResurrectEvent } from './lib/ConnectionPool';
3434
import Serializer from './lib/Serializer';
3535
import * as RequestParams from './api/requestParams';
@@ -82,7 +82,7 @@ interface ClientOptions {
8282
suggestCompression?: boolean;
8383
compression?: 'gzip';
8484
ssl?: SecureContextOptions;
85-
agent?: AgentOptions;
85+
agent?: AgentOptions | agentFn;
8686
nodeFilter?: nodeFilterFn;
8787
nodeSelector?: nodeSelectorFn | string;
8888
headers?: anyObject;

lib/Connection.d.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,14 @@ import { inspect, InspectOptions } from 'util';
2424
import * as http from 'http';
2525
import { SecureContextOptions } from 'tls';
2626

27+
export declare type agentFn = () => any;
28+
2729
interface ConnectionOptions {
2830
url: URL;
2931
ssl?: SecureContextOptions;
3032
id?: string;
3133
headers?: any;
32-
agent?: AgentOptions;
34+
agent?: AgentOptions | agentFn;
3335
status?: string;
3436
roles?: any;
3537
}

lib/Connection.js

Lines changed: 14 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -46,18 +46,20 @@ class Connection {
4646
throw new ConfigurationError(`Invalid protocol: '${this.url.protocol}'`)
4747
}
4848

49-
// Probably there is a bug in Node Core
50-
// see https://github.com/nodejs/node/issues/26357
51-
const keepAliveFalse = opts.agent && opts.agent.keepAlive === false
52-
const agentOptions = Object.assign({}, {
53-
keepAlive: true,
54-
keepAliveMsecs: 1000,
55-
maxSockets: keepAliveFalse ? Infinity : 256,
56-
maxFreeSockets: 256
57-
}, opts.agent)
58-
this.agent = this.url.protocol === 'http:'
59-
? new http.Agent(agentOptions)
60-
: new https.Agent(Object.assign({}, agentOptions, this.ssl))
49+
if (typeof opts.agent === 'function') {
50+
this.agent = opts.agent()
51+
} else {
52+
const keepAliveFalse = opts.agent && opts.agent.keepAlive === false
53+
const agentOptions = Object.assign({}, {
54+
keepAlive: true,
55+
keepAliveMsecs: 1000,
56+
maxSockets: keepAliveFalse ? Infinity : 256,
57+
maxFreeSockets: 256
58+
}, opts.agent)
59+
this.agent = this.url.protocol === 'http:'
60+
? new http.Agent(agentOptions)
61+
: new https.Agent(Object.assign({}, agentOptions, this.ssl))
62+
}
6163

6264
this.makeRequest = this.url.protocol === 'http:'
6365
? http.request

test/unit/connection.test.js

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ const { test } = require('tap')
2323
const { inspect } = require('util')
2424
const { createGzip, createDeflate } = require('zlib')
2525
const { URL } = require('url')
26+
const { Agent } = require('http')
2627
const intoStream = require('into-stream')
2728
const { buildServer } = require('../utils')
2829
const Connection = require('../../lib/Connection')
@@ -149,6 +150,55 @@ test('Basic (https with ssl agent)', t => {
149150
})
150151
})
151152

153+
test('Custom http agent', t => {
154+
t.plan(5)
155+
156+
function handler (req, res) {
157+
t.match(req.headers, {
158+
'x-custom-test': 'true',
159+
connection: 'keep-alive'
160+
})
161+
res.end('ok')
162+
}
163+
164+
buildServer(handler, ({ port }, server) => {
165+
const agent = new Agent({
166+
keepAlive: true,
167+
keepAliveMsecs: 1000,
168+
maxSockets: 256,
169+
maxFreeSockets: 256
170+
})
171+
agent.custom = true
172+
const connection = new Connection({
173+
url: new URL(`http://localhost:${port}`),
174+
agent: () => agent
175+
})
176+
t.true(connection.agent.custom)
177+
connection.request({
178+
path: '/hello',
179+
method: 'GET',
180+
headers: {
181+
'X-Custom-Test': true
182+
}
183+
}, (err, res) => {
184+
t.error(err)
185+
186+
t.match(res.headers, {
187+
connection: 'keep-alive'
188+
})
189+
190+
var payload = ''
191+
res.setEncoding('utf8')
192+
res.on('data', chunk => { payload += chunk })
193+
res.on('error', err => t.fail(err))
194+
res.on('end', () => {
195+
t.strictEqual(payload, 'ok')
196+
server.stop()
197+
})
198+
})
199+
})
200+
})
201+
152202
test('Disable keep alive', t => {
153203
t.plan(3)
154204

0 commit comments

Comments
 (0)