Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add HTTP Proxy support to NPM Binary Installer #1067

Merged
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
7 changes: 6 additions & 1 deletion installers/npm/binary.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ const cTable = require("console.table");
const libc = require("detect-libc");
const { join } = require("path");
const { spawnSync } = require("child_process");
const { configureProxy } = require("./proxy");

const error = (msg) => {
console.error(msg);
Expand Down Expand Up @@ -111,7 +112,11 @@ const run = () => {

const install = () => {
const binary = getBinary();
binary.install();

const proxy = configureProxy(binary.url);

binary.install(proxy);

let pluginInstallCommand = `${binary.binaryPath} install --plugin`;
let commands = [
`${pluginInstallCommand} supergraph@latest-0`,
Expand Down
99 changes: 99 additions & 0 deletions installers/npm/proxy.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
/**
*
* NoProxy logic derived from Request project:
* https://github.com/request/request/blob/3c0cddc7c8eb60b470e9519da85896ed7ee0081e/lib/getProxyFromURI.js
*
*/

const formatHostName = (hostname) =>
farawaysouthwest marked this conversation as resolved.
Show resolved Hide resolved
hostname.replace(/^\.*/, ".").toLowerCase();

const parseNoProxyZone = (zone) => {
zone = zone.trim();

const zoneParts = zone.split(":", 2);
const zoneHost = formatHostName(zoneParts[0]);
const zonePort = zoneParts[1];
const hasPort = zone.indexOf(":") > -1;

return { hostname: zoneHost, port: zonePort, hasPort: hasPort };
};

const urlInNoProxy = (requestURL, noProxy) => {
const port =
requestURL.port || (requestURL.protocol === "https:" ? "443" : "80");

// clean hostname
const hostname = formatHostName(requestURL.hostname);

// convert to array
const noProxyList = noProxy.split(",");

// iterate over noProxyList and find match with RequestURL
return noProxyList.map(parseNoProxyZone).some((noProxyZone) => {
const isMatchedAt = hostname.indexOf(noProxyZone.hostname);
const hostnameMatched =
isMatchedAt > -1 &&
isMatchedAt === hostname.length - noProxyZone.hostname.length;

if (noProxyZone.hasPort) {
return port === noProxyZone.port && hostnameMatched;
}

return hostnameMatched;
});
};

const getProxyEnv = (requestURL) => {
const noProxy = process.env.NO_PROXY || process.env.no_proxy || "";

// if the noProxy is a wildcard then return null
if (noProxy === "*") {
return null;
}

// if the noProxy is not empty and the uri is found, return null
if (noProxy !== "" && urlInNoProxy(requestURL, noProxy)) {
return null;
}

// get proxy based on request url's protocol
if (requestURL.protocol == "http:") {
return process.env.HTTP_PROXY || process.env.http_proxy || null;
}

if (requestURL.protocol == "https:") {
return process.env.HTTPS_PROXY || process.env.https_proxy || null;
}

// not a supported protocol...
return null;
};

const configureProxy = (requestURL) => {
const url = new URL(requestURL);
const env = getProxyEnv(url);

// short circuit if null
if (!env) return null;

// parse proxy url
const { hostname, port, protocol, username, password } = new URL(env);

// return proxy object for axios request
return {
proxy: {
protocol,
hostname,
port,
auth: {
username,
password,
},
},
};
};

module.exports = {
configureProxy,
};