Skip to content

Commit

Permalink
Merge pull request #3348 from snyk/fix/iac-bundle-proxy-support-stream
Browse files Browse the repository at this point in the history
fix: support HTTP(S) proxies in iac-test
  • Loading branch information
Craig Furman authored Jun 22, 2022
2 parents 0804baa + 3ac3ad0 commit 0b90441
Show file tree
Hide file tree
Showing 3 changed files with 55 additions and 11 deletions.
10 changes: 7 additions & 3 deletions src/cli/commands/test/iac/local-execution/local-cache.ts
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
import * as path from 'path';
import * as fs from 'fs';
import { EngineType, IaCErrorCodes } from './types';
import * as needle from 'needle';
import * as rimraf from 'rimraf';
import { createIacDir, extractBundle, isValidBundle } from './file-utils';
import * as Debug from 'debug';
import { CustomError } from '../../../../../lib/errors';
import * as analytics from '../../../../../lib/analytics';
import ReadableStream = NodeJS.ReadableStream;
import { getErrorStringCode } from './error-utils';
import config from '../../../../../lib/config';
import { streamRequest } from '../../../../../lib/request/request';

const debug = Debug('iac-local-cache');

Expand Down Expand Up @@ -141,7 +140,12 @@ export async function initLocalCache({
// always overwrite whatever might be there.
try {
const BUNDLE_URL = 'https://static.snyk.io/cli/wasm/bundle.tar.gz';
const response: ReadableStream = needle.get(BUNDLE_URL);
const response = await streamRequest({
method: 'get',
url: BUNDLE_URL,
body: null,
headers: {},
});
await extractBundle(response);
} catch (e) {
throw new FailedToDownloadRulesError();
Expand Down
39 changes: 36 additions & 3 deletions src/lib/request/request.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,7 @@ const snykDebug = debugModule('snyk');

declare const global: Global;

export async function makeRequest(
payload: Payload,
): Promise<{ res: needle.NeedleResponse; body: any }> {
function setupRequest(payload: Payload) {
// This ensures we support lowercase http(s)_proxy values as well
// The weird IF around it ensures we don't create an envvar with a value of undefined, which throws error when trying to use it as a proxy
if (process.env.HTTP_PROXY || process.env.http_proxy) {
Expand Down Expand Up @@ -129,6 +127,14 @@ export async function makeRequest(
options.rejectUnauthorized = false;
}

return { method, url, data, options };
}

export async function makeRequest(
payload: Payload,
): Promise<{ res: needle.NeedleResponse; body: any }> {
const { method, url, data, options } = setupRequest(payload);

return new Promise((resolve, reject) => {
needle.request(method, url, data, options, (err, res, respBody) => {
debug(err);
Expand All @@ -145,3 +151,30 @@ export async function makeRequest(
});
});
}

export async function streamRequest(
payload: Payload,
): Promise<needle.ReadableStream> {
const { method, url, data, options } = setupRequest(payload);

try {
const result = await needle.request(method, url, data, options);
const statusCode = await getStatusCode(result);
debug('response (%s): <stream>', statusCode);
return result;
} catch (e) {
debug(e);
throw e;
}
}

async function getStatusCode(stream: needle.ReadableStream): Promise<number> {
return new Promise((resolve, reject) => {
stream.on('header', (statusCode: number) => {
resolve(statusCode);
});
stream.on('err', (err: Error) => {
reject(err);
});
});
}
17 changes: 12 additions & 5 deletions test/jest/unit/iac/local-cache.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ import {
} from '../../../../src/cli/commands/test/iac/local-execution/local-cache';
import * as fileUtilsModule from '../../../../src/cli/commands/test/iac/local-execution/file-utils';
import { PassThrough } from 'stream';
import * as needle from 'needle';
import * as rimraf from 'rimraf';
import * as fs from 'fs';
import * as path from 'path';
import * as request from '../../../../src/lib/request/request';

describe('initLocalCache - downloads bundle successfully', () => {
beforeEach(() => {
Expand All @@ -24,12 +24,17 @@ describe('initLocalCache - downloads bundle successfully', () => {
.spyOn(fileUtilsModule, 'extractBundle')
.mockResolvedValue();
jest.spyOn(fileUtilsModule, 'createIacDir').mockImplementation(() => null);
jest.spyOn(needle, 'get').mockReturnValue(mockReadable);
jest
.spyOn(request, 'streamRequest')
.mockReturnValue(Promise.resolve(mockReadable));

await localCacheModule.initLocalCache();

expect(needle.get).toHaveBeenCalledWith(
expect.stringContaining('bundle.tar.gz'),
expect(request.streamRequest).toHaveBeenCalledWith(
expect.objectContaining({
method: 'get',
url: expect.stringContaining('bundle.tar.gz'),
}),
);
expect(spy).toHaveBeenCalledWith(mockReadable);
});
Expand All @@ -43,7 +48,9 @@ describe('initLocalCache - downloads bundle successfully', () => {
.mockResolvedValue();
jest.spyOn(fileUtilsModule, 'isValidBundle').mockReturnValue(true);
jest.spyOn(fileUtilsModule, 'createIacDir').mockImplementation(() => null);
jest.spyOn(needle, 'get').mockReturnValue(new PassThrough());
jest
.spyOn(request, 'streamRequest')
.mockReturnValue(Promise.resolve(new PassThrough()));
jest.spyOn(fs, 'createReadStream').mockReturnValue(mockReadable);

await localCacheModule.initLocalCache({
Expand Down

0 comments on commit 0b90441

Please sign in to comment.