Skip to content

Commit 165b4b9

Browse files
committedMar 29, 2021
feat: introduce envvar to control HTTP-HTTPS upgrade behavior
1 parent 9290478 commit 165b4b9

File tree

3 files changed

+65
-13
lines changed

3 files changed

+65
-13
lines changed
 

‎help/commands-docs/_ENVIRONMENT.md

+18-9
Original file line numberDiff line numberDiff line change
@@ -8,19 +8,28 @@ You can set these environment variables to change CLI run settings.
88
[How to get your account token](https://snyk.co/ucT6J)<br />
99
[How to use Service Accounts](https://snyk.co/ucT6L)<br />
1010

11-
- `SNYK_API`:
12-
Sets API host to use for Snyk requests. Useful for on-premise instances and configuring proxies.
13-
1411
- `SNYK_CFG_`<KEY>:
1512
Allows you to override any key that's also available as `snyk config` option.
1613

1714
E.g. `SNYK_CFG_ORG`=myorg will override default org option in `config` with "myorg".
1815

1916
- `SNYK_REGISTRY_USERNAME`:
20-
Specify a username to use when connecting to a container registry. Note that using the `--username` flag will
21-
override this value. This will be ignored in favour of local Docker binary credentials when Docker is present.
22-
17+
Specify a username to use when connecting to a container registry. Note that using the `--username` flag will
18+
override this value. This will be ignored in favour of local Docker binary credentials when Docker is present.
19+
2320
- `SNYK_REGISTRY_PASSWORD`:
24-
Specify a password to use when connecting to a container registry. Note that using the `--password` flag will
25-
override this value. This will be ignored in favour of local Docker binary credentials when Docker is present.
26-
21+
Specify a password to use when connecting to a container registry. Note that using the `--password` flag will
22+
override this value. This will be ignored in favour of local Docker binary credentials when Docker is present.
23+
24+
## Connecting to Snyk API
25+
26+
By default Snyk CLI will connect to `https://snyk.io/api/v1`.
27+
28+
- `SNYK_API`:
29+
Sets API host to use for Snyk requests. Useful for on-premise instances and configuring proxies. If set with `http` protocol CLI will upgrade the requests to `https`. Unless `SNYK_HTTP_PROTOCOL_UPGRADE` is set to `0`.
30+
31+
- `SNYK_HTTP_PROTOCOL_UPGRADE`=0:
32+
If set to the value of `0` the API requests aimed at `http` URLs will not be upgraded to `https`. Useful e.g., for reverse proxies.
33+
34+
- `HTTPS_PROXY` and `HTTP_PROXY`:
35+
Allows you to specify a proxy to use for `https` and `http` calls. The `https` in the `HTTPS_PROXY` means that _requests using `https` protocol_ will use this proxy. The proxy itself doesn't need to use `https`.

‎src/lib/request/request.ts

+6-2
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,8 @@ export = function makeRequest(
7171

7272
if (
7373
parsedUrl.protocol === 'http:' &&
74-
parsedUrl.hostname !== 'localhost'
74+
parsedUrl.hostname !== 'localhost' &&
75+
process.env.SNYK_HTTP_PROTOCOL_UPGRADE !== '0'
7576
) {
7677
debug('forcing api request to https');
7778
parsedUrl.protocol = 'https:';
@@ -95,7 +96,10 @@ export = function makeRequest(
9596
let url = payload.url;
9697

9798
if (payload.qs) {
98-
url = url + '?' + querystring.stringify(payload.qs);
99+
// Parse the URL and append the search part - this will take care of adding the '/?' part if it's missing
100+
const urlObject = new URL(url);
101+
urlObject.search = querystring.stringify(payload.qs);
102+
url = urlObject.toString();
99103
delete payload.qs;
100104
}
101105

‎test/request.test.ts

+41-2
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ test('request with timeout calls needle as expected', (t) => {
139139
test('request with query string calls needle as expected', (t) => {
140140
needleStub.yields(null, { statusCode: 200 }, 'text');
141141
const payload = {
142-
url: 'http://test.stub',
142+
url: 'https://test.stub',
143143
qs: {
144144
key: 'value',
145145
test: ['multi', 'value'],
@@ -155,7 +155,7 @@ test('request with query string calls needle as expected', (t) => {
155155
t.ok(
156156
needleStub.calledWith(
157157
'get', // default
158-
'https://test.stub/?key=value&test=multi&test=value', // turns http to https and appends querystring
158+
'https://test.stub/?key=value&test=multi&test=value', // appends querystring
159159
sinon.match.falsy, // no data
160160
sinon.match({
161161
headers: sinon.match({
@@ -442,3 +442,42 @@ test('request rejects if needle fails', (t) => {
442442
t.equals(e, 'Unexpected Error', 'rejects error');
443443
});
444444
});
445+
446+
test('request calls needle as expected and will not update HTTP to HTTPS if envvar is set', (t) => {
447+
process.env.SNYK_HTTP_PROTOCOL_UPGRADE = '0';
448+
needleStub.yields(null, { statusCode: 200 }, 'text');
449+
const payload = {
450+
url: 'http://test.stub',
451+
};
452+
return request(payload)
453+
.then((response) => {
454+
process.env.SNYK_HTTP_PROTOCOL_UPGRADE = '1';
455+
t.deepEquals(
456+
response,
457+
{ res: { statusCode: 200 }, body: 'text' },
458+
'response ok',
459+
);
460+
t.ok(
461+
needleStub.calledWith(
462+
'get', // default
463+
'http://test.stub', // won't upgrade http to https
464+
sinon.match.falsy, // no data
465+
sinon.match({
466+
headers: sinon.match({
467+
'x-snyk-cli-version': sinon.match.string, // dynamic version
468+
'content-encoding': undefined, // should not set when no data
469+
'content-length': undefined, // should not be set when no data
470+
}),
471+
follow_max: 5, // default
472+
timeout: 300000, // default
473+
json: undefined, // default
474+
agent: sinon.match.instanceOf(http.Agent),
475+
rejectUnauthorized: undefined, // should not be set when not use insecure mode
476+
}),
477+
sinon.match.func, // callback function
478+
),
479+
'needle called as expected',
480+
);
481+
})
482+
.catch((e) => t.fail('should not throw error', e));
483+
});

0 commit comments

Comments
 (0)
Please sign in to comment.