pax_global_header00006660000000000000000000000064141227457100014515gustar00rootroot0000000000000052 comment=5368fa899134a9b0d7d49cc6917c1eecabe7aeb0 node-http-proxy-agent-5.0.0/000077500000000000000000000000001412274571000156745ustar00rootroot00000000000000node-http-proxy-agent-5.0.0/.editorconfig000066400000000000000000000013131412274571000203470ustar00rootroot00000000000000root = true [*] indent_style = tab indent_size = 4 tab_width = 4 end_of_line = lf charset = utf-8 trim_trailing_whitespace = true insert_final_newline = true [{*.json,*.json.example,*.gyp,*.yml,*.yaml,*.workflow}] indent_style = space indent_size = 2 [{*.py,*.asm}] indent_style = space [*.py] indent_size = 4 [*.asm] indent_size = 8 [*.md] trim_trailing_whitespace = false # Ideal settings - some plugins might support these. [*.js] quote_type = single [{*.c,*.cc,*.h,*.hh,*.cpp,*.hpp,*.m,*.mm,*.mpp,*.js,*.java,*.go,*.rs,*.php,*.ng,*.jsx,*.ts,*.d,*.cs,*.swift}] curly_bracket_next_line = false spaces_around_operators = true spaces_around_brackets = outside # close enough to 1TB indent_brace_style = K&R node-http-proxy-agent-5.0.0/.eslintrc.js000066400000000000000000000055671412274571000201500ustar00rootroot00000000000000module.exports = { 'extends': [ 'airbnb', 'prettier' ], 'parser': '@typescript-eslint/parser', 'parserOptions': { 'ecmaVersion': 2018, 'sourceType': 'module', 'modules': true }, 'plugins': [ '@typescript-eslint' ], 'settings': { 'import/resolver': { 'typescript': { } } }, 'rules': { 'quotes': [ 2, 'single', { 'allowTemplateLiterals': true } ], 'class-methods-use-this': 0, 'consistent-return': 0, 'func-names': 0, 'global-require': 0, 'guard-for-in': 0, 'import/no-duplicates': 0, 'import/no-dynamic-require': 0, 'import/no-extraneous-dependencies': 0, 'import/prefer-default-export': 0, 'lines-between-class-members': 0, 'no-await-in-loop': 0, 'no-bitwise': 0, 'no-console': 0, 'no-continue': 0, 'no-control-regex': 0, 'no-empty': 0, 'no-loop-func': 0, 'no-nested-ternary': 0, 'no-param-reassign': 0, 'no-plusplus': 0, 'no-restricted-globals': 0, 'no-restricted-syntax': 0, 'no-shadow': 0, 'no-underscore-dangle': 0, 'no-use-before-define': 0, 'prefer-const': 0, 'prefer-destructuring': 0, 'camelcase': 0, 'no-unused-vars': 0, // in favor of '@typescript-eslint/no-unused-vars' // 'indent': 0 // in favor of '@typescript-eslint/indent' '@typescript-eslint/no-unused-vars': 'warn', // '@typescript-eslint/indent': ['error', 2] // this might conflict with a lot ongoing changes '@typescript-eslint/no-array-constructor': 'error', '@typescript-eslint/adjacent-overload-signatures': 'error', '@typescript-eslint/class-name-casing': 'error', '@typescript-eslint/interface-name-prefix': 'error', '@typescript-eslint/no-empty-interface': 'error', '@typescript-eslint/no-inferrable-types': 'error', '@typescript-eslint/no-misused-new': 'error', '@typescript-eslint/no-namespace': 'error', '@typescript-eslint/no-non-null-assertion': 'error', '@typescript-eslint/no-parameter-properties': 'error', '@typescript-eslint/no-triple-slash-reference': 'error', '@typescript-eslint/prefer-namespace-keyword': 'error', '@typescript-eslint/type-annotation-spacing': 'error', // '@typescript-eslint/array-type': 'error', // '@typescript-eslint/ban-types': 'error', // '@typescript-eslint/explicit-function-return-type': 'warn', // '@typescript-eslint/explicit-member-accessibility': 'error', // '@typescript-eslint/member-delimiter-style': 'error', // '@typescript-eslint/no-angle-bracket-type-assertion': 'error', // '@typescript-eslint/no-explicit-any': 'warn', // '@typescript-eslint/no-object-literal-type-assertion': 'error', // '@typescript-eslint/no-use-before-define': 'error', // '@typescript-eslint/no-var-requires': 'error', // '@typescript-eslint/prefer-interface': 'error' } } node-http-proxy-agent-5.0.0/.github/000077500000000000000000000000001412274571000172345ustar00rootroot00000000000000node-http-proxy-agent-5.0.0/.github/workflows/000077500000000000000000000000001412274571000212715ustar00rootroot00000000000000node-http-proxy-agent-5.0.0/.github/workflows/test.yml000066400000000000000000000015141412274571000227740ustar00rootroot00000000000000name: Node CI on: push: branches: - master tags: - '!*' pull_request: jobs: build: name: Test Node.js ${{ matrix.node-version }} on ${{ matrix.os }} strategy: matrix: os: [ubuntu-latest, macos-latest, windows-latest] node-version: [6.x, 8.x, 10.x, 12.x] runs-on: ${{ matrix.os }} steps: - uses: actions/checkout@v1 - name: Use Node.js ${{ matrix.node-version }} uses: actions/setup-node@v1 with: node-version: ${{ matrix.node-version }} - name: Print Node.js Version run: node --version - name: Install Dependencies run: npm install env: CI: true - name: Run "build" step run: npm run build --if-present env: CI: true - name: Run tests run: npm test env: CI: true node-http-proxy-agent-5.0.0/.gitignore000066400000000000000000000000451412274571000176630ustar00rootroot00000000000000/dist /yarn.lock /node_modules /?.?s node-http-proxy-agent-5.0.0/README.md000066400000000000000000000047371412274571000171660ustar00rootroot00000000000000http-proxy-agent ================ ### An HTTP(s) proxy `http.Agent` implementation for HTTP [![Build Status](https://github.com/TooTallNate/node-http-proxy-agent/workflows/Node%20CI/badge.svg)](https://github.com/TooTallNate/node-http-proxy-agent/actions?workflow=Node+CI) This module provides an `http.Agent` implementation that connects to a specified HTTP or HTTPS proxy server, and can be used with the built-in `http` module. __Note:__ For HTTP proxy usage with the `https` module, check out [`node-https-proxy-agent`](https://github.com/TooTallNate/node-https-proxy-agent). Installation ------------ Install with `npm`: ``` bash $ npm install http-proxy-agent ``` Example ------- ``` js var url = require('url'); var http = require('http'); var HttpProxyAgent = require('http-proxy-agent'); // HTTP/HTTPS proxy to connect to var proxy = process.env.http_proxy || 'http://168.63.76.32:3128'; console.log('using proxy server %j', proxy); // HTTP endpoint for the proxy to connect to var endpoint = process.argv[2] || 'http://nodejs.org/api/'; console.log('attempting to GET %j', endpoint); var opts = url.parse(endpoint); // create an instance of the `HttpProxyAgent` class with the proxy server information var agent = new HttpProxyAgent(proxy); opts.agent = agent; http.get(opts, function (res) { console.log('"response" event!', res.headers); res.pipe(process.stdout); }); ``` License ------- (The MIT License) Copyright (c) 2013 Nathan Rajlich <nathan@tootallnate.net> 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. node-http-proxy-agent-5.0.0/package.json000066400000000000000000000026211412274571000201630ustar00rootroot00000000000000{ "name": "http-proxy-agent", "version": "5.0.0", "description": "An HTTP(s) proxy `http.Agent` implementation for HTTP", "main": "./dist/index.js", "types": "./dist/index.d.ts", "files": [ "dist" ], "scripts": { "prebuild": "rimraf dist", "build": "tsc", "test": "mocha", "test-lint": "eslint src --ext .js,.ts", "prepublishOnly": "npm run build" }, "repository": { "type": "git", "url": "git://github.com/TooTallNate/node-http-proxy-agent.git" }, "keywords": [ "http", "proxy", "endpoint", "agent" ], "author": "Nathan Rajlich (http://n8.io/)", "license": "MIT", "bugs": { "url": "https://github.com/TooTallNate/node-http-proxy-agent/issues" }, "dependencies": { "@tootallnate/once": "2", "agent-base": "6", "debug": "4" }, "devDependencies": { "@types/debug": "4", "@types/node": "^12.19.2", "@typescript-eslint/eslint-plugin": "1.6.0", "@typescript-eslint/parser": "1.1.0", "eslint": "5.16.0", "eslint-config-airbnb": "17.1.0", "eslint-config-prettier": "4.1.0", "eslint-import-resolver-typescript": "1.1.1", "eslint-plugin-import": "2.16.0", "eslint-plugin-jsx-a11y": "6.2.1", "eslint-plugin-react": "7.12.4", "mocha": "^6.2.2", "proxy": "1", "rimraf": "^3.0.0", "typescript": "^4.4.3" }, "engines": { "node": ">= 6" } } node-http-proxy-agent-5.0.0/src/000077500000000000000000000000001412274571000164635ustar00rootroot00000000000000node-http-proxy-agent-5.0.0/src/agent.ts000066400000000000000000000115231412274571000201330ustar00rootroot00000000000000import net from 'net'; import tls from 'tls'; import url from 'url'; import createDebug from 'debug'; import once from '@tootallnate/once'; import { Agent, ClientRequest, RequestOptions } from 'agent-base'; import { HttpProxyAgentOptions } from '.'; const debug = createDebug('http-proxy-agent'); interface HttpProxyAgentClientRequest extends ClientRequest { path: string; output?: string[]; outputData?: { data: string; }[]; _header?: string | null; _implicitHeader(): void; } function isHTTPS(protocol?: string | null): boolean { return typeof protocol === 'string' ? /^https:?$/i.test(protocol) : false; } /** * The `HttpProxyAgent` implements an HTTP Agent subclass that connects * to the specified "HTTP proxy server" in order to proxy HTTP requests. * * @api public */ export default class HttpProxyAgent extends Agent { private secureProxy: boolean; private proxy: HttpProxyAgentOptions; constructor(_opts: string | HttpProxyAgentOptions) { let opts: HttpProxyAgentOptions; if (typeof _opts === 'string') { opts = url.parse(_opts); } else { opts = _opts; } if (!opts) { throw new Error( 'an HTTP(S) proxy server `host` and `port` must be specified!' ); } debug('Creating new HttpProxyAgent instance: %o', opts); super(opts); const proxy: HttpProxyAgentOptions = { ...opts }; // If `true`, then connect to the proxy server over TLS. // Defaults to `false`. this.secureProxy = opts.secureProxy || isHTTPS(proxy.protocol); // Prefer `hostname` over `host`, and set the `port` if needed. proxy.host = proxy.hostname || proxy.host; if (typeof proxy.port === 'string') { proxy.port = parseInt(proxy.port, 10); } if (!proxy.port && proxy.host) { proxy.port = this.secureProxy ? 443 : 80; } if (proxy.host && proxy.path) { // If both a `host` and `path` are specified then it's most likely // the result of a `url.parse()` call... we need to remove the // `path` portion so that `net.connect()` doesn't attempt to open // that as a Unix socket file. delete proxy.path; delete proxy.pathname; } this.proxy = proxy; } /** * Called when the node-core HTTP client library is creating a * new HTTP request. * * @api protected */ async callback( req: HttpProxyAgentClientRequest, opts: RequestOptions ): Promise { const { proxy, secureProxy } = this; const parsed = url.parse(req.path); if (!parsed.protocol) { parsed.protocol = 'http:'; } if (!parsed.hostname) { parsed.hostname = opts.hostname || opts.host || null; } if (parsed.port == null && typeof opts.port) { parsed.port = String(opts.port); } if (parsed.port === '80') { // if port is 80, then we can remove the port so that the // ":80" portion is not on the produced URL parsed.port = ''; } // Change the `http.ClientRequest` instance's "path" field // to the absolute path of the URL that will be requested. req.path = url.format(parsed); // Inject the `Proxy-Authorization` header if necessary. if (proxy.auth) { req.setHeader( 'Proxy-Authorization', `Basic ${Buffer.from(proxy.auth).toString('base64')}` ); } // Create a socket connection to the proxy server. let socket: net.Socket; if (secureProxy) { debug('Creating `tls.Socket`: %o', proxy); socket = tls.connect(proxy as tls.ConnectionOptions); } else { debug('Creating `net.Socket`: %o', proxy); socket = net.connect(proxy as net.NetConnectOpts); } // At this point, the http ClientRequest's internal `_header` field // might have already been set. If this is the case then we'll need // to re-generate the string since we just changed the `req.path`. if (req._header) { let first: string; let endOfHeaders: number; debug('Regenerating stored HTTP header string for request'); req._header = null; req._implicitHeader(); if (req.output && req.output.length > 0) { // Node < 12 debug( 'Patching connection write() output buffer with updated header' ); first = req.output[0]; endOfHeaders = first.indexOf('\r\n\r\n') + 4; req.output[0] = req._header + first.substring(endOfHeaders); debug('Output buffer: %o', req.output); } else if (req.outputData && req.outputData.length > 0) { // Node >= 12 debug( 'Patching connection write() output buffer with updated header' ); first = req.outputData[0].data; endOfHeaders = first.indexOf('\r\n\r\n') + 4; req.outputData[0].data = req._header + first.substring(endOfHeaders); debug('Output buffer: %o', req.outputData[0].data); } } // Wait for the socket's `connect` event, so that this `callback()` // function throws instead of the `http` request machinery. This is // important for i.e. `PacProxyAgent` which determines a failed proxy // connection via the `callback()` function throwing. await once(socket, 'connect'); return socket; } } node-http-proxy-agent-5.0.0/src/index.ts000066400000000000000000000016051412274571000201440ustar00rootroot00000000000000import net from 'net'; import tls from 'tls'; import { Url } from 'url'; import { AgentOptions } from 'agent-base'; import _HttpProxyAgent from './agent'; function createHttpProxyAgent( opts: string | createHttpProxyAgent.HttpProxyAgentOptions ): _HttpProxyAgent { return new _HttpProxyAgent(opts); } namespace createHttpProxyAgent { interface BaseHttpProxyAgentOptions { secureProxy?: boolean; host?: string | null; path?: string | null; port?: string | number | null; } export interface HttpProxyAgentOptions extends AgentOptions, BaseHttpProxyAgentOptions, Partial< Omit< Url & net.NetConnectOpts & tls.ConnectionOptions, keyof BaseHttpProxyAgentOptions > > {} export type HttpProxyAgent = _HttpProxyAgent; export const HttpProxyAgent = _HttpProxyAgent; createHttpProxyAgent.prototype = _HttpProxyAgent.prototype; } export = createHttpProxyAgent; node-http-proxy-agent-5.0.0/test/000077500000000000000000000000001412274571000166535ustar00rootroot00000000000000node-http-proxy-agent-5.0.0/test/ssl-cert-snakeoil.key000066400000000000000000000015671412274571000227350ustar00rootroot00000000000000-----BEGIN RSA PRIVATE KEY----- MIICWwIBAAKBgQCzURxIqzer0ACAbX/lHdsn4Gd9PLKrf7EeDYfIdV0HZKPD8WDr bBx2/fBu0OW2sjnzv/SVZbJ0DAuPE/p0+eT0qb2qC10iz9iTD7ribd7gxhirVb8y b3fBjXsxc8V8p4Ny1LcvNSqCjwUbJqdRogfoJeTiqPM58z5sNzuv5iq7iwIDAQAB AoGAPMQy4olrP0UotlzlJ36bowLP70ffgHCwU+/f4NWs5fF78c3du0oSx1w820Dd Z7E0JF8bgnlJJTxjumPZz0RUCugrEHBKJmzEz3cxF5E3+7NvteZcjKn9D67RrM5x 1/uSZ9cqKE9cYvY4fSuHx18diyZ4axR/wB1Pea2utjjDM+ECQQDb9ZbmmaWMiRpQ 5Up+loxP7BZNPsEVsm+DVJmEFbaFgGfncWBqSIqnPNjMwTwj0OigTwCAEGPkfRVW T0pbYWCxAkEA0LK7SCTwzyDmhASUalk0x+3uCAA6ryFdwJf/wd8TRAvVOmkTEldX uJ7ldLvfrONYO3v56uKTU/SoNdZYzKtO+wJAX2KM4ctXYy5BXztPpr2acz4qHa1N Bh+vBAC34fOYhyQ76r3b1btHhWZ5jbFuZwm9F2erC94Ps5IaoqcX07DSwQJAPKGw h2U0EPkd/3zVIZCJJQya+vgWFIs9EZcXVtvYXQyTBkVApTN66MhBIYjzkub5205J bVQmOV37AKklY1DhwQJAA1wos0cYxro02edzatxd0DIR2r4qqOqLkw6BhYHhq6HJ ZvIcQkHqdSXzdETFc01I1znDGGIrJHcnvKWgBPoEUg== -----END RSA PRIVATE KEY----- node-http-proxy-agent-5.0.0/test/ssl-cert-snakeoil.pem000066400000000000000000000012701412274571000227150ustar00rootroot00000000000000-----BEGIN CERTIFICATE----- MIIB1TCCAT4CCQDV5mPlzm9+izANBgkqhkiG9w0BAQUFADAvMS0wKwYDVQQDEyQ3 NTI3YmQ3Ny1hYjNlLTQ3NGItYWNlNy1lZWQ2MDUzOTMxZTcwHhcNMTUwNzA2MjI0 NTA3WhcNMjUwNzAzMjI0NTA3WjAvMS0wKwYDVQQDEyQ3NTI3YmQ3Ny1hYjNlLTQ3 NGItYWNlNy1lZWQ2MDUzOTMxZTcwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGB ALNRHEirN6vQAIBtf+Ud2yfgZ308sqt/sR4Nh8h1XQdko8PxYOtsHHb98G7Q5bay OfO/9JVlsnQMC48T+nT55PSpvaoLXSLP2JMPuuJt3uDGGKtVvzJvd8GNezFzxXyn g3LUty81KoKPBRsmp1GiB+gl5OKo8znzPmw3O6/mKruLAgMBAAEwDQYJKoZIhvcN AQEFBQADgYEACzoHUF8UV2Z6541Q2wKEA0UFUzmUjf/E1XwBO+1P15ZZ64uw34B4 1RwMPtAo9RY/PmICTWtNxWGxkzwb2JtDWtnxVER/lF8k2XcXPE76fxTHJF/BKk9J QU8OTD1dd9gHCBviQB9TqntRZ5X7axjtuWjb2umY+owBYzAHZkp1HKI= -----END CERTIFICATE----- node-http-proxy-agent-5.0.0/test/test.js000066400000000000000000000243131412274571000201730ustar00rootroot00000000000000/** * Module dependencies. */ const fs = require('fs'); const net = require('net'); const url = require('url'); const http = require('http'); const https = require('https'); const assert = require('assert'); const Proxy = require('proxy'); const { Agent } = require('agent-base'); const { HttpProxyAgent } = require('../'); const sleep = n => new Promise(r => setTimeout(r, n)); describe('HttpProxyAgent', function() { let server; let serverPort; let proxy; let proxyPort; let sslProxy; let sslProxyPort; before(function(done) { // setup HTTP proxy server proxy = Proxy(); proxy.listen(function() { proxyPort = proxy.address().port; done(); }); }); before(function(done) { // setup target HTTP server server = http.createServer(); server.listen(function() { serverPort = server.address().port; done(); }); }); beforeEach(function() { server.removeAllListeners('request'); }); before(function(done) { // setup SSL HTTP proxy server let options = { key: fs.readFileSync(`${__dirname}/ssl-cert-snakeoil.key`), cert: fs.readFileSync(`${__dirname}/ssl-cert-snakeoil.pem`) }; sslProxy = Proxy(https.createServer(options)); sslProxy.listen(function() { sslProxyPort = sslProxy.address().port; done(); }); }); // shut down test HTTP server after(function(done) { proxy.once('close', function() { done(); }); proxy.close(); }); after(function(done) { server.once('close', function() { done(); }); server.close(); }); after(function(done) { sslProxy.once('close', function() { done(); }); sslProxy.close(); }); describe('constructor', function() { it('should throw an Error if no "proxy" argument is given', function() { assert.throws(function() { new HttpProxyAgent(); }); }); it('should accept a "string" proxy argument', function() { let agent = new HttpProxyAgent(`http://127.0.0.1:${proxyPort}`); assert.equal('127.0.0.1', agent.proxy.host); assert.equal(proxyPort, agent.proxy.port); }); it('should accept a `url.parse()` result object argument', function() { let opts = url.parse(`http://127.0.0.1:${proxyPort}`); let agent = new HttpProxyAgent(opts); assert.equal('127.0.0.1', agent.proxy.host); assert.equal(proxyPort, agent.proxy.port); }); it('should set a `defaultPort` property', function() { let opts = url.parse(`http://127.0.0.1:${proxyPort}`); let agent = new HttpProxyAgent(opts); assert.equal(80, agent.defaultPort); }); describe('secureProxy', function() { it('should default to `false`', function() { let agent = new HttpProxyAgent({ port: proxyPort }); assert.equal(false, agent.secureProxy); }); it('should be `false` when "http:" protocol is used', function() { let agent = new HttpProxyAgent({ port: proxyPort, protocol: 'http:' }); assert.equal(false, agent.secureProxy); }); it('should be `true` when "https:" protocol is used', function() { let agent = new HttpProxyAgent({ port: proxyPort, protocol: 'https:' }); assert.equal(true, agent.secureProxy); }); it('should be `true` when "https" protocol is used', function() { let agent = new HttpProxyAgent({ port: proxyPort, protocol: 'https' }); assert.equal(true, agent.secureProxy); }); it('should support a `defaultPort` option', function() { let agent = new HttpProxyAgent({ port: proxyPort, secureProxy: true }); assert.equal(true, agent.secureProxy); }); }); }); describe('"http" module', function() { it('should work over an HTTP proxy', function(done) { // set HTTP "request" event handler for this test server.once('request', function(req, res) { res.end(JSON.stringify(req.headers)); }); let proxy = process.env.HTTP_PROXY || process.env.http_proxy || `http://127.0.0.1:${proxyPort}`; let agent = new HttpProxyAgent(proxy); let opts = url.parse(`http://127.0.0.1:${serverPort}`); opts.agent = agent; http.get(opts, function(res) { let data = ''; res.setEncoding('utf8'); res.on('data', function(b) { data += b; }); res.on('end', function() { data = JSON.parse(data); assert.equal(`127.0.0.1:${serverPort}`, data.host); assert('via' in data); done(); }); }); }); it('should work over an HTTPS proxy', function(done) { // set HTTP "request" event handler for this test server.once('request', function(req, res) { res.end(JSON.stringify(req.headers)); }); let proxy = process.env.HTTPS_PROXY || process.env.https_proxy || `https://127.0.0.1:${sslProxyPort}`; proxy = url.parse(proxy); proxy.rejectUnauthorized = false; let agent = new HttpProxyAgent(proxy); assert.equal(true, agent.secureProxy); let opts = url.parse(`http://127.0.0.1:${serverPort}`); opts.agent = agent; http.get(opts, function(res) { let data = ''; res.setEncoding('utf8'); res.on('data', function(b) { data += b; }); res.on('end', function() { data = JSON.parse(data); assert.equal(`127.0.0.1:${serverPort}`, data.host); assert('via' in data); done(); }); }); }); it('should proxy the query string of the request path', function(done) { // set HTTP "request" event handler for this test server.once('request', function(req, res) { res.end( JSON.stringify({ url: req.url }) ); }); let proxy = process.env.HTTP_PROXY || process.env.http_proxy || `http://127.0.0.1:${proxyPort}`; let agent = new HttpProxyAgent(proxy); let opts = url.parse( `http://127.0.0.1:${serverPort}/test?foo=bar&1=2` ); opts.agent = agent; http.get(opts, function(res) { let data = ''; res.setEncoding('utf8'); res.on('data', function(b) { data += b; }); res.on('end', function() { data = JSON.parse(data); assert.equal('/test?foo=bar&1=2', data.url); done(); }); }); }); it('should receive the 407 authorization code on the `http.ClientResponse`', function(done) { // set a proxy authentication function for this test proxy.authenticate = function(req, fn) { // reject all requests fn(null, false); }; let proxyUri = process.env.HTTP_PROXY || process.env.http_proxy || `http://127.0.0.1:${proxyPort}`; let agent = new HttpProxyAgent(proxyUri); let opts = {}; // `host` and `port` don't really matter since the proxy will reject anyways opts.host = '127.0.0.1'; opts.port = 80; opts.agent = agent; http.get(opts, function(res) { assert.equal(407, res.statusCode); assert('proxy-authenticate' in res.headers); delete proxy.authenticate; done(); }); }); it('should send the "Proxy-Authorization" request header', function(done) { // set a proxy authentication function for this test proxy.authenticate = function(req, fn) { // username:password is "foo:bar" fn( null, req.headers['proxy-authorization'] == 'Basic Zm9vOmJhcg==' ); }; // set HTTP "request" event handler for this test server.once('request', function(req, res) { res.end(JSON.stringify(req.headers)); }); let proxyUri = process.env.HTTP_PROXY || process.env.http_proxy || `http://127.0.0.1:${proxyPort}`; let proxyOpts = url.parse(proxyUri); proxyOpts.auth = 'foo:bar'; let agent = new HttpProxyAgent(proxyOpts); let opts = url.parse(`http://127.0.0.1:${serverPort}`); opts.agent = agent; http.get(opts, function(res) { let data = ''; res.setEncoding('utf8'); res.on('data', function(b) { data += b; }); res.on('end', function() { data = JSON.parse(data); assert.equal(`127.0.0.1:${serverPort}`, data.host); assert('via' in data); delete proxy.authenticate; done(); }); }); }); it('should emit an "error" event on the `http.ClientRequest` if the proxy does not exist', function(done) { // port 4 is a reserved, but "unassigned" port let proxyUri = 'http://127.0.0.1:4'; let agent = new HttpProxyAgent(proxyUri); let opts = url.parse('http://nodejs.org'); opts.agent = agent; let req = http.get(opts); req.once('error', function(err) { assert.equal('ECONNREFUSED', err.code); req.abort(); done(); }); }); it('should work after the first tick of the `http.ClientRequest` instance', function(done) { // set HTTP "request" event handler for this test server.once('request', function(req, res) { res.end(JSON.stringify(req.url)); }); let proxy = process.env.HTTP_PROXY || process.env.http_proxy || `http://127.0.0.1:${proxyPort}`; let httpProxyAgent = new HttpProxyAgent(proxy); // Defer the "connect()" function logic, since calling `req.end()` // before the socket is returned causes the HTTP header to be // generated *before* `HttpProxyAgent` can patch the `req.path` // property, making the header incorrect. const sleepAgent = new Agent((req, opts) => { assert.equal(opts.secureEndpoint, false); assert.equal(opts.protocol, 'http:'); assert(!req._header); return sleep(10).then(() => { assert.equal(typeof req._header, 'string'); return httpProxyAgent; }); }); const opts = url.parse(`http://127.0.0.1:${serverPort}/test`); opts.agent = sleepAgent; http.get(opts, function(res) { let data = ''; res.setEncoding('utf8'); res.on('data', function(b) { data += b; }); res.on('end', function() { data = JSON.parse(data); assert.equal('/test', data); done(); }); }); }); it('should not send a port number for the default port', function(done) { server.once('request', function(req, res) { res.end(JSON.stringify(req.headers)); }); let proxy = process.env.HTTP_PROXY || process.env.http_proxy || `http://127.0.0.1:${proxyPort}`; proxy = url.parse(proxy); let agent = new HttpProxyAgent(proxy); agent.defaultPort = serverPort; let opts = url.parse(`http://127.0.0.1:${serverPort}`); opts.agent = agent; http.get(opts, function(res) { let data = ''; res.setEncoding('utf8'); res.on('data', function(b) { data += b; }); res.on('end', function() { data = JSON.parse(data); assert.equal('127.0.0.1', data.host); done(); }); }); }); }); }); node-http-proxy-agent-5.0.0/tsconfig.json000066400000000000000000000005421412274571000204040ustar00rootroot00000000000000{ "compilerOptions": { "strict": true, "module": "CommonJS", "target": "es2015", "esModuleInterop": true, "lib": ["esnext"], "outDir": "dist", "sourceMap": true, "declaration": true, "typeRoots": [ "./@types", "./node_modules/@types" ] }, "include": ["src/**/*"], "exclude": ["node_modules"] }