diff options
Diffstat (limited to 'school/node_modules/proxy-from-env')
-rw-r--r-- | school/node_modules/proxy-from-env/.eslintrc | 29 | ||||
-rw-r--r-- | school/node_modules/proxy-from-env/.travis.yml | 10 | ||||
-rw-r--r-- | school/node_modules/proxy-from-env/LICENSE | 20 | ||||
-rw-r--r-- | school/node_modules/proxy-from-env/README.md | 131 | ||||
-rw-r--r-- | school/node_modules/proxy-from-env/index.js | 108 | ||||
-rw-r--r-- | school/node_modules/proxy-from-env/package.json | 34 | ||||
-rw-r--r-- | school/node_modules/proxy-from-env/test.js | 483 |
7 files changed, 815 insertions, 0 deletions
diff --git a/school/node_modules/proxy-from-env/.eslintrc b/school/node_modules/proxy-from-env/.eslintrc new file mode 100644 index 0000000..a51449b --- /dev/null +++ b/school/node_modules/proxy-from-env/.eslintrc @@ -0,0 +1,29 @@ +{ + "env": { + "node": true + }, + "rules": { + "array-bracket-spacing": [2, "never"], + "block-scoped-var": 2, + "brace-style": [2, "1tbs"], + "camelcase": 1, + "computed-property-spacing": [2, "never"], + "curly": 2, + "eol-last": 2, + "eqeqeq": [2, "smart"], + "max-depth": [1, 3], + "max-len": [1, 80], + "max-statements": [1, 15], + "new-cap": 1, + "no-extend-native": 2, + "no-mixed-spaces-and-tabs": 2, + "no-trailing-spaces": 2, + "no-unused-vars": 1, + "no-use-before-define": [2, "nofunc"], + "object-curly-spacing": [2, "never"], + "quotes": [2, "single", "avoid-escape"], + "semi": [2, "always"], + "keyword-spacing": [2, {"before": true, "after": true}], + "space-unary-ops": 2 + } +} diff --git a/school/node_modules/proxy-from-env/.travis.yml b/school/node_modules/proxy-from-env/.travis.yml new file mode 100644 index 0000000..64a05f9 --- /dev/null +++ b/school/node_modules/proxy-from-env/.travis.yml @@ -0,0 +1,10 @@ +language: node_js +node_js: + - node + - lts/* +script: + - npm run lint + # test-coverage will also run the tests, but does not print helpful output upon test failure. + # So we also run the tests separately. + - npm run test + - npm run test-coverage && cat coverage/lcov.info | ./node_modules/.bin/coveralls && rm -rf coverage diff --git a/school/node_modules/proxy-from-env/LICENSE b/school/node_modules/proxy-from-env/LICENSE new file mode 100644 index 0000000..8f25097 --- /dev/null +++ b/school/node_modules/proxy-from-env/LICENSE @@ -0,0 +1,20 @@ +The MIT License + +Copyright (C) 2016-2018 Rob Wu <rob@robwu.nl> + +Permission is hereby granted, free of charge, to any person obtaining a copy of +this software and associated documentation files (the "Software"), to deal in +the Software without restriction, including without limitation the rights to +use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +of the Software, and to permit persons to whom the Software is furnished to do +so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/school/node_modules/proxy-from-env/README.md b/school/node_modules/proxy-from-env/README.md new file mode 100644 index 0000000..e82520c --- /dev/null +++ b/school/node_modules/proxy-from-env/README.md @@ -0,0 +1,131 @@ +# proxy-from-env + +[![Build Status](https://travis-ci.org/Rob--W/proxy-from-env.svg?branch=master)](https://travis-ci.org/Rob--W/proxy-from-env) +[![Coverage Status](https://coveralls.io/repos/github/Rob--W/proxy-from-env/badge.svg?branch=master)](https://coveralls.io/github/Rob--W/proxy-from-env?branch=master) + +`proxy-from-env` is a Node.js package that exports a function (`getProxyForUrl`) +that takes an input URL (a string or +[`url.parse`](https://nodejs.org/docs/latest/api/url.html#url_url_parsing)'s +return value) and returns the desired proxy URL (also a string) based on +standard proxy environment variables. If no proxy is set, an empty string is +returned. + +It is your responsibility to actually proxy the request using the given URL. + +Installation: + +```sh +npm install proxy-from-env +``` + +## Example +This example shows how the data for a URL can be fetched via the +[`http` module](https://nodejs.org/api/http.html), in a proxy-aware way. + +```javascript +var http = require('http'); +var parseUrl = require('url').parse; +var getProxyForUrl = require('proxy-from-env').getProxyForUrl; + +var some_url = 'http://example.com/something'; + +// // Example, if there is a proxy server at 10.0.0.1:1234, then setting the +// // http_proxy environment variable causes the request to go through a proxy. +// process.env.http_proxy = 'http://10.0.0.1:1234'; +// +// // But if the host to be proxied is listed in NO_PROXY, then the request is +// // not proxied (but a direct request is made). +// process.env.no_proxy = 'example.com'; + +var proxy_url = getProxyForUrl(some_url); // <-- Our magic. +if (proxy_url) { + // Should be proxied through proxy_url. + var parsed_some_url = parseUrl(some_url); + var parsed_proxy_url = parseUrl(proxy_url); + // A HTTP proxy is quite simple. It is similar to a normal request, except the + // path is an absolute URL, and the proxied URL's host is put in the header + // instead of the server's actual host. + httpOptions = { + protocol: parsed_proxy_url.protocol, + hostname: parsed_proxy_url.hostname, + port: parsed_proxy_url.port, + path: parsed_some_url.href, + headers: { + Host: parsed_some_url.host, // = host name + optional port. + }, + }; +} else { + // Direct request. + httpOptions = some_url; +} +http.get(httpOptions, function(res) { + var responses = []; + res.on('data', function(chunk) { responses.push(chunk); }); + res.on('end', function() { console.log(responses.join('')); }); +}); + +``` + +## Environment variables +The environment variables can be specified in lowercase or uppercase, with the +lowercase name having precedence over the uppercase variant. A variable that is +not set has the same meaning as a variable that is set but has no value. + +### NO\_PROXY + +`NO_PROXY` is a list of host names (optionally with a port). If the input URL +matches any of the entries in `NO_PROXY`, then the input URL should be fetched +by a direct request (i.e. without a proxy). + +Matching follows the following rules: + +- `NO_PROXY=*` disables all proxies. +- Space and commas may be used to separate the entries in the `NO_PROXY` list. +- If `NO_PROXY` does not contain any entries, then proxies are never disabled. +- If a port is added after the host name, then the ports must match. If the URL + does not have an explicit port name, the protocol's default port is used. +- Generally, the proxy is only disabled if the host name is an exact match for + an entry in the `NO_PROXY` list. The only exceptions are entries that start + with a dot or with a wildcard; then the proxy is disabled if the host name + ends with the entry. + +See `test.js` for examples of what should match and what does not. + +### \*\_PROXY + +The environment variable used for the proxy depends on the protocol of the URL. +For example, `https://example.com` uses the "https" protocol, and therefore the +proxy to be used is `HTTPS_PROXY` (_NOT_ `HTTP_PROXY`, which is _only_ used for +http:-URLs). + +The library is not limited to http(s), other schemes such as +`FTP_PROXY` (ftp:), +`WSS_PROXY` (wss:), +`WS_PROXY` (ws:) +are also supported. + +If present, `ALL_PROXY` is used as fallback if there is no other match. + + +## External resources +The exact way of parsing the environment variables is not codified in any +standard. This library is designed to be compatible with formats as expected by +existing software. +The following resources were used to determine the desired behavior: + +- cURL: + https://curl.haxx.se/docs/manpage.html#ENVIRONMENT + https://github.com/curl/curl/blob/4af40b3646d3b09f68e419f7ca866ff395d1f897/lib/url.c#L4446-L4514 + https://github.com/curl/curl/blob/4af40b3646d3b09f68e419f7ca866ff395d1f897/lib/url.c#L4608-L4638 + +- wget: + https://www.gnu.org/software/wget/manual/wget.html#Proxies + http://git.savannah.gnu.org/cgit/wget.git/tree/src/init.c?id=636a5f9a1c508aa39e35a3a8e9e54520a284d93d#n383 + http://git.savannah.gnu.org/cgit/wget.git/tree/src/retr.c?id=93c1517c4071c4288ba5a4b038e7634e4c6b5482#n1278 + +- W3: + https://www.w3.org/Daemon/User/Proxies/ProxyClients.html + +- Python's urllib: + https://github.com/python/cpython/blob/936135bb97fe04223aa30ca6e98eac8f3ed6b349/Lib/urllib/request.py#L755-L782 + https://github.com/python/cpython/blob/936135bb97fe04223aa30ca6e98eac8f3ed6b349/Lib/urllib/request.py#L2444-L2479 diff --git a/school/node_modules/proxy-from-env/index.js b/school/node_modules/proxy-from-env/index.js new file mode 100644 index 0000000..df75004 --- /dev/null +++ b/school/node_modules/proxy-from-env/index.js @@ -0,0 +1,108 @@ +'use strict'; + +var parseUrl = require('url').parse; + +var DEFAULT_PORTS = { + ftp: 21, + gopher: 70, + http: 80, + https: 443, + ws: 80, + wss: 443, +}; + +var stringEndsWith = String.prototype.endsWith || function(s) { + return s.length <= this.length && + this.indexOf(s, this.length - s.length) !== -1; +}; + +/** + * @param {string|object} url - The URL, or the result from url.parse. + * @return {string} The URL of the proxy that should handle the request to the + * given URL. If no proxy is set, this will be an empty string. + */ +function getProxyForUrl(url) { + var parsedUrl = typeof url === 'string' ? parseUrl(url) : url || {}; + var proto = parsedUrl.protocol; + var hostname = parsedUrl.host; + var port = parsedUrl.port; + if (typeof hostname !== 'string' || !hostname || typeof proto !== 'string') { + return ''; // Don't proxy URLs without a valid scheme or host. + } + + proto = proto.split(':', 1)[0]; + // Stripping ports in this way instead of using parsedUrl.hostname to make + // sure that the brackets around IPv6 addresses are kept. + hostname = hostname.replace(/:\d*$/, ''); + port = parseInt(port) || DEFAULT_PORTS[proto] || 0; + if (!shouldProxy(hostname, port)) { + return ''; // Don't proxy URLs that match NO_PROXY. + } + + var proxy = + getEnv('npm_config_' + proto + '_proxy') || + getEnv(proto + '_proxy') || + getEnv('npm_config_proxy') || + getEnv('all_proxy'); + if (proxy && proxy.indexOf('://') === -1) { + // Missing scheme in proxy, default to the requested URL's scheme. + proxy = proto + '://' + proxy; + } + return proxy; +} + +/** + * Determines whether a given URL should be proxied. + * + * @param {string} hostname - The host name of the URL. + * @param {number} port - The effective port of the URL. + * @returns {boolean} Whether the given URL should be proxied. + * @private + */ +function shouldProxy(hostname, port) { + var NO_PROXY = + (getEnv('npm_config_no_proxy') || getEnv('no_proxy')).toLowerCase(); + if (!NO_PROXY) { + return true; // Always proxy if NO_PROXY is not set. + } + if (NO_PROXY === '*') { + return false; // Never proxy if wildcard is set. + } + + return NO_PROXY.split(/[,\s]/).every(function(proxy) { + if (!proxy) { + return true; // Skip zero-length hosts. + } + var parsedProxy = proxy.match(/^(.+):(\d+)$/); + var parsedProxyHostname = parsedProxy ? parsedProxy[1] : proxy; + var parsedProxyPort = parsedProxy ? parseInt(parsedProxy[2]) : 0; + if (parsedProxyPort && parsedProxyPort !== port) { + return true; // Skip if ports don't match. + } + + if (!/^[.*]/.test(parsedProxyHostname)) { + // No wildcards, so stop proxying if there is an exact match. + return hostname !== parsedProxyHostname; + } + + if (parsedProxyHostname.charAt(0) === '*') { + // Remove leading wildcard. + parsedProxyHostname = parsedProxyHostname.slice(1); + } + // Stop proxying if the hostname ends with the no_proxy host. + return !stringEndsWith.call(hostname, parsedProxyHostname); + }); +} + +/** + * Get the value for an environment variable. + * + * @param {string} key - The name of the environment variable. + * @return {string} The value of the environment variable. + * @private + */ +function getEnv(key) { + return process.env[key.toLowerCase()] || process.env[key.toUpperCase()] || ''; +} + +exports.getProxyForUrl = getProxyForUrl; diff --git a/school/node_modules/proxy-from-env/package.json b/school/node_modules/proxy-from-env/package.json new file mode 100644 index 0000000..be2b845 --- /dev/null +++ b/school/node_modules/proxy-from-env/package.json @@ -0,0 +1,34 @@ +{ + "name": "proxy-from-env", + "version": "1.1.0", + "description": "Offers getProxyForUrl to get the proxy URL for a URL, respecting the *_PROXY (e.g. HTTP_PROXY) and NO_PROXY environment variables.", + "main": "index.js", + "scripts": { + "lint": "eslint *.js", + "test": "mocha ./test.js --reporter spec", + "test-coverage": "istanbul cover ./node_modules/.bin/_mocha -- --reporter spec" + }, + "repository": { + "type": "git", + "url": "https://github.com/Rob--W/proxy-from-env.git" + }, + "keywords": [ + "proxy", + "http_proxy", + "https_proxy", + "no_proxy", + "environment" + ], + "author": "Rob Wu <rob@robwu.nl> (https://robwu.nl/)", + "license": "MIT", + "bugs": { + "url": "https://github.com/Rob--W/proxy-from-env/issues" + }, + "homepage": "https://github.com/Rob--W/proxy-from-env#readme", + "devDependencies": { + "coveralls": "^3.0.9", + "eslint": "^6.8.0", + "istanbul": "^0.4.5", + "mocha": "^7.1.0" + } +} diff --git a/school/node_modules/proxy-from-env/test.js b/school/node_modules/proxy-from-env/test.js new file mode 100644 index 0000000..abf6542 --- /dev/null +++ b/school/node_modules/proxy-from-env/test.js @@ -0,0 +1,483 @@ +/* eslint max-statements:0 */ +'use strict'; + +var assert = require('assert'); +var parseUrl = require('url').parse; + +var getProxyForUrl = require('./').getProxyForUrl; + +// Runs the callback with process.env temporarily set to env. +function runWithEnv(env, callback) { + var originalEnv = process.env; + process.env = env; + try { + callback(); + } finally { + process.env = originalEnv; + } +} + +// Defines a test case that checks whether getProxyForUrl(input) === expected. +function testProxyUrl(env, expected, input) { + assert(typeof env === 'object' && env !== null); + // Copy object to make sure that the in param does not get modified between + // the call of this function and the use of it below. + env = JSON.parse(JSON.stringify(env)); + + var title = 'getProxyForUrl(' + JSON.stringify(input) + ')' + + ' === ' + JSON.stringify(expected); + + // Save call stack for later use. + var stack = {}; + Error.captureStackTrace(stack, testProxyUrl); + // Only use the last stack frame because that shows where this function is + // called, and that is sufficient for our purpose. No need to flood the logs + // with an uninteresting stack trace. + stack = stack.stack.split('\n', 2)[1]; + + it(title, function() { + var actual; + runWithEnv(env, function() { + actual = getProxyForUrl(input); + }); + if (expected === actual) { + return; // Good! + } + try { + assert.strictEqual(expected, actual); // Create a formatted error message. + // Should not happen because previously we determined expected !== actual. + throw new Error('assert.strictEqual passed. This is impossible!'); + } catch (e) { + // Use the original stack trace, so we can see a helpful line number. + e.stack = e.message + stack; + throw e; + } + }); +} + +describe('getProxyForUrl', function() { + describe('No proxy variables', function() { + var env = {}; + testProxyUrl(env, '', 'http://example.com'); + testProxyUrl(env, '', 'https://example.com'); + testProxyUrl(env, '', 'ftp://example.com'); + }); + + describe('Invalid URLs', function() { + var env = {}; + env.ALL_PROXY = 'http://unexpected.proxy'; + testProxyUrl(env, '', 'bogus'); + testProxyUrl(env, '', '//example.com'); + testProxyUrl(env, '', '://example.com'); + testProxyUrl(env, '', '://'); + testProxyUrl(env, '', '/path'); + testProxyUrl(env, '', ''); + testProxyUrl(env, '', 'http:'); + testProxyUrl(env, '', 'http:/'); + testProxyUrl(env, '', 'http://'); + testProxyUrl(env, '', 'prototype://'); + testProxyUrl(env, '', 'hasOwnProperty://'); + testProxyUrl(env, '', '__proto__://'); + testProxyUrl(env, '', undefined); + testProxyUrl(env, '', null); + testProxyUrl(env, '', {}); + testProxyUrl(env, '', {host: 'x', protocol: 1}); + testProxyUrl(env, '', {host: 1, protocol: 'x'}); + }); + + describe('http_proxy and HTTP_PROXY', function() { + var env = {}; + env.HTTP_PROXY = 'http://http-proxy'; + + testProxyUrl(env, '', 'https://example'); + testProxyUrl(env, 'http://http-proxy', 'http://example'); + testProxyUrl(env, 'http://http-proxy', parseUrl('http://example')); + + // eslint-disable-next-line camelcase + env.http_proxy = 'http://priority'; + testProxyUrl(env, 'http://priority', 'http://example'); + }); + + describe('http_proxy with non-sensical value', function() { + var env = {}; + // Crazy values should be passed as-is. It is the responsibility of the + // one who launches the application that the value makes sense. + // TODO: Should we be stricter and perform validation? + env.HTTP_PROXY = 'Crazy \n!() { ::// }'; + testProxyUrl(env, 'Crazy \n!() { ::// }', 'http://wow'); + + // The implementation assumes that the HTTP_PROXY environment variable is + // somewhat reasonable, and if the scheme is missing, it is added. + // Garbage in, garbage out some would say... + env.HTTP_PROXY = 'crazy without colon slash slash'; + testProxyUrl(env, 'http://crazy without colon slash slash', 'http://wow'); + }); + + describe('https_proxy and HTTPS_PROXY', function() { + var env = {}; + // Assert that there is no fall back to http_proxy + env.HTTP_PROXY = 'http://unexpected.proxy'; + testProxyUrl(env, '', 'https://example'); + + env.HTTPS_PROXY = 'http://https-proxy'; + testProxyUrl(env, 'http://https-proxy', 'https://example'); + + // eslint-disable-next-line camelcase + env.https_proxy = 'http://priority'; + testProxyUrl(env, 'http://priority', 'https://example'); + }); + + describe('ftp_proxy', function() { + var env = {}; + // Something else than http_proxy / https, as a sanity check. + env.FTP_PROXY = 'http://ftp-proxy'; + + testProxyUrl(env, 'http://ftp-proxy', 'ftp://example'); + testProxyUrl(env, '', 'ftps://example'); + }); + + describe('all_proxy', function() { + var env = {}; + env.ALL_PROXY = 'http://catch-all'; + testProxyUrl(env, 'http://catch-all', 'https://example'); + + // eslint-disable-next-line camelcase + env.all_proxy = 'http://priority'; + testProxyUrl(env, 'http://priority', 'https://example'); + }); + + describe('all_proxy without scheme', function() { + var env = {}; + env.ALL_PROXY = 'noscheme'; + testProxyUrl(env, 'http://noscheme', 'http://example'); + testProxyUrl(env, 'https://noscheme', 'https://example'); + + // The module does not impose restrictions on the scheme. + testProxyUrl(env, 'bogus-scheme://noscheme', 'bogus-scheme://example'); + + // But the URL should still be valid. + testProxyUrl(env, '', 'bogus'); + }); + + describe('no_proxy empty', function() { + var env = {}; + env.HTTPS_PROXY = 'http://proxy'; + + // NO_PROXY set but empty. + env.NO_PROXY = ''; + testProxyUrl(env, 'http://proxy', 'https://example'); + + // No entries in NO_PROXY (comma). + env.NO_PROXY = ','; + testProxyUrl(env, 'http://proxy', 'https://example'); + + // No entries in NO_PROXY (whitespace). + env.NO_PROXY = ' '; + testProxyUrl(env, 'http://proxy', 'https://example'); + + // No entries in NO_PROXY (multiple whitespace / commas). + env.NO_PROXY = ',\t,,,\n, ,\r'; + testProxyUrl(env, 'http://proxy', 'https://example'); + }); + + describe('no_proxy=example (single host)', function() { + var env = {}; + env.HTTP_PROXY = 'http://proxy'; + + env.NO_PROXY = 'example'; + testProxyUrl(env, '', 'http://example'); + testProxyUrl(env, '', 'http://example:80'); + testProxyUrl(env, '', 'http://example:0'); + testProxyUrl(env, '', 'http://example:1337'); + testProxyUrl(env, 'http://proxy', 'http://sub.example'); + testProxyUrl(env, 'http://proxy', 'http://prefexample'); + testProxyUrl(env, 'http://proxy', 'http://example.no'); + testProxyUrl(env, 'http://proxy', 'http://a.b.example'); + testProxyUrl(env, 'http://proxy', 'http://host/example'); + }); + + describe('no_proxy=sub.example (subdomain)', function() { + var env = {}; + env.HTTP_PROXY = 'http://proxy'; + + env.NO_PROXY = 'sub.example'; + testProxyUrl(env, 'http://proxy', 'http://example'); + testProxyUrl(env, 'http://proxy', 'http://example:80'); + testProxyUrl(env, 'http://proxy', 'http://example:0'); + testProxyUrl(env, 'http://proxy', 'http://example:1337'); + testProxyUrl(env, '', 'http://sub.example'); + testProxyUrl(env, 'http://proxy', 'http://no.sub.example'); + testProxyUrl(env, 'http://proxy', 'http://sub-example'); + testProxyUrl(env, 'http://proxy', 'http://example.sub'); + }); + + describe('no_proxy=example:80 (host + port)', function() { + var env = {}; + env.HTTP_PROXY = 'http://proxy'; + + env.NO_PROXY = 'example:80'; + testProxyUrl(env, '', 'http://example'); + testProxyUrl(env, '', 'http://example:80'); + testProxyUrl(env, '', 'http://example:0'); + testProxyUrl(env, 'http://proxy', 'http://example:1337'); + testProxyUrl(env, 'http://proxy', 'http://sub.example'); + testProxyUrl(env, 'http://proxy', 'http://prefexample'); + testProxyUrl(env, 'http://proxy', 'http://example.no'); + testProxyUrl(env, 'http://proxy', 'http://a.b.example'); + }); + + describe('no_proxy=.example (host suffix)', function() { + var env = {}; + env.HTTP_PROXY = 'http://proxy'; + + env.NO_PROXY = '.example'; + testProxyUrl(env, 'http://proxy', 'http://example'); + testProxyUrl(env, 'http://proxy', 'http://example:80'); + testProxyUrl(env, 'http://proxy', 'http://example:1337'); + testProxyUrl(env, '', 'http://sub.example'); + testProxyUrl(env, '', 'http://sub.example:80'); + testProxyUrl(env, '', 'http://sub.example:1337'); + testProxyUrl(env, 'http://proxy', 'http://prefexample'); + testProxyUrl(env, 'http://proxy', 'http://example.no'); + testProxyUrl(env, '', 'http://a.b.example'); + }); + + describe('no_proxy=*', function() { + var env = {}; + env.HTTP_PROXY = 'http://proxy'; + env.NO_PROXY = '*'; + testProxyUrl(env, '', 'http://example.com'); + }); + + describe('no_proxy=*.example (host suffix with *.)', function() { + var env = {}; + env.HTTP_PROXY = 'http://proxy'; + + env.NO_PROXY = '*.example'; + testProxyUrl(env, 'http://proxy', 'http://example'); + testProxyUrl(env, 'http://proxy', 'http://example:80'); + testProxyUrl(env, 'http://proxy', 'http://example:1337'); + testProxyUrl(env, '', 'http://sub.example'); + testProxyUrl(env, '', 'http://sub.example:80'); + testProxyUrl(env, '', 'http://sub.example:1337'); + testProxyUrl(env, 'http://proxy', 'http://prefexample'); + testProxyUrl(env, 'http://proxy', 'http://example.no'); + testProxyUrl(env, '', 'http://a.b.example'); + }); + + describe('no_proxy=*example (substring suffix)', function() { + var env = {}; + env.HTTP_PROXY = 'http://proxy'; + + env.NO_PROXY = '*example'; + testProxyUrl(env, '', 'http://example'); + testProxyUrl(env, '', 'http://example:80'); + testProxyUrl(env, '', 'http://example:1337'); + testProxyUrl(env, '', 'http://sub.example'); + testProxyUrl(env, '', 'http://sub.example:80'); + testProxyUrl(env, '', 'http://sub.example:1337'); + testProxyUrl(env, '', 'http://prefexample'); + testProxyUrl(env, '', 'http://a.b.example'); + testProxyUrl(env, 'http://proxy', 'http://example.no'); + testProxyUrl(env, 'http://proxy', 'http://host/example'); + }); + + describe('no_proxy=.*example (arbitrary wildcards are NOT supported)', + function() { + var env = {}; + env.HTTP_PROXY = 'http://proxy'; + + env.NO_PROXY = '.*example'; + testProxyUrl(env, 'http://proxy', 'http://example'); + testProxyUrl(env, 'http://proxy', 'http://sub.example'); + testProxyUrl(env, 'http://proxy', 'http://sub.example'); + testProxyUrl(env, 'http://proxy', 'http://prefexample'); + testProxyUrl(env, 'http://proxy', 'http://x.prefexample'); + testProxyUrl(env, 'http://proxy', 'http://a.b.example'); + }); + + describe('no_proxy=[::1],[::2]:80,10.0.0.1,10.0.0.2:80 (IP addresses)', + function() { + var env = {}; + env.HTTP_PROXY = 'http://proxy'; + + env.NO_PROXY = '[::1],[::2]:80,10.0.0.1,10.0.0.2:80'; + testProxyUrl(env, '', 'http://[::1]/'); + testProxyUrl(env, '', 'http://[::1]:80/'); + testProxyUrl(env, '', 'http://[::1]:1337/'); + + testProxyUrl(env, '', 'http://[::2]/'); + testProxyUrl(env, '', 'http://[::2]:80/'); + testProxyUrl(env, 'http://proxy', 'http://[::2]:1337/'); + + testProxyUrl(env, '', 'http://10.0.0.1/'); + testProxyUrl(env, '', 'http://10.0.0.1:80/'); + testProxyUrl(env, '', 'http://10.0.0.1:1337/'); + + testProxyUrl(env, '', 'http://10.0.0.2/'); + testProxyUrl(env, '', 'http://10.0.0.2:80/'); + testProxyUrl(env, 'http://proxy', 'http://10.0.0.2:1337/'); + }); + + describe('no_proxy=127.0.0.1/32 (CIDR is NOT supported)', function() { + var env = {}; + env.HTTP_PROXY = 'http://proxy'; + + env.NO_PROXY = '127.0.0.1/32'; + testProxyUrl(env, 'http://proxy', 'http://127.0.0.1'); + testProxyUrl(env, 'http://proxy', 'http://127.0.0.1/32'); + }); + + describe('no_proxy=127.0.0.1 does NOT match localhost', function() { + var env = {}; + env.HTTP_PROXY = 'http://proxy'; + + env.NO_PROXY = '127.0.0.1'; + testProxyUrl(env, '', 'http://127.0.0.1'); + // We're not performing DNS queries, so this shouldn't match. + testProxyUrl(env, 'http://proxy', 'http://localhost'); + }); + + describe('no_proxy with protocols that have a default port', function() { + var env = {}; + env.WS_PROXY = 'http://ws'; + env.WSS_PROXY = 'http://wss'; + env.HTTP_PROXY = 'http://http'; + env.HTTPS_PROXY = 'http://https'; + env.GOPHER_PROXY = 'http://gopher'; + env.FTP_PROXY = 'http://ftp'; + env.ALL_PROXY = 'http://all'; + + env.NO_PROXY = 'xxx:21,xxx:70,xxx:80,xxx:443'; + + testProxyUrl(env, '', 'http://xxx'); + testProxyUrl(env, '', 'http://xxx:80'); + testProxyUrl(env, 'http://http', 'http://xxx:1337'); + + testProxyUrl(env, '', 'ws://xxx'); + testProxyUrl(env, '', 'ws://xxx:80'); + testProxyUrl(env, 'http://ws', 'ws://xxx:1337'); + + testProxyUrl(env, '', 'https://xxx'); + testProxyUrl(env, '', 'https://xxx:443'); + testProxyUrl(env, 'http://https', 'https://xxx:1337'); + + testProxyUrl(env, '', 'wss://xxx'); + testProxyUrl(env, '', 'wss://xxx:443'); + testProxyUrl(env, 'http://wss', 'wss://xxx:1337'); + + testProxyUrl(env, '', 'gopher://xxx'); + testProxyUrl(env, '', 'gopher://xxx:70'); + testProxyUrl(env, 'http://gopher', 'gopher://xxx:1337'); + + testProxyUrl(env, '', 'ftp://xxx'); + testProxyUrl(env, '', 'ftp://xxx:21'); + testProxyUrl(env, 'http://ftp', 'ftp://xxx:1337'); + }); + + describe('no_proxy should not be case-sensitive', function() { + var env = {}; + env.HTTP_PROXY = 'http://proxy'; + env.NO_PROXY = 'XXX,YYY,ZzZ'; + + testProxyUrl(env, '', 'http://xxx'); + testProxyUrl(env, '', 'http://XXX'); + testProxyUrl(env, '', 'http://yyy'); + testProxyUrl(env, '', 'http://YYY'); + testProxyUrl(env, '', 'http://ZzZ'); + testProxyUrl(env, '', 'http://zZz'); + }); + + describe('NPM proxy configuration', function() { + describe('npm_config_http_proxy should work', function() { + var env = {}; + // eslint-disable-next-line camelcase + env.npm_config_http_proxy = 'http://http-proxy'; + + testProxyUrl(env, '', 'https://example'); + testProxyUrl(env, 'http://http-proxy', 'http://example'); + + // eslint-disable-next-line camelcase + env.npm_config_http_proxy = 'http://priority'; + testProxyUrl(env, 'http://priority', 'http://example'); + }); + // eslint-disable-next-line max-len + describe('npm_config_http_proxy should take precedence over HTTP_PROXY and npm_config_proxy', function() { + var env = {}; + // eslint-disable-next-line camelcase + env.npm_config_http_proxy = 'http://http-proxy'; + // eslint-disable-next-line camelcase + env.npm_config_proxy = 'http://unexpected-proxy'; + env.HTTP_PROXY = 'http://unexpected-proxy'; + + testProxyUrl(env, 'http://http-proxy', 'http://example'); + }); + describe('npm_config_https_proxy should work', function() { + var env = {}; + // eslint-disable-next-line camelcase + env.npm_config_http_proxy = 'http://unexpected.proxy'; + testProxyUrl(env, '', 'https://example'); + + // eslint-disable-next-line camelcase + env.npm_config_https_proxy = 'http://https-proxy'; + testProxyUrl(env, 'http://https-proxy', 'https://example'); + + // eslint-disable-next-line camelcase + env.npm_config_https_proxy = 'http://priority'; + testProxyUrl(env, 'http://priority', 'https://example'); + }); + // eslint-disable-next-line max-len + describe('npm_config_https_proxy should take precedence over HTTPS_PROXY and npm_config_proxy', function() { + var env = {}; + // eslint-disable-next-line camelcase + env.npm_config_https_proxy = 'http://https-proxy'; + // eslint-disable-next-line camelcase + env.npm_config_proxy = 'http://unexpected-proxy'; + env.HTTPS_PROXY = 'http://unexpected-proxy'; + + testProxyUrl(env, 'http://https-proxy', 'https://example'); + }); + describe('npm_config_proxy should work', function() { + var env = {}; + // eslint-disable-next-line camelcase + env.npm_config_proxy = 'http://http-proxy'; + testProxyUrl(env, 'http://http-proxy', 'http://example'); + testProxyUrl(env, 'http://http-proxy', 'https://example'); + + // eslint-disable-next-line camelcase + env.npm_config_proxy = 'http://priority'; + testProxyUrl(env, 'http://priority', 'http://example'); + testProxyUrl(env, 'http://priority', 'https://example'); + }); + // eslint-disable-next-line max-len + describe('HTTP_PROXY and HTTPS_PROXY should take precedence over npm_config_proxy', function() { + var env = {}; + env.HTTP_PROXY = 'http://http-proxy'; + env.HTTPS_PROXY = 'http://https-proxy'; + // eslint-disable-next-line camelcase + env.npm_config_proxy = 'http://unexpected-proxy'; + testProxyUrl(env, 'http://http-proxy', 'http://example'); + testProxyUrl(env, 'http://https-proxy', 'https://example'); + }); + describe('npm_config_no_proxy should work', function() { + var env = {}; + env.HTTP_PROXY = 'http://proxy'; + // eslint-disable-next-line camelcase + env.npm_config_no_proxy = 'example'; + + testProxyUrl(env, '', 'http://example'); + testProxyUrl(env, 'http://proxy', 'http://otherwebsite'); + }); + // eslint-disable-next-line max-len + describe('npm_config_no_proxy should take precedence over NO_PROXY', function() { + var env = {}; + env.HTTP_PROXY = 'http://proxy'; + env.NO_PROXY = 'otherwebsite'; + // eslint-disable-next-line camelcase + env.npm_config_no_proxy = 'example'; + + testProxyUrl(env, '', 'http://example'); + testProxyUrl(env, 'http://proxy', 'http://otherwebsite'); + }); + }); +}); |