From 0b7fc4382815165612438c231a12aebaa51f87e2 Mon Sep 17 00:00:00 2001 From: Yingdong Yang Date: Sun, 11 Feb 2024 16:58:14 +0800 Subject: [PATCH] fix(cli): installation via a HTTP tunnel proxy --- cli/npm/install.js | 53 +++++++++++++++++++++++++++++----------------- 1 file changed, 33 insertions(+), 20 deletions(-) diff --git a/cli/npm/install.js b/cli/npm/install.js index 76b61648..b008947c 100755 --- a/cli/npm/install.js +++ b/cli/npm/install.js @@ -83,29 +83,42 @@ file.on('finish', () => { // Follow redirects. function get(url, callback) { - const requestUrl = new URL(url) - let request = https - let requestConfig = requestUrl - const proxyEnv = process.env['HTTPS_PROXY'] || process.env['https_proxy'] - - if (proxyEnv) { - const proxyUrl = new URL(proxyEnv) - request = proxyUrl.protocol === 'https:' ? https : http - requestConfig = { - hostname: proxyUrl.hostname, - port: proxyUrl.port, - path: requestUrl.toString(), - headers: { - Host: requestUrl.hostname - } - } - } - - request.get(requestConfig, response => { + const processResponse = (response) => { if (response.statusCode === 301 || response.statusCode === 302) { get(response.headers.location, callback); } else { callback(response); } - }); + }; + + const proxyEnv = process.env['HTTPS_PROXY'] || process.env['https_proxy']; + if (!proxyEnv) { + https.get(url, processResponse); + return; + } + + const requestUrl = new URL(url); + const requestPort = requestUrl.port || (requestUrl.protocol === 'https:' ? 443 : 80); + const proxyUrl = new URL(proxyEnv); + const request = proxyUrl.protocol === 'https:' ? https : http; + request.request({ + host: proxyUrl.hostname, + port: proxyUrl.port || (proxyUrl.protocol === 'https:' ? 443 : 80), + method: 'CONNECT', + path: `${requestUrl.hostname}:${requestPort}`, + }).on('connect', (response, socket, _head) => { + if (response.statusCode !== 200) { + // let caller handle error + callback(response); + return; + } + + const agent = https.Agent({ socket }); + https.get({ + host: requestUrl.host, + port: requestPort, + path: `${requestUrl.pathname}${requestUrl.search}`, + agent, + }, processResponse); + }).end(); }