Custom http agent support (#810)

This commit is contained in:
Tomas Della Vedova
2019-04-10 11:13:22 +02:00
committed by delvedor
parent bbd6b5a546
commit fb365c9adf
5 changed files with 82 additions and 16 deletions

View File

@ -90,8 +90,20 @@ _Default:_ `false`
_Default:_ `null`
|`agent`
|`http.AgentOptions` - http agent https://nodejs.org/api/http.html#http_new_agent_options[options]. +
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. +
_Default:_ `null`
[source,js]
----
const client = new Client({
node: 'http://localhost:9200',
agent: { agent: 'options' }
})
const client = new Client({
node: 'http://localhost:9200',
agent: () => new CustomAgent()
})
----
|`nodeFilter`
a|`function` - Filters which node not to use for a request. +

4
index.d.ts vendored
View File

@ -29,7 +29,7 @@ import Transport, {
nodeFilterFn,
nodeSelectorFn
} from './lib/Transport';
import Connection, { AgentOptions } from './lib/Connection';
import Connection, { AgentOptions, agentFn } from './lib/Connection';
import ConnectionPool, { ResurrectEvent } from './lib/ConnectionPool';
import Serializer from './lib/Serializer';
import * as RequestParams from './api/requestParams';
@ -82,7 +82,7 @@ interface ClientOptions {
suggestCompression?: boolean;
compression?: 'gzip';
ssl?: SecureContextOptions;
agent?: AgentOptions;
agent?: AgentOptions | agentFn;
nodeFilter?: nodeFilterFn;
nodeSelector?: nodeSelectorFn | string;
headers?: anyObject;

4
lib/Connection.d.ts vendored
View File

@ -24,12 +24,14 @@ import { inspect, InspectOptions } from 'util';
import * as http from 'http';
import { SecureContextOptions } from 'tls';
export declare type agentFn = () => any;
interface ConnectionOptions {
url: URL;
ssl?: SecureContextOptions;
id?: string;
headers?: any;
agent?: AgentOptions;
agent?: AgentOptions | agentFn;
status?: string;
roles?: any;
}

View File

@ -46,18 +46,20 @@ class Connection {
throw new ConfigurationError(`Invalid protocol: '${this.url.protocol}'`)
}
// Probably there is a bug in Node Core
// see https://github.com/nodejs/node/issues/26357
const keepAliveFalse = opts.agent && opts.agent.keepAlive === false
const agentOptions = Object.assign({}, {
keepAlive: true,
keepAliveMsecs: 1000,
maxSockets: keepAliveFalse ? Infinity : 256,
maxFreeSockets: 256
}, opts.agent)
this.agent = this.url.protocol === 'http:'
? new http.Agent(agentOptions)
: new https.Agent(Object.assign({}, agentOptions, this.ssl))
if (typeof opts.agent === 'function') {
this.agent = opts.agent()
} else {
const keepAliveFalse = opts.agent && opts.agent.keepAlive === false
const agentOptions = Object.assign({}, {
keepAlive: true,
keepAliveMsecs: 1000,
maxSockets: keepAliveFalse ? Infinity : 256,
maxFreeSockets: 256
}, opts.agent)
this.agent = this.url.protocol === 'http:'
? new http.Agent(agentOptions)
: new https.Agent(Object.assign({}, agentOptions, this.ssl))
}
this.makeRequest = this.url.protocol === 'http:'
? http.request

View File

@ -23,6 +23,7 @@ const { test } = require('tap')
const { inspect } = require('util')
const { createGzip, createDeflate } = require('zlib')
const { URL } = require('url')
const { Agent } = require('http')
const intoStream = require('into-stream')
const { buildServer } = require('../utils')
const Connection = require('../../lib/Connection')
@ -149,6 +150,55 @@ test('Basic (https with ssl agent)', t => {
})
})
test('Custom http agent', t => {
t.plan(5)
function handler (req, res) {
t.match(req.headers, {
'x-custom-test': 'true',
connection: 'keep-alive'
})
res.end('ok')
}
buildServer(handler, ({ port }, server) => {
const agent = new Agent({
keepAlive: true,
keepAliveMsecs: 1000,
maxSockets: 256,
maxFreeSockets: 256
})
agent.custom = true
const connection = new Connection({
url: new URL(`http://localhost:${port}`),
agent: () => agent
})
t.true(connection.agent.custom)
connection.request({
path: '/hello',
method: 'GET',
headers: {
'X-Custom-Test': true
}
}, (err, res) => {
t.error(err)
t.match(res.headers, {
connection: 'keep-alive'
})
var payload = ''
res.setEncoding('utf8')
res.on('data', chunk => { payload += chunk })
res.on('error', err => t.fail(err))
res.on('end', () => {
t.strictEqual(payload, 'ok')
server.stop()
})
})
})
})
test('Disable keep alive', t => {
t.plan(3)