├── .gitignore ├── .travis.yml ├── README.md ├── index.js ├── package-lock.json └── package.json /.gitignore: -------------------------------------------------------------------------------- 1 | /node_modules 2 | 3 | /?.js 4 | /*.pac 5 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "0.8" 4 | - "0.10" 5 | - "0.12" 6 | before_install: 7 | - '[ "${TRAVIS_NODE_VERSION}" != "0.8" ] || npm install -g npm@1.4.28' 8 | - npm install -g npm@latest 9 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | electron-proxy-agent 2 | =============== 3 | ### A proxy `http.Agent` implementation for HTTP and HTTPS, 4 | rewritten to work seamlessly with [Electron](https://github.com/atom/electron) API 5 | 6 | This module provides an `http.Agent` implementation that uses the [session.resolveProxy](https://github.com/atom/electron/blob/master/docs/api/session.md#sesresolveproxyurl-callback) API of [Electron](https://github.com/atom/electron) to resolve which HTTP, HTTPS, or SOCKS proxy, or if a direct connection should be used to connect to the HTTP(S) endpoint. 7 | 8 | It is designed to be be used with the built-in `http` and `https` modules 9 | 10 | 11 | Installation 12 | ------------ 13 | 14 | Install with `npm`: 15 | 16 | ``` bash 17 | $ npm install electron-proxy-agent --save 18 | ``` 19 | 20 | 21 | Examples 22 | ------- 23 | 24 | - Single request 25 | ``` js 26 | var url = require('url'); 27 | var http = require('http'); 28 | var ElectronProxyAgent = require('electron-proxy-agent'); 29 | var session = require('session').defaultSession; 30 | 31 | // HTTP endpoint for the proxy to connect to 32 | var endpoint = 'http://nodejs.org/api/'; 33 | console.log('attempting to GET %j', endpoint); 34 | var opts = url.parse(endpoint); 35 | 36 | // create an instance of the `ElectronProxyAgent` class with the default electron session 37 | var agent = new ElectronProxyAgent(session); 38 | opts.agent = agent; 39 | 40 | http.get(opts, function (res) { 41 | console.log('"response" event!', res.headers); 42 | res.pipe(process.stdout); 43 | }); 44 | ``` 45 | 46 | - Global agent 47 | ``` js 48 | var http = require('http'); 49 | var https = require('http'); 50 | var ElectronProxyAgent = require('electron-proxy-agent'); 51 | var session = require('session').defaultSession; 52 | 53 | // use ElectronProxyAgent as http and https globalAgents 54 | http.globalAgent = https.globalAgent = new ElectronProxyAgent(session); 55 | ``` 56 | 57 | Notes 58 | ----- 59 | - Passing no or invalid parameter to the constructor would result in trying to use default session. 60 | ``` 61 | new ElectronProxyAgent() // try to use default session 62 | ``` 63 | - Could be used or mocked out of Electron by passing an object that implements resolveProxy 64 | ``` 65 | new ElectronProxyAgent({ 66 | resolveProxy : function(url, callback) { 67 | callback("PROXY 127.0.0.1:8888; DIRECT"); // return a valid pac syntax 68 | } 69 | }) 70 | ``` 71 | 72 | 73 | License 74 | ------- 75 | 76 | (The MIT License) 77 | 78 | Copyright (c) 2014 Nathan Rajlich <nathan@tootallnate.net> 79 | Copyright (c) 2015 Félicien François <felicien@tweakstyle.com> 80 | 81 | Permission is hereby granted, free of charge, to any person obtaining 82 | a copy of this software and associated documentation files (the 83 | 'Software'), to deal in the Software without restriction, including 84 | without limitation the rights to use, copy, modify, merge, publish, 85 | distribute, sublicense, and/or sell copies of the Software, and to 86 | permit persons to whom the Software is furnished to do so, subject to 87 | the following conditions: 88 | 89 | The above copyright notice and this permission notice shall be 90 | included in all copies or substantial portions of the Software. 91 | 92 | THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, 93 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 94 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 95 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY 96 | CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, 97 | TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE 98 | SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 99 | 100 | -------------------------------------------------------------------------------- /index.js: -------------------------------------------------------------------------------- 1 | 2 | /** 3 | * Module exports. 4 | */ 5 | 6 | module.exports = exports = ElectronProxyAgent; 7 | 8 | /** 9 | * Supported "protocols". Delegates out to the `get-uri` module. 10 | */ 11 | 12 | var getUri = require('get-uri'); 13 | Object.defineProperty(exports, 'protocols', { 14 | enumerable: true, 15 | configurable: true, 16 | get: function () { return Object.keys(getUri.protocols); } 17 | }); 18 | 19 | /** 20 | * Module dependencies. 21 | */ 22 | 23 | var net = require('net'); 24 | var tls = require('tls'); 25 | var parse = require('url').parse; 26 | var format = require('url').format; 27 | var extend = require('extend'); 28 | var Agent = require('agent-base'); 29 | var HttpProxyAgent = require('http-proxy-agent'); 30 | var HttpsProxyAgent = require('https-proxy-agent'); 31 | var SocksProxyAgent = require('socks-proxy-agent'); 32 | var inherits = require('util').inherits; 33 | var debug = require('debug')('electron-proxy-agent'); 34 | 35 | /** 36 | * The `ElectronProxyAgent` class. 37 | * 38 | * session : { 39 | * resolveProxy(url, callback) 40 | * } 41 | * 42 | * See https://github.com/atom/electron/blob/master/docs/api/session.md#sesresolveproxyurl-callback 43 | * 44 | * @api public 45 | */ 46 | 47 | function ElectronProxyAgent(session) { 48 | if (!(this instanceof ElectronProxyAgent)) return new ElectronProxyAgent(session); 49 | 50 | if (!session || typeof(session.resolveProxy) !== 'function') { 51 | debug('no valid session found, trying to initialize ElectronProxyAgent with defaultSession'); 52 | if (typeof(window) === 'undefined') { 53 | session = require('session').defaultSession; 54 | } else { 55 | session = require('remote').getCurrentWindow().webContents.session; 56 | } 57 | } 58 | 59 | Agent.call(this, connect); 60 | 61 | this.session = session; 62 | 63 | this.cache = this._resolver = null; 64 | } 65 | inherits(ElectronProxyAgent, Agent); 66 | 67 | /** 68 | * Called when the node-core HTTP client library is creating a new HTTP request. 69 | * 70 | * @api public 71 | */ 72 | 73 | function connect (req, opts, fn) { 74 | var url; 75 | var host; 76 | var self = this; 77 | var secure = Boolean(opts.secureEndpoint); 78 | 79 | // calculate the `url` parameter 80 | var defaultPort = secure ? 443 : 80; 81 | var path = req.path; 82 | var firstQuestion = path.indexOf('?'); 83 | var search; 84 | if (-1 != firstQuestion) { 85 | search = path.substring(firstQuestion); 86 | path = path.substring(0, firstQuestion); 87 | } 88 | url = format(extend({}, opts, { 89 | protocol: secure ? 'https:' : 'http:', 90 | pathname: path, 91 | search: search, 92 | 93 | // need to use `hostname` instead of `host` otherwise `port` is ignored 94 | hostname: opts.host, 95 | host: null, 96 | 97 | // set `port` to null when it is the protocol default port (80 / 443) 98 | port: defaultPort == opts.port ? null : opts.port 99 | })); 100 | 101 | debug('url: %o', url); 102 | var handled = false; 103 | var promise = self.session.resolveProxy(url, onproxy); 104 | if(promise && promise.then) { 105 | promise.then(onproxy); 106 | } 107 | 108 | // `resolveProxy()` callback function 109 | function onproxy (proxy) { 110 | if(handled) return; 111 | handled = true 112 | 113 | // default to "DIRECT" if a falsey value was returned (or nothing) 114 | if (!proxy) proxy = 'DIRECT'; 115 | 116 | var proxies = String(proxy).trim().split(/\s*;\s*/g).filter(Boolean); 117 | 118 | // XXX: right now, only the first proxy specified will be used 119 | var first = proxies[0]; 120 | debug('using proxy: %o', first); 121 | 122 | var agent; 123 | var parts = first.split(/\s+/); 124 | var type = parts[0]; 125 | 126 | if ('DIRECT' == type) { 127 | // direct connection to the destination endpoint 128 | var socket; 129 | if (secure) { 130 | socket = tls.connect(opts); 131 | } else { 132 | socket = net.connect(opts); 133 | } 134 | return fn(null, socket); 135 | } else if ('SOCKS' == type || 'SOCKS5' == type) { 136 | // use a SOCKS proxy 137 | agent = new SocksProxyAgent('socks://' + parts[1]); 138 | } else if ('PROXY' == type || 'HTTPS' == type) { 139 | // use an HTTP or HTTPS proxy 140 | // http://dev.chromium.org/developers/design-documents/secure-web-proxy 141 | var proxyURL = ('HTTPS' === type ? 'https' : 'http') + '://' + parts[1]; 142 | var proxy = parse(proxyURL); 143 | if (secure) { 144 | agent = new HttpsProxyAgent(proxy); 145 | } else { 146 | agent = new HttpProxyAgent(proxy); 147 | } 148 | } else { 149 | throw new Error('Unknown proxy type: ' + type); 150 | } 151 | if (agent) agent.callback(req, opts, fn); 152 | } 153 | } 154 | -------------------------------------------------------------------------------- /package-lock.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "electron-proxy-agent", 3 | "version": "1.2.1", 4 | "lockfileVersion": 1, 5 | "requires": true, 6 | "dependencies": { 7 | "@tootallnate/once": { 8 | "version": "1.1.2", 9 | "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-1.1.2.tgz", 10 | "integrity": "sha512-RbzJvlNzmRq5c3O09UipeuXno4tA1FE6ikOjxZK0tuxVv3412l64l5t1W5pj4+rJq9vpkm/kwiR07aZXnsKPxw==" 11 | }, 12 | "agent-base": { 13 | "version": "2.1.1", 14 | "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-2.1.1.tgz", 15 | "integrity": "sha1-1t4Q1a9hMtW9aSQn1G/FOFOQlMc=", 16 | "requires": { 17 | "extend": "~3.0.0", 18 | "semver": "~5.0.1" 19 | } 20 | }, 21 | "core-util-is": { 22 | "version": "1.0.2", 23 | "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", 24 | "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=" 25 | }, 26 | "data-uri-to-buffer": { 27 | "version": "0.0.4", 28 | "resolved": "https://registry.npmjs.org/data-uri-to-buffer/-/data-uri-to-buffer-0.0.4.tgz", 29 | "integrity": "sha1-RuE6udqOMJdFyNAc5UchPr2y/j8=" 30 | }, 31 | "debug": { 32 | "version": "2.6.9", 33 | "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", 34 | "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", 35 | "requires": { 36 | "ms": "2.0.0" 37 | } 38 | }, 39 | "extend": { 40 | "version": "3.0.2", 41 | "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", 42 | "integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==" 43 | }, 44 | "file-uri-to-path": { 45 | "version": "0.0.2", 46 | "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-0.0.2.tgz", 47 | "integrity": "sha1-N83RtbkFQEs/BeGyNkW+aU/3D4I=" 48 | }, 49 | "ftp": { 50 | "version": "0.3.10", 51 | "resolved": "https://registry.npmjs.org/ftp/-/ftp-0.3.10.tgz", 52 | "integrity": "sha1-kZfYYa2BQvPmPVqDv+TFn3MwiF0=", 53 | "requires": { 54 | "readable-stream": "1.1.x", 55 | "xregexp": "2.0.0" 56 | }, 57 | "dependencies": { 58 | "readable-stream": { 59 | "version": "1.1.14", 60 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-1.1.14.tgz", 61 | "integrity": "sha1-fPTFTvZI44EwhMY23SB54WbAgdk=", 62 | "requires": { 63 | "core-util-is": "~1.0.0", 64 | "inherits": "~2.0.1", 65 | "isarray": "0.0.1", 66 | "string_decoder": "~0.10.x" 67 | } 68 | } 69 | } 70 | }, 71 | "get-uri": { 72 | "version": "1.1.0", 73 | "resolved": "https://registry.npmjs.org/get-uri/-/get-uri-1.1.0.tgz", 74 | "integrity": "sha1-c3XQTa9/y1hLNjJnnL3zObUbsUk=", 75 | "requires": { 76 | "data-uri-to-buffer": "0", 77 | "debug": "2", 78 | "extend": "3", 79 | "file-uri-to-path": "0", 80 | "ftp": "~0.3.5", 81 | "readable-stream": "2" 82 | } 83 | }, 84 | "http-proxy-agent": { 85 | "version": "4.0.1", 86 | "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-4.0.1.tgz", 87 | "integrity": "sha512-k0zdNgqWTGA6aeIRVpvfVob4fL52dTfaehylg0Y4UvSySvOq/Y+BOyPrgpUrA7HylqvU8vIZGsRuXmspskV0Tg==", 88 | "requires": { 89 | "@tootallnate/once": "1", 90 | "agent-base": "6", 91 | "debug": "4" 92 | }, 93 | "dependencies": { 94 | "agent-base": { 95 | "version": "6.0.0", 96 | "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.0.tgz", 97 | "integrity": "sha512-j1Q7cSCqN+AwrmDd+pzgqc0/NpC655x2bUf5ZjRIO77DcNBFmh+OgRNzF6OKdCC9RSCb19fGd99+bhXFdkRNqw==", 98 | "requires": { 99 | "debug": "4" 100 | } 101 | }, 102 | "debug": { 103 | "version": "4.1.1", 104 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", 105 | "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", 106 | "requires": { 107 | "ms": "^2.1.1" 108 | } 109 | }, 110 | "ms": { 111 | "version": "2.1.2", 112 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 113 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" 114 | } 115 | } 116 | }, 117 | "https-proxy-agent": { 118 | "version": "5.0.0", 119 | "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", 120 | "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", 121 | "requires": { 122 | "agent-base": "6", 123 | "debug": "4" 124 | }, 125 | "dependencies": { 126 | "agent-base": { 127 | "version": "6.0.0", 128 | "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.0.tgz", 129 | "integrity": "sha512-j1Q7cSCqN+AwrmDd+pzgqc0/NpC655x2bUf5ZjRIO77DcNBFmh+OgRNzF6OKdCC9RSCb19fGd99+bhXFdkRNqw==", 130 | "requires": { 131 | "debug": "4" 132 | } 133 | }, 134 | "debug": { 135 | "version": "4.1.1", 136 | "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", 137 | "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", 138 | "requires": { 139 | "ms": "^2.1.1" 140 | } 141 | }, 142 | "ms": { 143 | "version": "2.1.2", 144 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", 145 | "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" 146 | } 147 | } 148 | }, 149 | "inherits": { 150 | "version": "2.0.4", 151 | "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", 152 | "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==" 153 | }, 154 | "ip": { 155 | "version": "1.1.5", 156 | "resolved": "https://registry.npmjs.org/ip/-/ip-1.1.5.tgz", 157 | "integrity": "sha1-vd7XARQpCCjAoDnnLvJfWq7ENUo=" 158 | }, 159 | "isarray": { 160 | "version": "0.0.1", 161 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-0.0.1.tgz", 162 | "integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=" 163 | }, 164 | "ms": { 165 | "version": "2.0.0", 166 | "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", 167 | "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=" 168 | }, 169 | "process-nextick-args": { 170 | "version": "2.0.1", 171 | "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", 172 | "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" 173 | }, 174 | "readable-stream": { 175 | "version": "2.3.7", 176 | "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", 177 | "integrity": "sha512-Ebho8K4jIbHAxnuxi7o42OrZgF/ZTNcsZj6nRKyUmkhLFq8CHItp/fy6hQZuZmP/n3yZ9VBUbp4zz/mX8hmYPw==", 178 | "requires": { 179 | "core-util-is": "~1.0.0", 180 | "inherits": "~2.0.3", 181 | "isarray": "~1.0.0", 182 | "process-nextick-args": "~2.0.0", 183 | "safe-buffer": "~5.1.1", 184 | "string_decoder": "~1.1.1", 185 | "util-deprecate": "~1.0.1" 186 | }, 187 | "dependencies": { 188 | "isarray": { 189 | "version": "1.0.0", 190 | "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", 191 | "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=" 192 | }, 193 | "string_decoder": { 194 | "version": "1.1.1", 195 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", 196 | "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", 197 | "requires": { 198 | "safe-buffer": "~5.1.0" 199 | } 200 | } 201 | } 202 | }, 203 | "safe-buffer": { 204 | "version": "5.1.2", 205 | "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", 206 | "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" 207 | }, 208 | "semver": { 209 | "version": "5.0.3", 210 | "resolved": "https://registry.npmjs.org/semver/-/semver-5.0.3.tgz", 211 | "integrity": "sha1-d0Zt5YnNXTyV8TiqeLxWmjy10no=" 212 | }, 213 | "smart-buffer": { 214 | "version": "1.1.15", 215 | "resolved": "https://registry.npmjs.org/smart-buffer/-/smart-buffer-1.1.15.tgz", 216 | "integrity": "sha1-fxFLW2X6s+KjWqd1uxLw0cZJvxY=" 217 | }, 218 | "socks": { 219 | "version": "1.1.10", 220 | "resolved": "https://registry.npmjs.org/socks/-/socks-1.1.10.tgz", 221 | "integrity": "sha1-W4t/x8jzQcU+0FbpKbe/Tei6e1o=", 222 | "requires": { 223 | "ip": "^1.1.4", 224 | "smart-buffer": "^1.0.13" 225 | } 226 | }, 227 | "socks-proxy-agent": { 228 | "version": "2.1.1", 229 | "resolved": "https://registry.npmjs.org/socks-proxy-agent/-/socks-proxy-agent-2.1.1.tgz", 230 | "integrity": "sha512-sFtmYqdUK5dAMh85H0LEVFUCO7OhJJe1/z2x/Z6mxp3s7/QPf1RkZmpZy+BpuU0bEjcV9npqKjq9Y3kwFUjnxw==", 231 | "requires": { 232 | "agent-base": "2", 233 | "extend": "3", 234 | "socks": "~1.1.5" 235 | } 236 | }, 237 | "string_decoder": { 238 | "version": "0.10.31", 239 | "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-0.10.31.tgz", 240 | "integrity": "sha1-YuIDvEF2bGwoyfyEMB2rHFMQ+pQ=" 241 | }, 242 | "util-deprecate": { 243 | "version": "1.0.2", 244 | "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", 245 | "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=" 246 | }, 247 | "xregexp": { 248 | "version": "2.0.0", 249 | "resolved": "https://registry.npmjs.org/xregexp/-/xregexp-2.0.0.tgz", 250 | "integrity": "sha1-UqY+VsoLhKfzpfPWGHLxJq16WUM=" 251 | } 252 | } 253 | } 254 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "electron-proxy-agent", 3 | "version": "1.2.1", 4 | "description": "NodeJS http(s).Agent implementation for electron shell", 5 | "main": "index.js", 6 | "repository": { 7 | "type": "git", 8 | "url": "git://github.com/felicienfrancois/electron-proxy-agent.git" 9 | }, 10 | "keywords": [ 11 | "electron", 12 | "atom shell", 13 | "proxy", 14 | "agent", 15 | "http", 16 | "https", 17 | "socks", 18 | "request", 19 | "access" 20 | ], 21 | "authors": [ 22 | "Nathan Rajlich (http://n8.io/)", 23 | "Félicien François " 24 | ], 25 | "license": "MIT", 26 | "bugs": { 27 | "url": "https://github.com/felicienfrancois/node-electron-proxy-agent/issues" 28 | }, 29 | "homepage": "https://github.com/felicienfrancois/node-electron-proxy-agent", 30 | "dependencies": { 31 | "agent-base": "2", 32 | "debug": "2", 33 | "extend": "3", 34 | "get-uri": "1", 35 | "http-proxy-agent": "^4.0.1", 36 | "https-proxy-agent": "^5.0.0", 37 | "socks-proxy-agent": "2" 38 | } 39 | } 40 | --------------------------------------------------------------------------------