Skip to content

Commit

Permalink
feat: support proxy from npmrc or env
Browse files Browse the repository at this point in the history
Support npmrc https-proxy and proxy.
Support env HTTPS_PROXY, https_proxy, HTTP_PROXY, http_proxy.

closes #6
  • Loading branch information
3cp committed Mar 13, 2020
1 parent 9f53716 commit da5b712
Show file tree
Hide file tree
Showing 4 changed files with 124 additions and 10 deletions.
47 changes: 47 additions & 0 deletions lib/get-https-proxy-agent.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Only support https proxy right now
const config = require('libnpmconfig');
const HttpsProxyAgent = require('https-proxy-agent');
const {info, warn} = require('./log');

module.exports = function ({
_npmrc,
_env = process.env
} = {}) {
if (!_npmrc) _npmrc = config.read().toJSON();
const rcHttpsProxy = _npmrc['https-proxy'];
const rcProxy = _npmrc['proxy'];
const envHttpsProxy = _env.HTTPS_PROXY;
const envHttpsProxyL = _env.https_proxy;
const envHttpProxy = _env.HTTP_PROXY;
const envHttpProxyL = _env.http_proxy;

let proxy;
if (rcHttpsProxy) {
info(`Got npmrc https-proxy: ${rcHttpsProxy}`);
proxy = rcHttpsProxy;
} else if (rcProxy) {
info(`Got npmrc proxy: ${rcProxy}`);
proxy = rcProxy;
} else if (envHttpsProxy) {
info(`Got env HTTPS_PROXY: ${envHttpsProxy}`);
proxy = envHttpsProxy;
} else if (envHttpsProxyL) {
info(`Got env https_proxy: ${envHttpsProxyL}`);
proxy = envHttpsProxyL;
} else if (envHttpProxy) {
info(`Got env HTTP_PROXY: ${envHttpProxy}`);
proxy = envHttpProxy;
} else if (envHttpProxyL) {
info(`Got env http_proxy: ${envHttpProxyL}`);
proxy = envHttpProxyL;
}

if (!proxy) return;

// Start with http or https
if (proxy.startsWith('http')) {
return new HttpsProxyAgent(proxy);
}

warn('Unsupported (not a http(s) proxy), you may experience failure.');
};
26 changes: 16 additions & 10 deletions lib/skeleton-dir.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ const {info, warn} = require('./log');
const {folderExists} = require('./file-exists');
const useGitRepo = require('./use-git-repo');
const SoftError = require('./soft-error');
const agent = require('./get-https-proxy-agent')();
const tmp = require('tmp');
tmp.setGracefulCleanup();

Expand All @@ -31,7 +32,8 @@ function getHash(tarball) {
hostname: url.hostname,
path: url.pathname,
search: url.search,
method: 'HEAD'
method: 'HEAD',
agent
}, res => {
if (res.statusCode === 200) {
let hash;
Expand Down Expand Up @@ -111,16 +113,20 @@ module.exports = async function(supplier, {
target => {
info('Fetching tarball ' + result.tarball);
return new Promise((resolve, reject) => {
https.get(result.tarball, res => {
if (res.statusCode == 200) {
res.pipe(gunzip())
.pipe(tar.extract(target))
.once('error', reject)
.once('finish', resolve);
} else {
reject(new SoftError(`Unable to download ${result.tarball}\n${res.statusCode} ${res.statusMessage}`));
https.get(
result.tarball,
{agent},
res => {
if (res.statusCode == 200) {
res.pipe(gunzip())
.pipe(tar.extract(target))
.once('error', reject)
.once('finish', resolve);
} else {
reject(new SoftError(`Unable to download ${result.tarball}\n${res.statusCode} ${res.statusMessage}`));
}
}
}).on('error', reject);
).on('error', reject);
});
}
);
Expand Down
2 changes: 2 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,9 @@
"eslint": "^6.8.0",
"gunzip-maybe": "^1.4.1",
"hosted-git-info": "^3.0.4",
"https-proxy-agent": "^5.0.0",
"isutf8": "^2.1.0",
"libnpmconfig": "^1.2.1",
"lodash.camelcase": "^4.3.0",
"lodash.mergewith": "^4.6.2",
"minimist": "^1.2.0",
Expand Down
59 changes: 59 additions & 0 deletions test/get-https-proxy-agent.spec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
const test = require('ava');
const getAgent = require('../lib/get-https-proxy-agent');

test.serial('getHttpsProxyAgent gets https-proxy from npmrc', async t => {

const agent = getAgent({
_npmrc: { 'https-proxy' : 'https://domain1.com'},
_env: {}
});
t.is(agent.proxy.href, 'https://domain1.com/');
});

test.serial('getHttpsProxyAgent gets proxy from npmrc', async t => {
const agent = getAgent({
_npmrc: { 'proxy' : 'https://domain2.com:80443'},
_env: {}
});
t.is(agent.proxy.href, 'https://domain2.com:80443/');
});

test.serial('getHttpsProxyAgent gets HTTPS_PROXY from env', async t => {
const agent = getAgent({
_npmrc: {},
_env: {HTTPS_PROXY: 'https://domain3.com'}
});
t.is(agent.proxy.href, 'https://domain3.com/');
});

test.serial('getHttpsProxyAgent gets https_proxy from env', async t => {
const agent = getAgent({
_npmrc: {},
_env: {https_proxy: 'https://domain4.com'}
});
t.is(agent.proxy.href, 'https://domain4.com/');
});

test.serial('getHttpsProxyAgent gets HTTP_PROXY from env', async t => {
const agent = getAgent({
_npmrc: {},
_env: {HTTP_PROXY: 'http://domain5.com'}
});
t.is(agent.proxy.href, 'http://domain5.com/');
});

test.serial('getHttpsProxyAgent gets http_proxy from env', async t => {
const agent = getAgent({
_npmrc: {},
_env: {HTTP_PROXY: 'http://domain6.com'}
});
t.is(agent.proxy.href, 'http://domain6.com/');
});

test.serial('getHttpsProxyAgent returns nothing if no proxy set', async t => {
const agent = getAgent({
_npmrc: {},
_env: {}
});
t.is(agent, undefined);
});

0 comments on commit da5b712

Please sign in to comment.