Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions packages/integration-sdk-http-client/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,8 @@
"@jupiterone/integration-sdk-core": "^17.0.2",
"@lifeomic/attempt": "^3.0.3",
"form-data": "^4.0.0",
"http-proxy-agent": "^7.0.2",
"https-proxy-agent": "^7.0.6",
"lodash": "^4.17.21",
"node-fetch": "^2.7.0"
},
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,39 @@ describe('APIClient', () => {
expect(spy).not.toHaveBeenCalled();
});

it('should use HTTP_PROXY environment variable if set', async () => {
process.env.HTTP_PROXY = 'http://proxy.example.com:8080';

authHeadersFn.mockReturnValue({
Authorization: 'Bearer test-token',
});
const mockResponse = {} as Response;
(fetch as unknown as jest.Mock).mockResolvedValue(mockResponse);

const client = new MockAPIClient({
baseUrl: 'https://api.example.com',
logger: mockLogger,
integrationConfig: {},
});

await (client as any).request('/test', {
method: 'GET',
body: { test: 'test' },
});

// Check that fetch was called with an agent that is a HttpsProxyAgent and has the correct proxy URL
const fetchOptions = (fetch as unknown as jest.Mock).mock.calls[0][1];
const { HttpsProxyAgent } = require('https-proxy-agent');
expect(fetchOptions.agent).toBeInstanceOf(HttpsProxyAgent);
expect(
fetchOptions.agent.proxy?.href ||
fetchOptions.agent.options?.proxy?.href ||
fetchOptions.agent.options?.url, // fallback for some versions
).toContain('http://proxy.example.com:8080');

delete process.env.HTTP_PROXY;
});

describe('fmtBody', () => {
test('should format body as JSON string when bodyType is json', async () => {
const mockResponse = {} as Response;
Expand Down Expand Up @@ -564,6 +597,4 @@ describe('APIClient', () => {
);
});
});

// Add more test cases for other methods as needed
});
19 changes: 18 additions & 1 deletion packages/integration-sdk-http-client/src/client.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { join as joinPath } from 'node:path/posix';
import fetch, { Headers, Response } from 'node-fetch';
import { HttpsProxyAgent } from 'https-proxy-agent';
import {
IntegrationError,
IntegrationInstanceConfig,
Expand Down Expand Up @@ -274,6 +275,22 @@ export abstract class BaseAPIClient {
fmtBody = JSON.stringify(body);
}
}

// Proxy agent logic
const proxy = process.env.HTTPS_PROXY || process.env.HTTP_PROXY;
let finalAgent: Agent | undefined;
if (proxy) {
// If an agent is provided, wrap it with the proxy agent
finalAgent = new HttpsProxyAgent(proxy);
// If a custom agent is provided, set it as the 'secureProxy' option for HttpsProxyAgent
if (agent) {
// @ts-expect-error: HttpsProxyAgent accepts 'secureProxy' in its options
finalAgent.options = { ...finalAgent.options, secureProxy: agent };
}
} else {
finalAgent = agent ?? this.internalGetDefaultAgent();
}

const response = await fetch(url, {
method,
headers: {
Expand All @@ -288,7 +305,7 @@ export abstract class BaseAPIClient {
...headers,
},
body: fmtBody,
agent: agent ?? this.internalGetDefaultAgent(),
agent: finalAgent,
});
return response;
}
Expand Down