-
Notifications
You must be signed in to change notification settings - Fork 20
/
index.js
120 lines (108 loc) · 2.75 KB
/
index.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
/*jshint node:true */
'use strict';
/**
* @fileOverview
* Global proxy settings.
*/
var globalTunnel = exports;
exports.constructor = function globalTunnel(){};
var http = require('http');
var https = require('https');
var urlParse = require('url').parse;
var _ = require('lodash');
var tunnel = require('tunnel');
// save the original globalAgents for restoration later.
var ORIGINALS = {
http: _.pick(http, 'globalAgent', 'request'),
https: _.pick(https, 'globalAgent', 'request')
};
function resetGlobals() {
_.assign(http, ORIGINALS.http);
_.assign(https, ORIGINALS.https);
}
/**
* Parses the de facto `http_proxy` environment.
*/
function tryParseEnv() {
var url = process.env['http_proxy'];
if (!url) {
return null;
}
var conf = {};
var parsed = urlParse(url);
conf.host = parsed.hostname;
conf.port = parsed.port;
return conf;
}
globalTunnel.isProxying = false;
/**
* Overrides the node http/https `globalAgent`s to use the configured proxy.
*
* If the config is empty, the `http_proxy` environment variable is checked. If
* that's not present, no proxying will be enabled.
*
* @param {object} conf
* @param {string} conf.host
* @param {int} conf.port
* @param {int} [conf.sockets] maximum number of sockets to pool (falsy uses
* node's default).
*/
globalTunnel.initialize = function(conf) {
if (globalTunnel.isProxying) {
return;
}
conf = conf || {};
if (_.isEmpty(conf)) {
conf = tryParseEnv();
if (!conf) {
globalTunnel.isProxying = false;
return;
}
}
if (!conf.host) {
throw new Error('upstream proxy host is required');
}
if (!conf.port) {
throw new Error('upstream proxy port is required');
}
var proxyConf = {
proxy: {
host: conf.host,
port: conf.port
},
maxSockets: conf.sockets // falsy uses node's default
};
try {
http.globalAgent = tunnel.httpOverHttp(proxyConf);
https.globalAgent = tunnel.httpsOverHttp(proxyConf);
http.request = function(options, callback) {
if (typeof options === 'string') {
options = urlParse(options);
} else {
options = _.clone(options);
}
options.agent = http.globalAgent;
return ORIGINALS.http.request.call(http, options, callback);
};
https.request = function(options, callback) {
if (typeof options === 'string') {
options = urlParse(options);
} else {
options = _.clone(options);
}
options.agent = https.globalAgent;
return ORIGINALS.https.request.call(https, options, callback);
};
globalTunnel.isProxying = true;
} catch (e) {
resetGlobals();
throw e;
}
};
/**
* Restores global http/https agents.
*/
globalTunnel.end = function() {
resetGlobals();
globalTunnel.isProxying = false;
};