{"_id":"@asendia/proxy-chain","_rev":"2-4b18ff75a2004d1667c7c022e70495b2","name":"@asendia/proxy-chain","dist-tags":{"latest":"0.1.31","beta":"0.2.31"},"versions":{"0.1.31":{"name":"@asendia/proxy-chain","version":"0.1.31","description":"Node.js implementation of a proxy server (think Squid) with support for SSL, authentication, upstream proxy chaining, and protocol tunneling.","main":"build/index.js","keywords":["proxy","squid","apify","tunnel"],"author":{"name":"Apify","email":"support@apify.com","url":"https://www.apify.com"},"contributors":[{"name":"Jan Curn","email":"jan@apify.com"}],"license":"Apache-2.0","repository":{"type":"git","url":"git+https://github.com/apifytech/proxy-chain.git"},"bugs":{"url":"https://github.com/apifytech/proxy-chain/issues"},"homepage":"https://blog.apify.com/how-to-make-headless-chrome-and-puppeteer-use-a-proxy-server-with-authentication-249a21a79212","files":["build"],"scripts":{"build":"rm -rf ./build && babel src --out-dir build","local-proxy":"npm run build && node ./build/run_locally.js","test":"npm run build && mocha --compilers js:babel-core/register --recursive","prepare":"npm run build","clean":"rm -rf build","lint":"npm run build && eslint src"},"dependencies":{"bluebird":"^3.5.1","portastic":"^1.0.1","underscore":"^1.8.3"},"devDependencies":{"babel-cli":"^6.6.5","babel-core":"^6.1.21","babel-eslint":"^7.2.2","babel-preset-es2015":"^6.1.18","babel-preset-stage-0":"^6.1.18","basic-auth":"^2.0.0","body-parser":"^1.18.2","chai":"^4.0.2","eslint":"^3.19.0","eslint-config-airbnb":"^15.0.1","eslint-config-airbnb-base":"^11.1.0","eslint-plugin-import":"^2.2.0","eslint-plugin-jsx-a11y":"^5.0.3","eslint-plugin-promise":"^3.4.2","eslint-plugin-react":"^7.0.1","express":"^4.16.2","https-proxy-agent":"^2.1.0","isparta":"^4.0.0","mocha":"^3.2.0","phantomjs-prebuilt":"^2.1.16","proxy":"^0.2.4","request":"^2.83.0","sinon":"^2.2.0","sinon-stub-promise":"^4.0.0","through":"^2.3.8","ws":"^3.3.1"},"optionalDependencies":{},"gitHead":"042fbeb157c608a83447d5bc5809abd09abb703e","_id":"@asendia/proxy-chain@0.1.31","_npmVersion":"5.8.0","_nodeVersion":"9.8.0","_npmUser":{"name":"asendia","email":"asendia@me.com"},"dist":{"integrity":"sha512-dkXFkigicidgS6kX82OtxBOsbZWyeq/4K+16yvgyT5pZPiLWCP8yQem5OQ7cf4ym4JgIblo02tYElKzJBqdjiA==","shasum":"e75943c52334d1fbbc99c36b011fe7e1c6d531f6","tarball":"https://registry.npmjs.org/@asendia/proxy-chain/-/proxy-chain-0.1.31.tgz","fileCount":16,"unpackedSize":105773,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbDAshCRA9TVsSAnZWagAA1+8P/RbtQLfyWYnsFqeh07hN\nsRjYBAX4L7dQfJPGg503+69/PxIGlNCLhflXUguU8iJU/4OnQL24gwT2T7fo\nVLrnd0G0My44ZjvrvNmb67gC74VJLDCw2ORGqeVngn2rzdhJQbl3ZN4JisAk\nzT+ww0If3+j6FunZefq4AnsT4BJk1tGaz/aKFynkD/CU+EQIXcJ3Dax8EzcX\npswmkGmCApWEcjJ0N1eZtW+nWPTGq/tJPB7GbnRPZnOjfHY7GtMwrvC9OIhu\nhwyOXVZRitNZ0DHSSXJxRavCPUxcLG489IfLUEVURzCl8Q5rD1+tFBTb5KFK\nwk+kaW6MEuOdNi6SZr6kDja7ilB5CgV9HTND+BnsnpSxTgdwsxLFn2RaN38i\nAZruMwtd+JS/ojS1SXNcErADyTgJpuEgPB27d5otuJYG6qGd9g1rhz0sFhh0\n7J8MGdn5ewxWIIEkQLX7I5jNW9TYYJrJZxAJpSpehuWXxAN0fadx1kCdT8aa\n1bymJ+x6UorD9/h29DiAxM6G68Xeh9hlBKX2fWIe639vC58Fd2B5QFacP27q\n2GgLsL9YU0cg1C+gqG40he73zeCCwOhkAmEeY6X5dRrU8EiVuP5UqtvMJoUz\nweF2pBFBTV3IqYOUsbw+UfmipHR67EP+Kg75JzYYPSt/u7VTO+VYSI7sjAxu\ny284\r\n=zKdP\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEUCIQDpbhtB2o/cyk0TVTX5mSeAFRN21jmh0sRICBif7Zc55wIgDF5cNgHR8KVTjk0CpruMxQhKCEz6rQAUFvB7qPdqag4="}]},"maintainers":[{"name":"asendia","email":"asendia@me.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/proxy-chain_0.1.31_1527515935975_0.6767969095160982"},"_hasShrinkwrap":false},"0.2.31":{"name":"@asendia/proxy-chain","version":"0.2.31","description":"Node.js implementation of a proxy server (think Squid) with support for SSL, authentication, upstream proxy chaining, and protocol tunneling.","main":"build/index.js","keywords":["proxy","squid","apify","tunnel"],"author":{"name":"Apify","email":"support@apify.com","url":"https://www.apify.com"},"contributors":[{"name":"Jan Curn","email":"jan@apify.com"}],"license":"Apache-2.0","repository":{"type":"git","url":"git+https://github.com/apifytech/proxy-chain.git"},"bugs":{"url":"https://github.com/apifytech/proxy-chain/issues"},"homepage":"https://blog.apify.com/how-to-make-headless-chrome-and-puppeteer-use-a-proxy-server-with-authentication-249a21a79212","files":["build"],"scripts":{"build":"rm -rf ./build && babel src --out-dir build","local-proxy":"npm run build && node ./build/run_locally.js","test":"npm run build && mocha --compilers js:@babel/register --recursive","prepublishOnly":"(test $RUNNING_FROM_SCRIPT || (echo \"You must use publish.sh instead of 'npm publish' directly!\"; exit 1)) && npm test && npm run lint","prepare":"npm run build","clean":"rm -rf build","lint":"npm run build && eslint src"},"dependencies":{"underscore":"^1.8.3"},"devDependencies":{"@babel/cli":"^7.0.0-beta.49","@babel/core":"^7.0.0-beta.49","@babel/preset-env":"^7.0.0-beta.49","@babel/register":"^7.0.0-beta.49","basic-auth":"^2.0.0","body-parser":"^1.18.2","chai":"^4.0.2","eslint":"^3.19.0","eslint-config-airbnb":"^15.0.1","eslint-config-airbnb-base":"^11.1.0","eslint-plugin-import":"^2.2.0","eslint-plugin-jsx-a11y":"^5.0.3","eslint-plugin-promise":"^3.4.2","eslint-plugin-react":"^7.0.1","express":"^4.16.2","https-proxy-agent":"^2.1.0","isparta":"^4.0.0","mocha":"^3.2.0","phantomjs-prebuilt":"^2.1.16","proxy":"^0.2.4","request":"^2.83.0","sinon":"^2.2.0","sinon-stub-promise":"^4.0.0","through":"^2.3.8","ws":"^3.3.1"},"optionalDependencies":{},"readme":"# Programmable HTTP proxy server for Node.js\n\n[![npm version](https://badge.fury.io/js/proxy-chain.svg)](http://badge.fury.io/js/proxy-chain)\n[![Build Status](https://travis-ci.org/apifytech/proxy-chain.svg)](https://travis-ci.org/apifytech/proxy-chain)\n\nNode.js implementation of a proxy server (think Squid) with support for SSL, authentication and upstream proxy chaining.\nThe authentication and proxy chaining configuration is defined in code and can be dynamic.\nNote that the proxy server only supports Basic authentication\n(see [Proxy-Authorization](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Proxy-Authorization) for details).\n\nFor example, this package is useful if you need to use proxies with authentication\nin the headless Chrome web browser, because it doesn't accept proxy URLs such as `http://username:password@proxy.example.com:8080`.\nWith this library, you can setup a local proxy server without any password\nthat will forward requests to the upstream proxy with password.\nFor this very purpose the package is used by the [Apify web scraping platform](https://www.apify.com).\n\nTo learn more about the rationale behind this package,\nread [How to make headless Chrome and Puppeteer use a proxy server with authentication](https://medium.com/@jancurn/how-to-make-headless-chrome-and-puppeteer-use-a-proxy-server-with-authentication-249a21a79212).\n\n\n## Run a simple HTTP/HTTPS proxy server\n\n```javascript\nconst ProxyChain = require('proxy-chain');\n\nconst server = new ProxyChain.Server({ port: 8000 });\n\nserver.listen(() => {\n    console.log(`Proxy server is listening on port ${8000}`);\n});\n```\n\n## Run a HTTP/HTTPS proxy server with credentials and upstream proxy\n\n```javascript\nconst ProxyChain = require('proxy-chain');\n\nconst server = new ProxyChain.Server({\n    // Port where the server the server will listen. By default 8000.\n    port: 8000,\n\n    // Enables verbose logging\n    verbose: true,\n\n    // Custom function to authenticate proxy requests and provide the URL to chained upstream proxy.\n    // It must return an object (or promise resolving to the object) with following form:\n    // { requestAuthentication: Boolean, upstreamProxyUrl: String }\n    // If the function is not defined or is null, the server runs in a simple mode.\n    // Note that the function takes a single argument with the following properties:\n    // * request  - An instance of http.IncomingMessage class with information about the client request\n    //              (which is either HTTP CONNECT for SSL protocol, or other HTTP request)\n    // * username - Username parsed from the Proxy-Authorization header. Might be empty string.\n    // * password - Password parsed from the Proxy-Authorization header. Might be empty string.\n    // * hostname - Hostname of the target server\n    // * port     - Port of the target server\n    // * isHttp   - If true, this is a HTTP request, otherwise it's a HTTP CONNECT tunnel for SSL\n    //              or other protocols\n    prepareRequestFunction: ({ request, username, password, hostname, port, isHttp }) => {\n        return {\n            // Require clients to authenticate with username 'bob' and password 'TopSecret'\n            requestAuthentication: username !== 'bob' || password !== 'TopSecret',\n\n            // Sets up an upstream HTTP proxy to which all the requests are forwarded.\n            // If null, the proxy works in direct mode.\n            upstreamProxyUrl: `http://username:password@proxy.example.com:3128`,\n        };\n    },\n});\n\nserver.listen(() => {\n  console.log(`Proxy server is listening on port ${8000}`);\n});\n```\n\n## Closing the server\n\nTo shutdown the proxy server, call the `close([destroyConnections], [callback])` function. For example:\n\n```javascript\nserver.close(true, () => {\n  console.log('Proxy server was closed.');\n});\n```\n\nThe `closeConnections` parameter indicates whether pending proxy connections should be forcibly closed.\nIf the `callback` parameter is omitted, the function returns a promise.\n\n\n## Helper functions\n\nThe package also provides several utility functions.\n\n\n### `anonymizeProxy(proxyUrl, callback)`\n\nParses and validates a HTTP proxy URL. If the proxy requires authentication,\nthen the function starts an open local proxy server that forwards to the proxy.\nThe port is chosen randomly.\n\nThe function takes optional callback that receives the anonymous proxy URL.\nIf no callback is supplied, the function returns a promise that resolves to a String with\nanonymous proxy URL or the original URL if it was already anonymous.\n\n\n### `closeAnonymizedProxy(anonymizedProxyUrl, closeConnections, callback)`\n\nCloses anonymous proxy previously started by `anonymizeProxy()`.\nIf proxy was not found or was already closed, the function has no effect\nand its result if `false`. Otherwise the result is `true`.\n\nThe `closeConnections` parameter indicates whether pending proxy connections are forcibly closed.\n\nThe function takes optional callback that receives the result Boolean from the function.\nIf callback is not provided, the function returns a promise instead.\n\n### `createTunnel(proxyUrl, target, options, callback)`\n\nAttempts to create a network tunnel through proxy server specified in param \"proxyUrl\" to a network service\nspecified in param \"target\".\n\nThe function takes optional callback that receives the path to local service.\nIf no callback is supplied, the function returns a promise that resolves to a String with\nthe path to local service.\n\nExample usage:\n\n```javascript\nconst tunnel = await createTunnel('http://<username>:<password>@<proxy-server>:<port>', '<service-host>:<service-port>');\n// tunnel will be in format \"localhost:<randomly-assigned-port>\" and while it's running\n// it can be used instead of '<service-host>:<service-port>' to proxy requests.\n```\n\n### `closeTunnel(tunnelString, closeConnections, callback)`\n\nCloses tunnel previously started by `createTunnel()`.\nReturns false if tunnel is not found or running. Otherwise the result is `true`.\n\nThe `closeConnections` parameter indicates whether pending connections are forcibly closed.\n\nThe function takes optional callback that receives the result Boolean from the function.\nIf callback is not provided, the function returns a promise instead.\n\n### `parseUrl(url)`\n\nCalls Node.js's [url.parse](https://nodejs.org/docs/latest/api/url.html#url_url_parse_urlstring_parsequerystring_slashesdenotehost)\nfunction and extends the resulting object with the following fields: `scheme`, `username` and `password`.\nFor example, for `HTTP://bob:pass123@example.com` these values are\n`http`, `bob` and `pass123`, respectively.\n\n\n### `redactUrl(url, passwordReplacement)`\n\nTakes a URL and hides the password from it. For example:\n\n```javascript\n// Prints 'http://bob:<redacted>@example.com'\nconsole.log(redactUrl('http://bob:pass123@example.com'));\n```\n","readmeFilename":"README.md","gitHead":"ce4d03963e7cd242c2ac3f7261073476a241ab49","_id":"@asendia/proxy-chain@0.2.31","_npmVersion":"5.8.0","_nodeVersion":"9.8.0","_npmUser":{"name":"asendia","email":"asendia@me.com"},"dist":{"integrity":"sha512-mTg+ZAUoYmjc6PlKXw7jH8/PtRaY3KNvH6oFkDEhkLv6VJhLZkMkEz/wcqoCssv0RdkM6aKDL5ozZ7WRbE6k1w==","shasum":"ebc806884e9c1ea0eaa868239a26e842f003bb19","tarball":"https://registry.npmjs.org/@asendia/proxy-chain/-/proxy-chain-0.2.31.tgz","fileCount":16,"unpackedSize":80788,"npm-signature":"-----BEGIN PGP SIGNATURE-----\r\nVersion: OpenPGP.js v3.0.4\r\nComment: https://openpgpjs.org\r\n\r\nwsFcBAEBCAAQBQJbDOSrCRA9TVsSAnZWagAA+U4P/jua8HE+rlhxj4qNYpbB\nsVIpvgoMmP8tOL8+3iwnrWwhSPtyQD0jDdVMBCAaaD47QCMDfkK4nocikwvU\nGALWkne23+Zs7wvFjkotd5nRZC8unjIDb/iwhmkUyGUhG/lLKOZSKH4lx8aW\nUsOyS2KECrRPmLN28LnShpHqchZuELmESDE06aRiVD1G9kuYVI/uMEQVsvfE\n48WV+LCSxsn4m5ZkquW3hgiAaSSPIZWhCBqOuO6q5ORKaezXlPJoaTQDGOQ1\nL93vSDUjMn5tuz/oM7HkQT62hgPKVUnFFt4qkPSOljJ1hAEK1QRxyUGLDXWD\nDjj+XqFuvrFKxm47Ies2pcf2yxKIhHFJFdOL4JmpGeAox+C1NVfcamlE5psx\nVYssZwyn1liP3Iz/aQN1U4qvFoTJ3zaC2J6lX874T/s78UQ+RU4D0fCy1+Vg\nsfonAty4Te9xhSlH47OtpoIqC87imfn2SrffmQGsLBM2tic/xW661lMN0++F\nQO2I/08WOBmAuaZriICTgZ1XWX1dXqn0hhfXL1zvqJG1IpQz48Y1mWLRhhJf\nGis8RFZGj+xFi3/4v7mHu9A3HDlsY3JBOyiENsTZo6yT7mG2GWhim8YEQnRQ\nwBOOzrcqFa3OelAIZj++Ba8FWdeqmrU76/C1caQeGui9wjaZb2nIWb0slrQ/\nki7n\r\n=lFUi\r\n-----END PGP SIGNATURE-----\r\n","signatures":[{"keyid":"SHA256:jl3bwswu80PjjokCgh0o2w5c2U4LhQAE57gj9cz1kzA","sig":"MEYCIQCB1CNMK/mESLpXOfwAQ0SjFsq72b4mTOxaF0wxqYldngIhAPxyZ1oLpCb9sG/yGjlUQAJ4Wwszikn0eAsFfsMxwyJZ"}]},"maintainers":[{"name":"asendia","email":"asendia@me.com"}],"directories":{},"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/proxy-chain_0.2.31_1527571626770_0.32405436508526053"},"_hasShrinkwrap":false}},"time":{"created":"2018-05-28T13:58:55.711Z","0.1.31":"2018-05-28T13:58:56.035Z","modified":"2022-04-04T15:44:46.287Z","0.2.31":"2018-05-29T05:27:07.022Z"},"maintainers":[{"name":"asendia","email":"asendia@me.com"}],"description":"Node.js implementation of a proxy server (think Squid) with support for SSL, authentication, upstream proxy chaining, and protocol tunneling.","homepage":"https://blog.apify.com/how-to-make-headless-chrome-and-puppeteer-use-a-proxy-server-with-authentication-249a21a79212","keywords":["proxy","squid","apify","tunnel"],"repository":{"type":"git","url":"git+https://github.com/apifytech/proxy-chain.git"},"contributors":[{"name":"Jan Curn","email":"jan@apify.com"}],"author":{"name":"Apify","email":"support@apify.com","url":"https://www.apify.com"},"bugs":{"url":"https://github.com/apifytech/proxy-chain/issues"},"license":"Apache-2.0","readme":"","readmeFilename":""}