From 93600b5da85824858a065e831d615887d700e787 Mon Sep 17 00:00:00 2001 From: lohit-bruno Date: Tue, 3 Mar 2026 09:27:31 +0530 Subject: [PATCH] refactor(agent-cache): use named props for getOrCreateAgent and getOrCreateHttpAgent --- .../src/runner/run-single-request.js | 16 ++--- .../bruno-electron/src/utils/proxy-util.js | 16 ++--- .../src/utils/agent-cache.spec.ts | 64 +++++++++---------- .../bruno-requests/src/utils/agent-cache.ts | 54 ++++++++-------- .../src/utils/http-https-agents.ts | 18 +++--- 5 files changed, 85 insertions(+), 83 deletions(-) diff --git a/packages/bruno-cli/src/runner/run-single-request.js b/packages/bruno-cli/src/runner/run-single-request.js index eb635fdce..01923c5c3 100644 --- a/packages/bruno-cli/src/runner/run-single-request.js +++ b/packages/bruno-cli/src/runner/run-single-request.js @@ -459,15 +459,15 @@ const runSingleRequest = async function ( // Only set the agent needed for the request protocol if (socksEnabled) { if (isHttpsRequest) { - request.httpsAgent = getOrCreateAgent(SocksProxyAgent, tlsOptions, proxyUri); + request.httpsAgent = getOrCreateAgent({ AgentClass: SocksProxyAgent, options: tlsOptions, proxyUri }); } else { - request.httpAgent = getOrCreateHttpAgent(SocksProxyAgent, httpAgentOptions, proxyUri); + request.httpAgent = getOrCreateHttpAgent({ AgentClass: SocksProxyAgent, options: httpAgentOptions, proxyUri }); } } else { if (isHttpsRequest) { - request.httpsAgent = getOrCreateAgent(PatchedHttpsProxyAgent, tlsOptions, proxyUri); + request.httpsAgent = getOrCreateAgent({ AgentClass: PatchedHttpsProxyAgent, options: tlsOptions, proxyUri }); } else { - request.httpAgent = getOrCreateHttpAgent(HttpProxyAgent, httpAgentOptions, proxyUri); + request.httpAgent = getOrCreateHttpAgent({ AgentClass: HttpProxyAgent, options: httpAgentOptions, proxyUri }); } } } @@ -479,7 +479,7 @@ const runSingleRequest = async function ( try { if (http_proxy?.length && !isHttpsRequest) { new URL(http_proxy); - request.httpAgent = getOrCreateHttpAgent(HttpProxyAgent, httpAgentOptions, http_proxy); + request.httpAgent = getOrCreateHttpAgent({ AgentClass: HttpProxyAgent, options: httpAgentOptions, proxyUri: http_proxy }); } } catch (error) { throw new Error('Invalid system http_proxy'); @@ -487,7 +487,7 @@ const runSingleRequest = async function ( try { if (https_proxy?.length && isHttpsRequest) { new URL(https_proxy); - request.httpsAgent = getOrCreateAgent(PatchedHttpsProxyAgent, tlsOptions, https_proxy); + request.httpsAgent = getOrCreateAgent({ AgentClass: PatchedHttpsProxyAgent, options: tlsOptions, proxyUri: https_proxy }); } } catch (error) { throw new Error('Invalid system https_proxy'); @@ -501,9 +501,9 @@ const runSingleRequest = async function ( if (!request.httpAgent && !request.httpsAgent) { if (isHttpsRequest) { - request.httpsAgent = getOrCreateAgent(https.Agent, tlsOptions, null); + request.httpsAgent = getOrCreateAgent({ AgentClass: https.Agent, options: tlsOptions }); } else { - request.httpAgent = getOrCreateHttpAgent(http.Agent, httpAgentOptions, null); + request.httpAgent = getOrCreateHttpAgent({ AgentClass: http.Agent, options: httpAgentOptions }); } } diff --git a/packages/bruno-electron/src/utils/proxy-util.js b/packages/bruno-electron/src/utils/proxy-util.js index 8b6ecea0e..0b63c5dde 100644 --- a/packages/bruno-electron/src/utils/proxy-util.js +++ b/packages/bruno-electron/src/utils/proxy-util.js @@ -142,15 +142,15 @@ function setupProxyAgents({ // Only set the agent needed for the request protocol if (socksEnabled) { if (isHttpsRequest) { - requestConfig.httpsAgent = getOrCreateAgent(SocksProxyAgent, tlsOptions, proxyUri, timeline, disableCache); + requestConfig.httpsAgent = getOrCreateAgent({ AgentClass: SocksProxyAgent, options: tlsOptions, proxyUri, timeline, disableCache }); } else { - requestConfig.httpAgent = getOrCreateHttpAgent(SocksProxyAgent, { keepAlive: true }, proxyUri, timeline, disableCache); + requestConfig.httpAgent = getOrCreateHttpAgent({ AgentClass: SocksProxyAgent, options: { keepAlive: true }, proxyUri, timeline, disableCache }); } } else { if (isHttpsRequest) { - requestConfig.httpsAgent = getOrCreateAgent(PatchedHttpsProxyAgent, tlsOptions, proxyUri, timeline, disableCache); + requestConfig.httpsAgent = getOrCreateAgent({ AgentClass: PatchedHttpsProxyAgent, options: tlsOptions, proxyUri, timeline, disableCache }); } else { - requestConfig.httpAgent = getOrCreateHttpAgent(HttpProxyAgent, { keepAlive: true }, proxyUri, timeline, disableCache); + requestConfig.httpAgent = getOrCreateHttpAgent({ AgentClass: HttpProxyAgent, options: { keepAlive: true }, proxyUri, timeline, disableCache }); } } } @@ -168,7 +168,7 @@ function setupProxyAgents({ message: `Using system proxy: ${http_proxy}` }); } - requestConfig.httpAgent = getOrCreateHttpAgent(HttpProxyAgent, { keepAlive: true }, http_proxy, timeline, disableCache); + requestConfig.httpAgent = getOrCreateHttpAgent({ AgentClass: HttpProxyAgent, options: { keepAlive: true }, proxyUri: http_proxy, timeline, disableCache }); } } catch (error) { throw new Error(`Invalid system http_proxy "${http_proxy}": ${error.message}`); @@ -183,7 +183,7 @@ function setupProxyAgents({ message: `Using system proxy: ${https_proxy}` }); } - requestConfig.httpsAgent = getOrCreateAgent(PatchedHttpsProxyAgent, tlsOptions, https_proxy, timeline, disableCache); + requestConfig.httpsAgent = getOrCreateAgent({ AgentClass: PatchedHttpsProxyAgent, options: tlsOptions, proxyUri: https_proxy, timeline, disableCache }); } } catch (error) { throw new Error(`Invalid system https_proxy "${https_proxy}": ${error.message}`); @@ -193,9 +193,9 @@ function setupProxyAgents({ if (!requestConfig.httpAgent && !requestConfig.httpsAgent) { if (isHttpsRequest) { - requestConfig.httpsAgent = getOrCreateAgent(https.Agent, tlsOptions, null, timeline, disableCache); + requestConfig.httpsAgent = getOrCreateAgent({ AgentClass: https.Agent, options: tlsOptions, proxyUri: null, timeline, disableCache }); } else { - requestConfig.httpAgent = getOrCreateHttpAgent(http.Agent, { keepAlive: true }, null, timeline, disableCache); + requestConfig.httpAgent = getOrCreateHttpAgent({ AgentClass: http.Agent, options: { keepAlive: true }, proxyUri: null, timeline, disableCache }); } } } diff --git a/packages/bruno-requests/src/utils/agent-cache.spec.ts b/packages/bruno-requests/src/utils/agent-cache.spec.ts index 443039d56..871c41156 100644 --- a/packages/bruno-requests/src/utils/agent-cache.spec.ts +++ b/packages/bruno-requests/src/utils/agent-cache.spec.ts @@ -10,7 +10,7 @@ describe('Agent Cache', () => { describe('getOrCreateAgent', () => { it('creates a new agent when cache is empty', () => { - const agent = getOrCreateAgent(https.Agent, { rejectUnauthorized: true }); + const agent = getOrCreateAgent({ AgentClass: https.Agent, options: { rejectUnauthorized: true } }); expect(agent).toBeInstanceOf(https.Agent); expect(getAgentCacheSize()).toBe(1); @@ -19,24 +19,24 @@ describe('Agent Cache', () => { it('returns cached agent for identical options', () => { const options = { rejectUnauthorized: true, keepAlive: true }; - const agent1 = getOrCreateAgent(https.Agent, options); - const agent2 = getOrCreateAgent(https.Agent, options); + const agent1 = getOrCreateAgent({ AgentClass: https.Agent, options }); + const agent2 = getOrCreateAgent({ AgentClass: https.Agent, options }); expect(agent1).toBe(agent2); expect(getAgentCacheSize()).toBe(1); }); it('creates separate agents for different rejectUnauthorized values', () => { - const agent1 = getOrCreateAgent(https.Agent, { rejectUnauthorized: true }); - const agent2 = getOrCreateAgent(https.Agent, { rejectUnauthorized: false }); + const agent1 = getOrCreateAgent({ AgentClass: https.Agent, options: { rejectUnauthorized: true } }); + const agent2 = getOrCreateAgent({ AgentClass: https.Agent, options: { rejectUnauthorized: false } }); expect(agent1).not.toBe(agent2); expect(getAgentCacheSize()).toBe(2); }); it('creates separate agents for different CA certificates', () => { - const agent1 = getOrCreateAgent(https.Agent, { ca: 'cert-a' }); - const agent2 = getOrCreateAgent(https.Agent, { ca: 'cert-b' }); + const agent1 = getOrCreateAgent({ AgentClass: https.Agent, options: { ca: 'cert-a' } }); + const agent2 = getOrCreateAgent({ AgentClass: https.Agent, options: { ca: 'cert-b' } }); expect(agent1).not.toBe(agent2); expect(getAgentCacheSize()).toBe(2); @@ -45,8 +45,8 @@ describe('Agent Cache', () => { it('creates separate agents for different proxy URIs', () => { const options = { rejectUnauthorized: true }; - const agent1 = getOrCreateAgent(https.Agent, options, 'http://proxy1:8080'); - const agent2 = getOrCreateAgent(https.Agent, options, 'http://proxy2:8080'); + const agent1 = getOrCreateAgent({ AgentClass: https.Agent, options, proxyUri: 'http://proxy1:8080' }); + const agent2 = getOrCreateAgent({ AgentClass: https.Agent, options, proxyUri: 'http://proxy2:8080' }); expect(agent1).not.toBe(agent2); expect(getAgentCacheSize()).toBe(2); @@ -55,16 +55,16 @@ describe('Agent Cache', () => { it('creates separate agents for different agent classes', () => { const options = { keepAlive: true }; - const httpsAgent = getOrCreateAgent(https.Agent, options); - const httpAgent = getOrCreateAgent(http.Agent, options); + const httpsAgent = getOrCreateAgent({ AgentClass: https.Agent, options }); + const httpAgent = getOrCreateAgent({ AgentClass: http.Agent, options }); expect(httpsAgent).not.toBe(httpAgent); expect(getAgentCacheSize()).toBe(2); }); it('creates separate agents for different keepAlive values', () => { - const agent1 = getOrCreateAgent(https.Agent, { keepAlive: true }); - const agent2 = getOrCreateAgent(https.Agent, { keepAlive: false }); + const agent1 = getOrCreateAgent({ AgentClass: https.Agent, options: { keepAlive: true } }); + const agent2 = getOrCreateAgent({ AgentClass: https.Agent, options: { keepAlive: false } }); expect(agent1).not.toBe(agent2); expect(getAgentCacheSize()).toBe(2); @@ -73,14 +73,14 @@ describe('Agent Cache', () => { describe('timeline support', () => { it('initializes timeline array on new agents', () => { - const agent = getOrCreateAgent(https.Agent, {}) as any; + const agent = getOrCreateAgent({ AgentClass: https.Agent, options: {} }) as any; expect(Array.isArray(agent.timeline)).toBe(true); }); it('uses provided timeline array', () => { const timeline: any[] = []; - const agent = getOrCreateAgent(https.Agent, {}, null, timeline) as any; + const agent = getOrCreateAgent({ AgentClass: https.Agent, options: {}, timeline }) as any; expect(agent.timeline).toBe(timeline); }); @@ -89,10 +89,10 @@ describe('Agent Cache', () => { const timeline1: any[] = []; const timeline2: any[] = []; - const agent1 = getOrCreateAgent(https.Agent, {}, null, timeline1) as any; + const agent1 = getOrCreateAgent({ AgentClass: https.Agent, options: {}, timeline: timeline1 }) as any; expect(agent1.timeline).toBe(timeline1); - const agent2 = getOrCreateAgent(https.Agent, {}, null, timeline2) as any; + const agent2 = getOrCreateAgent({ AgentClass: https.Agent, options: {}, timeline: timeline2 }) as any; expect(agent1).toBe(agent2); expect(agent2.timeline).toBe(timeline2); }); @@ -102,11 +102,11 @@ describe('Agent Cache', () => { const timeline2: any[] = []; // First call creates new agent - no reuse message - getOrCreateAgent(https.Agent, {}, null, timeline1); + getOrCreateAgent({ AgentClass: https.Agent, options: {}, timeline: timeline1 }); expect(timeline1.some((e) => e.message.includes('Reusing cached agent'))).toBe(false); // Second call reuses cached agent - should log reuse message with SSL session reuse - getOrCreateAgent(https.Agent, {}, null, timeline2); + getOrCreateAgent({ AgentClass: https.Agent, options: {}, timeline: timeline2 }); expect(timeline2.some((e) => e.message.includes('Reusing cached agent'))).toBe(true); expect(timeline2.some((e) => e.message.includes('SSL session reuse'))).toBe(true); }); @@ -116,18 +116,18 @@ describe('Agent Cache', () => { const timeline2: any[] = []; // First call creates new agent - no reuse message - getOrCreateHttpAgent(http.Agent, { keepAlive: true }, null, timeline1); + getOrCreateHttpAgent({ AgentClass: http.Agent, options: { keepAlive: true }, timeline: timeline1 }); expect(timeline1.some((e) => e.message.includes('Reusing cached agent'))).toBe(false); // Second call reuses cached agent - should log reuse message with connection reuse - getOrCreateHttpAgent(http.Agent, { keepAlive: true }, null, timeline2); + getOrCreateHttpAgent({ AgentClass: http.Agent, options: { keepAlive: true }, timeline: timeline2 }); expect(timeline2.some((e) => e.message.includes('Reusing cached agent'))).toBe(true); expect(timeline2.some((e) => e.message.includes('connection reuse'))).toBe(true); }); it('logs SSL validation status on agent creation', () => { const timeline: any[] = []; - getOrCreateAgent(https.Agent, { rejectUnauthorized: true }, null, timeline); + getOrCreateAgent({ AgentClass: https.Agent, options: { rejectUnauthorized: true }, timeline }); const sslEntry = timeline.find((e) => e.message.includes('SSL validation')); expect(sslEntry).toBeDefined(); @@ -136,7 +136,7 @@ describe('Agent Cache', () => { it('logs SSL validation disabled when rejectUnauthorized is false', () => { const timeline: any[] = []; - getOrCreateAgent(https.Agent, { rejectUnauthorized: false }, null, timeline); + getOrCreateAgent({ AgentClass: https.Agent, options: { rejectUnauthorized: false }, timeline }); const sslEntry = timeline.find((e) => e.message.includes('SSL validation')); expect(sslEntry).toBeDefined(); @@ -146,8 +146,8 @@ describe('Agent Cache', () => { describe('clearAgentCache', () => { it('removes all cached agents', () => { - getOrCreateAgent(https.Agent, { rejectUnauthorized: true }); - getOrCreateAgent(https.Agent, { rejectUnauthorized: false }); + getOrCreateAgent({ AgentClass: https.Agent, options: { rejectUnauthorized: true } }); + getOrCreateAgent({ AgentClass: https.Agent, options: { rejectUnauthorized: false } }); expect(getAgentCacheSize()).toBe(2); clearAgentCache(); @@ -159,7 +159,7 @@ describe('Agent Cache', () => { // Create several agents and attach mock destroy functions for (let i = 0; i < 5; i++) { - const agent = getOrCreateAgent(https.Agent, { ca: `cert-${i}` }) as any; + const agent = getOrCreateAgent({ AgentClass: https.Agent, options: { ca: `cert-${i}` } }) as any; const mock = jest.fn(); agent.destroy = mock; destroyMocks.push(mock); @@ -181,7 +181,7 @@ describe('Agent Cache', () => { it('maintains cache size under limit', () => { // Create many agents with different options for (let i = 0; i < 150; i++) { - getOrCreateAgent(https.Agent, { ca: `cert-${i}` }); + getOrCreateAgent({ AgentClass: https.Agent, options: { ca: `cert-${i}` } }); } // Cache should be capped at MAX_AGENT_CACHE_SIZE (100) @@ -190,13 +190,13 @@ describe('Agent Cache', () => { it('destroys evicted agents to prevent memory leaks', () => { // Create first agent and attach a mock destroy function - const firstAgent = getOrCreateAgent(https.Agent, { ca: 'cert-to-evict' }) as any; + const firstAgent = getOrCreateAgent({ AgentClass: https.Agent, options: { ca: 'cert-to-evict' } }) as any; const destroyMock = jest.fn(); firstAgent.destroy = destroyMock; // Fill cache to trigger eviction (100 more agents will evict the first one) for (let i = 0; i < 100; i++) { - getOrCreateAgent(https.Agent, { ca: `cert-${i}` }); + getOrCreateAgent({ AgentClass: https.Agent, options: { ca: `cert-${i}` } }); } // First agent should have been evicted and destroyed @@ -210,8 +210,8 @@ describe('Agent Cache', () => { const timeline2: any[] = []; // Get the same agent twice with different timelines (simulating concurrent requests) - const agent1 = getOrCreateAgent(https.Agent, {}, null, timeline1) as any; - const agent2 = getOrCreateAgent(https.Agent, {}, null, timeline2) as any; + const agent1 = getOrCreateAgent({ AgentClass: https.Agent, options: {}, timeline: timeline1 }) as any; + const agent2 = getOrCreateAgent({ AgentClass: https.Agent, options: {}, timeline: timeline2 }) as any; // Both should return the same cached agent expect(agent1).toBe(agent2); @@ -285,7 +285,7 @@ describe('Agent Cache', () => { const timeline1: any[] = []; const timeline2: any[] = []; - const agent = getOrCreateAgent(https.Agent, {}, null, timeline1) as any; + const agent = getOrCreateAgent({ AgentClass: https.Agent, options: {}, timeline: timeline1 }) as any; // Create a mock socket const mockSocket = new EventEmitter() as any; diff --git a/packages/bruno-requests/src/utils/agent-cache.ts b/packages/bruno-requests/src/utils/agent-cache.ts index ecdf5244f..71f228429 100644 --- a/packages/bruno-requests/src/utils/agent-cache.ts +++ b/packages/bruno-requests/src/utils/agent-cache.ts @@ -217,21 +217,22 @@ function getOrCreateAgentInternal( * Reuses existing agents to enable SSL session caching. * Uses LRU-style eviction when cache exceeds MAX_AGENT_CACHE_SIZE. * Automatically wraps the agent class with timeline logging support. - * - * @param BaseAgentClass - The base agent class (https.Agent, HttpsProxyAgent, etc.) - * @param options - Agent options (TLS settings, etc.) - * @param proxyUri - Proxy URI if using a proxy - * @param timeline - Timeline array for logging TLS events */ -function getOrCreateAgent( - BaseAgentClass: any, - options: AgentOptions, - proxyUri: string | null = null, - timeline: TimelineEntry[] | null = null, - disableCache: boolean = false -): HttpAgent | HttpsAgent { +function getOrCreateAgent({ + AgentClass, + options, + proxyUri = null, + timeline = null, + disableCache = false +}: { + AgentClass: any; + options: AgentOptions; + proxyUri?: string | null; + timeline?: TimelineEntry[] | null; + disableCache?: boolean; +}): HttpAgent | HttpsAgent { return getOrCreateAgentInternal( - BaseAgentClass, + AgentClass, options, proxyUri, timeline, @@ -247,21 +248,22 @@ function getOrCreateAgent( * Reuses existing agents to enable connection reuse. * Uses LRU-style eviction when cache exceeds MAX_AGENT_CACHE_SIZE. * Automatically wraps the agent class with timeline logging support. - * - * @param BaseAgentClass - The base HTTP agent class (http.Agent, HttpProxyAgent, etc.) - * @param options - Agent options - * @param proxyUri - Proxy URI if using a proxy - * @param timeline - Timeline array for logging connection events */ -function getOrCreateHttpAgent( - BaseAgentClass: any, - options: HttpAgentOptions, - proxyUri: string | null = null, - timeline: TimelineEntry[] | null = null, - disableCache: boolean = false -): HttpAgent { +function getOrCreateHttpAgent({ + AgentClass, + options, + proxyUri = null, + timeline = null, + disableCache = false +}: { + AgentClass: any; + options: HttpAgentOptions; + proxyUri?: string | null; + timeline?: TimelineEntry[] | null; + disableCache?: boolean; +}): HttpAgent { return getOrCreateAgentInternal( - BaseAgentClass, + AgentClass, options, proxyUri, timeline, diff --git a/packages/bruno-requests/src/utils/http-https-agents.ts b/packages/bruno-requests/src/utils/http-https-agents.ts index 476490a92..22445e535 100644 --- a/packages/bruno-requests/src/utils/http-https-agents.ts +++ b/packages/bruno-requests/src/utils/http-https-agents.ts @@ -393,21 +393,21 @@ function createAgents({ // Only set the agent needed for the request protocol if (socksEnabled) { if (isHttpsRequest) { - httpsAgent = getOrCreateAgent(SocksProxyAgent, tlsOptions as any, proxyUri, timeline || null) as HttpsAgent; + httpsAgent = getOrCreateAgent({ AgentClass: SocksProxyAgent, options: tlsOptions as any, proxyUri, timeline: timeline || null }) as HttpsAgent; } else { - httpAgent = getOrCreateHttpAgent(SocksProxyAgent, { keepAlive: true }, proxyUri, timeline || null); + httpAgent = getOrCreateHttpAgent({ AgentClass: SocksProxyAgent, options: { keepAlive: true }, proxyUri, timeline: timeline || null }); } } else { if (isHttpsRequest) { - httpsAgent = getOrCreateAgent(PatchedHttpsProxyAgent, tlsOptions as any, proxyUri, timeline || null) as HttpsAgent; + httpsAgent = getOrCreateAgent({ AgentClass: PatchedHttpsProxyAgent, options: tlsOptions as any, proxyUri, timeline: timeline || null }) as HttpsAgent; } else { - httpAgent = getOrCreateHttpAgent(HttpProxyAgent, { keepAlive: true }, proxyUri, timeline || null); + httpAgent = getOrCreateHttpAgent({ AgentClass: HttpProxyAgent, options: { keepAlive: true }, proxyUri, timeline: timeline || null }); } } } else { // If proxy should not be used, only set HTTPS agent for HTTPS requests if (isHttpsRequest) { - httpsAgent = getOrCreateAgent(https.Agent, tlsOptions as any, null, timeline || null) as HttpsAgent; + httpsAgent = getOrCreateAgent({ AgentClass: https.Agent, options: tlsOptions as any, timeline: timeline || null }) as HttpsAgent; } // HTTP requests without proxy don't need a custom agent } @@ -420,7 +420,7 @@ function createAgents({ try { if (http_proxy?.length && !isHttpsRequest) { new URL(http_proxy); - httpAgent = getOrCreateHttpAgent(HttpProxyAgent, { keepAlive: true }, http_proxy, timeline || null); + httpAgent = getOrCreateHttpAgent({ AgentClass: HttpProxyAgent, options: { keepAlive: true }, proxyUri: http_proxy, timeline: timeline || null }); } } catch (error) { throw new Error('Invalid system http_proxy'); @@ -428,7 +428,7 @@ function createAgents({ try { if (https_proxy?.length && isHttpsRequest) { new URL(https_proxy); - httpsAgent = getOrCreateAgent(PatchedHttpsProxyAgent, tlsOptions as any, https_proxy, timeline || null) as HttpsAgent; + httpsAgent = getOrCreateAgent({ AgentClass: PatchedHttpsProxyAgent, options: tlsOptions as any, proxyUri: https_proxy, timeline: timeline || null }) as HttpsAgent; } } catch (error) { throw new Error('Invalid system https_proxy'); @@ -438,9 +438,9 @@ function createAgents({ if (!httpAgent && !httpsAgent) { if (isHttpsRequest) { - httpsAgent = getOrCreateAgent(https.Agent, tlsOptions as any, null, timeline || null) as HttpsAgent; + httpsAgent = getOrCreateAgent({ AgentClass: https.Agent, options: tlsOptions as any, timeline: timeline || null }) as HttpsAgent; } else { - httpAgent = getOrCreateHttpAgent(http.Agent, { keepAlive: true }, null, timeline || null); + httpAgent = getOrCreateHttpAgent({ AgentClass: http.Agent, options: { keepAlive: true }, timeline: timeline || null }); } }