mirror of
https://github.com/electron/node-gyp.git
synced 2025-08-15 12:58:19 +02:00
lib: noproxy support, match proxy detection to request
PR-URL: https://github.com/nodejs/node-gyp/pull/1978 Reviewed-By: Rod Vagg <rod@vagg.org>
This commit is contained in:
parent
345c70e56d
commit
3bcba2a01a
5 changed files with 192 additions and 5 deletions
|
@ -193,7 +193,8 @@ Some additional resources for Node.js native addons and writing `gyp` configurat
|
||||||
| `--devdir=$path` | SDK download directory (default is OS cache directory)
|
| `--devdir=$path` | SDK download directory (default is OS cache directory)
|
||||||
| `--ensure` | Don't reinstall headers if already present
|
| `--ensure` | Don't reinstall headers if already present
|
||||||
| `--dist-url=$url` | Download header tarball from custom URL
|
| `--dist-url=$url` | Download header tarball from custom URL
|
||||||
| `--proxy=$url` | Set HTTP proxy for downloading header tarball
|
| `--proxy=$url` | Set HTTP(S) proxy for downloading header tarball
|
||||||
|
| `--noproxy=$urls` | Set urls to ignore proxies when downloading header tarball
|
||||||
| `--cafile=$cafile` | Override default CA chain (to download tarball)
|
| `--cafile=$cafile` | Override default CA chain (to download tarball)
|
||||||
| `--nodedir=$path` | Set the path to the node source code
|
| `--nodedir=$path` | Set the path to the node source code
|
||||||
| `--python=$path` | Set path to the Python binary
|
| `--python=$path` | Set path to the Python binary
|
||||||
|
|
|
@ -11,6 +11,7 @@ const request = require('request')
|
||||||
const mkdir = require('mkdirp')
|
const mkdir = require('mkdirp')
|
||||||
const processRelease = require('./process-release')
|
const processRelease = require('./process-release')
|
||||||
const win = process.platform === 'win32'
|
const win = process.platform === 'win32'
|
||||||
|
const getProxyFromURI = require('./proxy')
|
||||||
|
|
||||||
function install (fs, gyp, argv, callback) {
|
function install (fs, gyp, argv, callback) {
|
||||||
var release = processRelease(argv, gyp, process.version, process.release)
|
var release = processRelease(argv, gyp, process.version, process.release)
|
||||||
|
@ -410,10 +411,7 @@ function download (gyp, env, url) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// basic support for a proxy server
|
// basic support for a proxy server
|
||||||
var proxyUrl = gyp.opts.proxy ||
|
var proxyUrl = getProxyFromURI(gyp, env, url)
|
||||||
env.http_proxy ||
|
|
||||||
env.HTTP_PROXY ||
|
|
||||||
env.npm_config_proxy
|
|
||||||
if (proxyUrl) {
|
if (proxyUrl) {
|
||||||
if (/^https?:\/\//i.test(proxyUrl)) {
|
if (/^https?:\/\//i.test(proxyUrl)) {
|
||||||
log.verbose('download', 'using proxy url: "%s"', proxyUrl)
|
log.verbose('download', 'using proxy url: "%s"', proxyUrl)
|
||||||
|
|
|
@ -67,6 +67,7 @@ proto.configDefs = {
|
||||||
ensure: Boolean, // 'install'
|
ensure: Boolean, // 'install'
|
||||||
solution: String, // 'build' (windows only)
|
solution: String, // 'build' (windows only)
|
||||||
proxy: String, // 'install'
|
proxy: String, // 'install'
|
||||||
|
noproxy: String, // 'install'
|
||||||
devdir: String, // everywhere
|
devdir: String, // everywhere
|
||||||
nodedir: String, // 'configure'
|
nodedir: String, // 'configure'
|
||||||
loglevel: String, // everywhere
|
loglevel: String, // everywhere
|
||||||
|
|
92
lib/proxy.js
Normal file
92
lib/proxy.js
Normal file
|
@ -0,0 +1,92 @@
|
||||||
|
'use strict'
|
||||||
|
// Taken from https://github.com/request/request/blob/212570b/lib/getProxyFromURI.js
|
||||||
|
|
||||||
|
const url = require('url')
|
||||||
|
|
||||||
|
function formatHostname (hostname) {
|
||||||
|
// canonicalize the hostname, so that 'oogle.com' won't match 'google.com'
|
||||||
|
return hostname.replace(/^\.*/, '.').toLowerCase()
|
||||||
|
}
|
||||||
|
|
||||||
|
function parseNoProxyZone (zone) {
|
||||||
|
zone = zone.trim().toLowerCase()
|
||||||
|
|
||||||
|
var zoneParts = zone.split(':', 2)
|
||||||
|
var zoneHost = formatHostname(zoneParts[0])
|
||||||
|
var zonePort = zoneParts[1]
|
||||||
|
var hasPort = zone.indexOf(':') > -1
|
||||||
|
|
||||||
|
return { hostname: zoneHost, port: zonePort, hasPort: hasPort }
|
||||||
|
}
|
||||||
|
|
||||||
|
function uriInNoProxy (uri, noProxy) {
|
||||||
|
var port = uri.port || (uri.protocol === 'https:' ? '443' : '80')
|
||||||
|
var hostname = formatHostname(uri.hostname)
|
||||||
|
var noProxyList = noProxy.split(',')
|
||||||
|
|
||||||
|
// iterate through the noProxyList until it finds a match.
|
||||||
|
return noProxyList.map(parseNoProxyZone).some(function (noProxyZone) {
|
||||||
|
var isMatchedAt = hostname.indexOf(noProxyZone.hostname)
|
||||||
|
var hostnameMatched = (
|
||||||
|
isMatchedAt > -1 &&
|
||||||
|
(isMatchedAt === hostname.length - noProxyZone.hostname.length)
|
||||||
|
)
|
||||||
|
|
||||||
|
if (noProxyZone.hasPort) {
|
||||||
|
return (port === noProxyZone.port) && hostnameMatched
|
||||||
|
}
|
||||||
|
|
||||||
|
return hostnameMatched
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
function getProxyFromURI (gyp, env, uri) {
|
||||||
|
// If a string URI/URL was given, parse it into a URL object
|
||||||
|
if (typeof uri === 'string') {
|
||||||
|
// eslint-disable-next-line
|
||||||
|
uri = url.parse(uri)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Decide the proper request proxy to use based on the request URI object and the
|
||||||
|
// environmental variables (NO_PROXY, HTTP_PROXY, etc.)
|
||||||
|
// respect NO_PROXY environment variables (see: https://lynx.invisible-island.net/lynx2.8.7/breakout/lynx_help/keystrokes/environments.html)
|
||||||
|
|
||||||
|
var noProxy = gyp.opts.noproxy || env.NO_PROXY || env.no_proxy || env.npm_config_noproxy || ''
|
||||||
|
|
||||||
|
// 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 !== '' && uriInNoProxy(uri, noProxy)) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check for HTTP or HTTPS Proxy in environment Else default to null
|
||||||
|
|
||||||
|
if (uri.protocol === 'http:') {
|
||||||
|
return gyp.opts.proxy ||
|
||||||
|
env.HTTP_PROXY ||
|
||||||
|
env.http_proxy ||
|
||||||
|
env.npm_config_proxy || null
|
||||||
|
}
|
||||||
|
|
||||||
|
if (uri.protocol === 'https:') {
|
||||||
|
return gyp.opts.proxy ||
|
||||||
|
env.HTTPS_PROXY ||
|
||||||
|
env.https_proxy ||
|
||||||
|
env.HTTP_PROXY ||
|
||||||
|
env.http_proxy ||
|
||||||
|
env.npm_config_proxy || null
|
||||||
|
}
|
||||||
|
|
||||||
|
// if none of that works, return null
|
||||||
|
// (What uri protocol are you using then?)
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = getProxyFromURI
|
|
@ -90,6 +90,101 @@ test('download over https with custom ca', function (t) {
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
test('download over http with proxy', function (t) {
|
||||||
|
t.plan(2)
|
||||||
|
|
||||||
|
var server = http.createServer(function (req, res) {
|
||||||
|
t.strictEqual(req.headers['user-agent'],
|
||||||
|
'node-gyp v42 (node ' + process.version + ')')
|
||||||
|
res.end('ok')
|
||||||
|
pserver.close(function () {
|
||||||
|
server.close()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
var pserver = http.createServer(function (req, res) {
|
||||||
|
t.strictEqual(req.headers['user-agent'],
|
||||||
|
'node-gyp v42 (node ' + process.version + ')')
|
||||||
|
res.end('proxy ok')
|
||||||
|
server.close(function () {
|
||||||
|
pserver.close()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
var host = 'localhost'
|
||||||
|
server.listen(0, host, function () {
|
||||||
|
var port = this.address().port
|
||||||
|
pserver.listen(port + 1, host, function () {
|
||||||
|
var gyp = {
|
||||||
|
opts: {
|
||||||
|
proxy: 'http://' + host + ':' + (port + 1)
|
||||||
|
},
|
||||||
|
version: '42'
|
||||||
|
}
|
||||||
|
var url = 'http://' + host + ':' + port
|
||||||
|
var req = install.test.download(gyp, {}, url)
|
||||||
|
req.on('response', function (res) {
|
||||||
|
var body = ''
|
||||||
|
res.setEncoding('utf8')
|
||||||
|
res.on('data', function (data) {
|
||||||
|
body += data
|
||||||
|
})
|
||||||
|
res.on('end', function () {
|
||||||
|
t.strictEqual(body, 'proxy ok')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
test('download over http with noproxy', function (t) {
|
||||||
|
t.plan(2)
|
||||||
|
|
||||||
|
var server = http.createServer(function (req, res) {
|
||||||
|
t.strictEqual(req.headers['user-agent'],
|
||||||
|
'node-gyp v42 (node ' + process.version + ')')
|
||||||
|
res.end('ok')
|
||||||
|
pserver.close(function () {
|
||||||
|
server.close()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
var pserver = http.createServer(function (req, res) {
|
||||||
|
t.strictEqual(req.headers['user-agent'],
|
||||||
|
'node-gyp v42 (node ' + process.version + ')')
|
||||||
|
res.end('proxy ok')
|
||||||
|
server.close(function () {
|
||||||
|
pserver.close()
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
|
var host = 'localhost'
|
||||||
|
server.listen(0, host, function () {
|
||||||
|
var port = this.address().port
|
||||||
|
pserver.listen(port + 1, host, function () {
|
||||||
|
var gyp = {
|
||||||
|
opts: {
|
||||||
|
proxy: 'http://' + host + ':' + (port + 1),
|
||||||
|
noproxy: 'localhost'
|
||||||
|
},
|
||||||
|
version: '42'
|
||||||
|
}
|
||||||
|
var url = 'http://' + host + ':' + port
|
||||||
|
var req = install.test.download(gyp, {}, url)
|
||||||
|
req.on('response', function (res) {
|
||||||
|
var body = ''
|
||||||
|
res.setEncoding('utf8')
|
||||||
|
res.on('data', function (data) {
|
||||||
|
body += data
|
||||||
|
})
|
||||||
|
res.on('end', function () {
|
||||||
|
t.strictEqual(body, 'ok')
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
test('download with missing cafile', function (t) {
|
test('download with missing cafile', function (t) {
|
||||||
t.plan(1)
|
t.plan(1)
|
||||||
var gyp = {
|
var gyp = {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue