tlsd 2.5.0 → 2.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (71) hide show
  1. package/README.md +26 -3
  2. package/domains/README.txt +0 -0
  3. package/package.json +1 -1
  4. package/proxy/config.json +5 -0
  5. package/proxy/package-lock.json +118 -0
  6. package/proxy/package.json +15 -0
  7. package/proxy/proxy.js +20 -0
  8. package/proxy/siriusmercantile.com/index.js +14 -0
  9. package/proxy/siriusmercantile.com/package-lock.json +137 -0
  10. package/proxy/siriusmercantile.com/package.json +7 -0
  11. package/proxy/zzz/was-nm/debug/CHANGELOG.md +395 -0
  12. package/proxy/zzz/was-nm/debug/LICENSE +19 -0
  13. package/proxy/zzz/was-nm/debug/README.md +437 -0
  14. package/proxy/zzz/was-nm/debug/dist/debug.js +886 -0
  15. package/proxy/zzz/was-nm/debug/node.js +1 -0
  16. package/proxy/zzz/was-nm/debug/package.json +90 -0
  17. package/proxy/zzz/was-nm/debug/src/browser.js +180 -0
  18. package/proxy/zzz/was-nm/debug/src/common.js +249 -0
  19. package/proxy/zzz/was-nm/debug/src/index.js +12 -0
  20. package/proxy/zzz/was-nm/debug/src/node.js +174 -0
  21. package/proxy/zzz/was-nm/eventemitter3/LICENSE +21 -0
  22. package/proxy/zzz/was-nm/eventemitter3/README.md +92 -0
  23. package/proxy/zzz/was-nm/eventemitter3/index.d.ts +67 -0
  24. package/proxy/zzz/was-nm/eventemitter3/index.js +336 -0
  25. package/proxy/zzz/was-nm/eventemitter3/package.json +84 -0
  26. package/proxy/zzz/was-nm/eventemitter3/umd/eventemitter3.js +340 -0
  27. package/proxy/zzz/was-nm/eventemitter3/umd/eventemitter3.min.js +1 -0
  28. package/proxy/zzz/was-nm/eventemitter3/umd/eventemitter3.min.js.map +1 -0
  29. package/proxy/zzz/was-nm/follow-redirects/LICENSE +18 -0
  30. package/proxy/zzz/was-nm/follow-redirects/README.md +145 -0
  31. package/proxy/zzz/was-nm/follow-redirects/http.js +1 -0
  32. package/proxy/zzz/was-nm/follow-redirects/https.js +1 -0
  33. package/proxy/zzz/was-nm/follow-redirects/index.js +452 -0
  34. package/proxy/zzz/was-nm/follow-redirects/package.json +87 -0
  35. package/proxy/zzz/was-nm/http-proxy/.auto-changelog +6 -0
  36. package/proxy/zzz/was-nm/http-proxy/.gitattributes +1 -0
  37. package/proxy/zzz/was-nm/http-proxy/CHANGELOG.md +1864 -0
  38. package/proxy/zzz/was-nm/http-proxy/CODE_OF_CONDUCT.md +74 -0
  39. package/proxy/zzz/was-nm/http-proxy/LICENSE +23 -0
  40. package/proxy/zzz/was-nm/http-proxy/README.md +568 -0
  41. package/proxy/zzz/was-nm/http-proxy/codecov.yml +10 -0
  42. package/proxy/zzz/was-nm/http-proxy/index.js +13 -0
  43. package/proxy/zzz/was-nm/http-proxy/lib/http-proxy/common.js +248 -0
  44. package/proxy/zzz/was-nm/http-proxy/lib/http-proxy/index.js +185 -0
  45. package/proxy/zzz/was-nm/http-proxy/lib/http-proxy/passes/web-incoming.js +192 -0
  46. package/proxy/zzz/was-nm/http-proxy/lib/http-proxy/passes/web-outgoing.js +147 -0
  47. package/proxy/zzz/was-nm/http-proxy/lib/http-proxy/passes/ws-incoming.js +162 -0
  48. package/proxy/zzz/was-nm/http-proxy/lib/http-proxy.js +66 -0
  49. package/proxy/zzz/was-nm/http-proxy/package.json +77 -0
  50. package/proxy/zzz/was-nm/http-proxy/renovate.json +19 -0
  51. package/proxy/zzz/was-nm/ms/index.js +162 -0
  52. package/proxy/zzz/was-nm/ms/license.md +21 -0
  53. package/proxy/zzz/was-nm/ms/package.json +69 -0
  54. package/proxy/zzz/was-nm/ms/readme.md +60 -0
  55. package/proxy/zzz/was-nm/requires-port/.travis.yml +19 -0
  56. package/proxy/zzz/was-nm/requires-port/LICENSE +22 -0
  57. package/proxy/zzz/was-nm/requires-port/README.md +47 -0
  58. package/proxy/zzz/was-nm/requires-port/index.js +38 -0
  59. package/proxy/zzz/was-nm/requires-port/package.json +74 -0
  60. package/proxy/zzz/was-nm/requires-port/test.js +98 -0
  61. package/proxy/zzz/was-nm/sleepless/README.md +4 -0
  62. package/proxy/zzz/was-nm/sleepless/autosite/README.txt +0 -0
  63. package/proxy/zzz/was-nm/sleepless/autosite/site/foobar.txt +1 -0
  64. package/proxy/zzz/was-nm/sleepless/autosite/site/pull.php +4 -0
  65. package/proxy/zzz/was-nm/sleepless/index.js +2 -0
  66. package/proxy/zzz/was-nm/sleepless/package.json +44 -0
  67. package/proxy/zzz/was-nm/sleepless/sleepless.js +613 -0
  68. package/proxy/zzz/was-nm/sleepless/test.html +9 -0
  69. package/proxy/zzz/was-nm/sleepless/test.js +146 -0
  70. package/tlsd +11 -2
  71. package/tlsd.js +2 -0
@@ -0,0 +1,248 @@
1
+ var common = exports,
2
+ url = require('url'),
3
+ extend = require('util')._extend,
4
+ required = require('requires-port');
5
+
6
+ var upgradeHeader = /(^|,)\s*upgrade\s*($|,)/i,
7
+ isSSL = /^https|wss/;
8
+
9
+ /**
10
+ * Simple Regex for testing if protocol is https
11
+ */
12
+ common.isSSL = isSSL;
13
+ /**
14
+ * Copies the right headers from `options` and `req` to
15
+ * `outgoing` which is then used to fire the proxied
16
+ * request.
17
+ *
18
+ * Examples:
19
+ *
20
+ * common.setupOutgoing(outgoing, options, req)
21
+ * // => { host: ..., hostname: ...}
22
+ *
23
+ * @param {Object} Outgoing Base object to be filled with required properties
24
+ * @param {Object} Options Config object passed to the proxy
25
+ * @param {ClientRequest} Req Request Object
26
+ * @param {String} Forward String to select forward or target
27
+
28
+ * @return {Object} Outgoing Object with all required properties set
29
+ *
30
+ * @api private
31
+ */
32
+
33
+ common.setupOutgoing = function(outgoing, options, req, forward) {
34
+ outgoing.port = options[forward || 'target'].port ||
35
+ (isSSL.test(options[forward || 'target'].protocol) ? 443 : 80);
36
+
37
+ ['host', 'hostname', 'socketPath', 'pfx', 'key',
38
+ 'passphrase', 'cert', 'ca', 'ciphers', 'secureProtocol'].forEach(
39
+ function(e) { outgoing[e] = options[forward || 'target'][e]; }
40
+ );
41
+
42
+ outgoing.method = options.method || req.method;
43
+ outgoing.headers = extend({}, req.headers);
44
+
45
+ if (options.headers){
46
+ extend(outgoing.headers, options.headers);
47
+ }
48
+
49
+ if (options.auth) {
50
+ outgoing.auth = options.auth;
51
+ }
52
+
53
+ if (options.ca) {
54
+ outgoing.ca = options.ca;
55
+ }
56
+
57
+ if (isSSL.test(options[forward || 'target'].protocol)) {
58
+ outgoing.rejectUnauthorized = (typeof options.secure === "undefined") ? true : options.secure;
59
+ }
60
+
61
+
62
+ outgoing.agent = options.agent || false;
63
+ outgoing.localAddress = options.localAddress;
64
+
65
+ //
66
+ // Remark: If we are false and not upgrading, set the connection: close. This is the right thing to do
67
+ // as node core doesn't handle this COMPLETELY properly yet.
68
+ //
69
+ if (!outgoing.agent) {
70
+ outgoing.headers = outgoing.headers || {};
71
+ if (typeof outgoing.headers.connection !== 'string'
72
+ || !upgradeHeader.test(outgoing.headers.connection)
73
+ ) { outgoing.headers.connection = 'close'; }
74
+ }
75
+
76
+
77
+ // the final path is target path + relative path requested by user:
78
+ var target = options[forward || 'target'];
79
+ var targetPath = target && options.prependPath !== false
80
+ ? (target.path || '')
81
+ : '';
82
+
83
+ //
84
+ // Remark: Can we somehow not use url.parse as a perf optimization?
85
+ //
86
+ var outgoingPath = !options.toProxy
87
+ ? (url.parse(req.url).path || '')
88
+ : req.url;
89
+
90
+ //
91
+ // Remark: ignorePath will just straight up ignore whatever the request's
92
+ // path is. This can be labeled as FOOT-GUN material if you do not know what
93
+ // you are doing and are using conflicting options.
94
+ //
95
+ outgoingPath = !options.ignorePath ? outgoingPath : '';
96
+
97
+ outgoing.path = common.urlJoin(targetPath, outgoingPath);
98
+
99
+ if (options.changeOrigin) {
100
+ outgoing.headers.host =
101
+ required(outgoing.port, options[forward || 'target'].protocol) && !hasPort(outgoing.host)
102
+ ? outgoing.host + ':' + outgoing.port
103
+ : outgoing.host;
104
+ }
105
+ return outgoing;
106
+ };
107
+
108
+ /**
109
+ * Set the proper configuration for sockets,
110
+ * set no delay and set keep alive, also set
111
+ * the timeout to 0.
112
+ *
113
+ * Examples:
114
+ *
115
+ * common.setupSocket(socket)
116
+ * // => Socket
117
+ *
118
+ * @param {Socket} Socket instance to setup
119
+
120
+ * @return {Socket} Return the configured socket.
121
+ *
122
+ * @api private
123
+ */
124
+
125
+ common.setupSocket = function(socket) {
126
+ socket.setTimeout(0);
127
+ socket.setNoDelay(true);
128
+
129
+ socket.setKeepAlive(true, 0);
130
+
131
+ return socket;
132
+ };
133
+
134
+ /**
135
+ * Get the port number from the host. Or guess it based on the connection type.
136
+ *
137
+ * @param {Request} req Incoming HTTP request.
138
+ *
139
+ * @return {String} The port number.
140
+ *
141
+ * @api private
142
+ */
143
+ common.getPort = function(req) {
144
+ var res = req.headers.host ? req.headers.host.match(/:(\d+)/) : '';
145
+
146
+ return res ?
147
+ res[1] :
148
+ common.hasEncryptedConnection(req) ? '443' : '80';
149
+ };
150
+
151
+ /**
152
+ * Check if the request has an encrypted connection.
153
+ *
154
+ * @param {Request} req Incoming HTTP request.
155
+ *
156
+ * @return {Boolean} Whether the connection is encrypted or not.
157
+ *
158
+ * @api private
159
+ */
160
+ common.hasEncryptedConnection = function(req) {
161
+ return Boolean(req.connection.encrypted || req.connection.pair);
162
+ };
163
+
164
+ /**
165
+ * OS-agnostic join (doesn't break on URLs like path.join does on Windows)>
166
+ *
167
+ * @return {String} The generated path.
168
+ *
169
+ * @api private
170
+ */
171
+
172
+ common.urlJoin = function() {
173
+ //
174
+ // We do not want to mess with the query string. All we want to touch is the path.
175
+ //
176
+ var args = Array.prototype.slice.call(arguments),
177
+ lastIndex = args.length - 1,
178
+ last = args[lastIndex],
179
+ lastSegs = last.split('?'),
180
+ retSegs;
181
+
182
+ args[lastIndex] = lastSegs.shift();
183
+
184
+ //
185
+ // Join all strings, but remove empty strings so we don't get extra slashes from
186
+ // joining e.g. ['', 'am']
187
+ //
188
+ retSegs = [
189
+ args.filter(Boolean).join('/')
190
+ .replace(/\/+/g, '/')
191
+ .replace('http:/', 'http://')
192
+ .replace('https:/', 'https://')
193
+ ];
194
+
195
+ // Only join the query string if it exists so we don't have trailing a '?'
196
+ // on every request
197
+
198
+ // Handle case where there could be multiple ? in the URL.
199
+ retSegs.push.apply(retSegs, lastSegs);
200
+
201
+ return retSegs.join('?')
202
+ };
203
+
204
+ /**
205
+ * Rewrites or removes the domain of a cookie header
206
+ *
207
+ * @param {String|Array} Header
208
+ * @param {Object} Config, mapping of domain to rewritten domain.
209
+ * '*' key to match any domain, null value to remove the domain.
210
+ *
211
+ * @api private
212
+ */
213
+ common.rewriteCookieProperty = function rewriteCookieProperty(header, config, property) {
214
+ if (Array.isArray(header)) {
215
+ return header.map(function (headerElement) {
216
+ return rewriteCookieProperty(headerElement, config, property);
217
+ });
218
+ }
219
+ return header.replace(new RegExp("(;\\s*" + property + "=)([^;]+)", 'i'), function(match, prefix, previousValue) {
220
+ var newValue;
221
+ if (previousValue in config) {
222
+ newValue = config[previousValue];
223
+ } else if ('*' in config) {
224
+ newValue = config['*'];
225
+ } else {
226
+ //no match, return previous value
227
+ return match;
228
+ }
229
+ if (newValue) {
230
+ //replace value
231
+ return prefix + newValue;
232
+ } else {
233
+ //remove value
234
+ return '';
235
+ }
236
+ });
237
+ };
238
+
239
+ /**
240
+ * Check the host and see if it potentially has a port in it (keep it simple)
241
+ *
242
+ * @returns {Boolean} Whether we have one or not
243
+ *
244
+ * @api private
245
+ */
246
+ function hasPort(host) {
247
+ return !!~host.indexOf(':');
248
+ };
@@ -0,0 +1,185 @@
1
+ var httpProxy = module.exports,
2
+ extend = require('util')._extend,
3
+ parse_url = require('url').parse,
4
+ EE3 = require('eventemitter3'),
5
+ http = require('http'),
6
+ https = require('https'),
7
+ web = require('./passes/web-incoming'),
8
+ ws = require('./passes/ws-incoming');
9
+
10
+ httpProxy.Server = ProxyServer;
11
+
12
+ /**
13
+ * Returns a function that creates the loader for
14
+ * either `ws` or `web`'s passes.
15
+ *
16
+ * Examples:
17
+ *
18
+ * httpProxy.createRightProxy('ws')
19
+ * // => [Function]
20
+ *
21
+ * @param {String} Type Either 'ws' or 'web'
22
+
23
+ * @return {Function} Loader Function that when called returns an iterator for the right passes
24
+ *
25
+ * @api private
26
+ */
27
+
28
+ function createRightProxy(type) {
29
+
30
+ return function(options) {
31
+ return function(req, res /*, [head], [opts] */) {
32
+ var passes = (type === 'ws') ? this.wsPasses : this.webPasses,
33
+ args = [].slice.call(arguments),
34
+ cntr = args.length - 1,
35
+ head, cbl;
36
+
37
+ /* optional args parse begin */
38
+ if(typeof args[cntr] === 'function') {
39
+ cbl = args[cntr];
40
+
41
+ cntr--;
42
+ }
43
+
44
+ var requestOptions = options;
45
+ if(
46
+ !(args[cntr] instanceof Buffer) &&
47
+ args[cntr] !== res
48
+ ) {
49
+ //Copy global options
50
+ requestOptions = extend({}, options);
51
+ //Overwrite with request options
52
+ extend(requestOptions, args[cntr]);
53
+
54
+ cntr--;
55
+ }
56
+
57
+ if(args[cntr] instanceof Buffer) {
58
+ head = args[cntr];
59
+ }
60
+
61
+ /* optional args parse end */
62
+
63
+ ['target', 'forward'].forEach(function(e) {
64
+ if (typeof requestOptions[e] === 'string')
65
+ requestOptions[e] = parse_url(requestOptions[e]);
66
+ });
67
+
68
+ if (!requestOptions.target && !requestOptions.forward) {
69
+ return this.emit('error', new Error('Must provide a proper URL as target'));
70
+ }
71
+
72
+ for(var i=0; i < passes.length; i++) {
73
+ /**
74
+ * Call of passes functions
75
+ * pass(req, res, options, head)
76
+ *
77
+ * In WebSockets case the `res` variable
78
+ * refer to the connection socket
79
+ * pass(req, socket, options, head)
80
+ */
81
+ if(passes[i](req, res, requestOptions, head, this, cbl)) { // passes can return a truthy value to halt the loop
82
+ break;
83
+ }
84
+ }
85
+ };
86
+ };
87
+ }
88
+ httpProxy.createRightProxy = createRightProxy;
89
+
90
+ function ProxyServer(options) {
91
+ EE3.call(this);
92
+
93
+ options = options || {};
94
+ options.prependPath = options.prependPath === false ? false : true;
95
+
96
+ this.web = this.proxyRequest = createRightProxy('web')(options);
97
+ this.ws = this.proxyWebsocketRequest = createRightProxy('ws')(options);
98
+ this.options = options;
99
+
100
+ this.webPasses = Object.keys(web).map(function(pass) {
101
+ return web[pass];
102
+ });
103
+
104
+ this.wsPasses = Object.keys(ws).map(function(pass) {
105
+ return ws[pass];
106
+ });
107
+
108
+ this.on('error', this.onError, this);
109
+
110
+ }
111
+
112
+ require('util').inherits(ProxyServer, EE3);
113
+
114
+ ProxyServer.prototype.onError = function (err) {
115
+ //
116
+ // Remark: Replicate node core behavior using EE3
117
+ // so we force people to handle their own errors
118
+ //
119
+ if(this.listeners('error').length === 1) {
120
+ throw err;
121
+ }
122
+ };
123
+
124
+ ProxyServer.prototype.listen = function(port, hostname) {
125
+ var self = this,
126
+ closure = function(req, res) { self.web(req, res); };
127
+
128
+ this._server = this.options.ssl ?
129
+ https.createServer(this.options.ssl, closure) :
130
+ http.createServer(closure);
131
+
132
+ if(this.options.ws) {
133
+ this._server.on('upgrade', function(req, socket, head) { self.ws(req, socket, head); });
134
+ }
135
+
136
+ this._server.listen(port, hostname);
137
+
138
+ return this;
139
+ };
140
+
141
+ ProxyServer.prototype.close = function(callback) {
142
+ var self = this;
143
+ if (this._server) {
144
+ this._server.close(done);
145
+ }
146
+
147
+ // Wrap callback to nullify server after all open connections are closed.
148
+ function done() {
149
+ self._server = null;
150
+ if (callback) {
151
+ callback.apply(null, arguments);
152
+ }
153
+ };
154
+ };
155
+
156
+ ProxyServer.prototype.before = function(type, passName, callback) {
157
+ if (type !== 'ws' && type !== 'web') {
158
+ throw new Error('type must be `web` or `ws`');
159
+ }
160
+ var passes = (type === 'ws') ? this.wsPasses : this.webPasses,
161
+ i = false;
162
+
163
+ passes.forEach(function(v, idx) {
164
+ if(v.name === passName) i = idx;
165
+ })
166
+
167
+ if(i === false) throw new Error('No such pass');
168
+
169
+ passes.splice(i, 0, callback);
170
+ };
171
+ ProxyServer.prototype.after = function(type, passName, callback) {
172
+ if (type !== 'ws' && type !== 'web') {
173
+ throw new Error('type must be `web` or `ws`');
174
+ }
175
+ var passes = (type === 'ws') ? this.wsPasses : this.webPasses,
176
+ i = false;
177
+
178
+ passes.forEach(function(v, idx) {
179
+ if(v.name === passName) i = idx;
180
+ })
181
+
182
+ if(i === false) throw new Error('No such pass');
183
+
184
+ passes.splice(i++, 0, callback);
185
+ };
@@ -0,0 +1,192 @@
1
+ var httpNative = require('http'),
2
+ httpsNative = require('https'),
3
+ web_o = require('./web-outgoing'),
4
+ common = require('../common'),
5
+ followRedirects = require('follow-redirects');
6
+
7
+ web_o = Object.keys(web_o).map(function(pass) {
8
+ return web_o[pass];
9
+ });
10
+
11
+ var nativeAgents = { http: httpNative, https: httpsNative };
12
+
13
+ /*!
14
+ * Array of passes.
15
+ *
16
+ * A `pass` is just a function that is executed on `req, res, options`
17
+ * so that you can easily add new checks while still keeping the base
18
+ * flexible.
19
+ */
20
+
21
+
22
+ module.exports = {
23
+
24
+ /**
25
+ * Sets `content-length` to '0' if request is of DELETE type.
26
+ *
27
+ * @param {ClientRequest} Req Request object
28
+ * @param {IncomingMessage} Res Response object
29
+ * @param {Object} Options Config object passed to the proxy
30
+ *
31
+ * @api private
32
+ */
33
+
34
+ deleteLength: function deleteLength(req, res, options) {
35
+ if((req.method === 'DELETE' || req.method === 'OPTIONS')
36
+ && !req.headers['content-length']) {
37
+ req.headers['content-length'] = '0';
38
+ delete req.headers['transfer-encoding'];
39
+ }
40
+ },
41
+
42
+ /**
43
+ * Sets timeout in request socket if it was specified in options.
44
+ *
45
+ * @param {ClientRequest} Req Request object
46
+ * @param {IncomingMessage} Res Response object
47
+ * @param {Object} Options Config object passed to the proxy
48
+ *
49
+ * @api private
50
+ */
51
+
52
+ timeout: function timeout(req, res, options) {
53
+ if(options.timeout) {
54
+ req.socket.setTimeout(options.timeout);
55
+ }
56
+ },
57
+
58
+ /**
59
+ * Sets `x-forwarded-*` headers if specified in config.
60
+ *
61
+ * @param {ClientRequest} Req Request object
62
+ * @param {IncomingMessage} Res Response object
63
+ * @param {Object} Options Config object passed to the proxy
64
+ *
65
+ * @api private
66
+ */
67
+
68
+ XHeaders: function XHeaders(req, res, options) {
69
+ if(!options.xfwd) return;
70
+
71
+ var encrypted = req.isSpdy || common.hasEncryptedConnection(req);
72
+ var values = {
73
+ for : req.connection.remoteAddress || req.socket.remoteAddress,
74
+ port : common.getPort(req),
75
+ proto: encrypted ? 'https' : 'http'
76
+ };
77
+
78
+ ['for', 'port', 'proto'].forEach(function(header) {
79
+ req.headers['x-forwarded-' + header] =
80
+ (req.headers['x-forwarded-' + header] || '') +
81
+ (req.headers['x-forwarded-' + header] ? ',' : '') +
82
+ values[header];
83
+ });
84
+
85
+ req.headers['x-forwarded-host'] = req.headers['x-forwarded-host'] || req.headers['host'] || '';
86
+ },
87
+
88
+ /**
89
+ * Does the actual proxying. If `forward` is enabled fires up
90
+ * a ForwardStream, same happens for ProxyStream. The request
91
+ * just dies otherwise.
92
+ *
93
+ * @param {ClientRequest} Req Request object
94
+ * @param {IncomingMessage} Res Response object
95
+ * @param {Object} Options Config object passed to the proxy
96
+ *
97
+ * @api private
98
+ */
99
+
100
+ stream: function stream(req, res, options, _, server, clb) {
101
+
102
+ // And we begin!
103
+ server.emit('start', req, res, options.target || options.forward);
104
+
105
+ var agents = options.followRedirects ? followRedirects : nativeAgents;
106
+ var http = agents.http;
107
+ var https = agents.https;
108
+
109
+ if(options.forward) {
110
+ // If forward enable, so just pipe the request
111
+ var forwardReq = (options.forward.protocol === 'https:' ? https : http).request(
112
+ common.setupOutgoing(options.ssl || {}, options, req, 'forward')
113
+ );
114
+
115
+ // error handler (e.g. ECONNRESET, ECONNREFUSED)
116
+ // Handle errors on incoming request as well as it makes sense to
117
+ var forwardError = createErrorHandler(forwardReq, options.forward);
118
+ req.on('error', forwardError);
119
+ forwardReq.on('error', forwardError);
120
+
121
+ (options.buffer || req).pipe(forwardReq);
122
+ if(!options.target) { return res.end(); }
123
+ }
124
+
125
+ // Request initalization
126
+ var proxyReq = (options.target.protocol === 'https:' ? https : http).request(
127
+ common.setupOutgoing(options.ssl || {}, options, req)
128
+ );
129
+
130
+ // Enable developers to modify the proxyReq before headers are sent
131
+ proxyReq.on('socket', function(socket) {
132
+ if(server) { server.emit('proxyReq', proxyReq, req, res, options); }
133
+ });
134
+
135
+ // allow outgoing socket to timeout so that we could
136
+ // show an error page at the initial request
137
+ if(options.proxyTimeout) {
138
+ proxyReq.setTimeout(options.proxyTimeout, function() {
139
+ proxyReq.abort();
140
+ });
141
+ }
142
+
143
+ // Ensure we abort proxy if request is aborted
144
+ req.on('aborted', function () {
145
+ proxyReq.abort();
146
+ });
147
+
148
+ // handle errors in proxy and incoming request, just like for forward proxy
149
+ var proxyError = createErrorHandler(proxyReq, options.target);
150
+ req.on('error', proxyError);
151
+ proxyReq.on('error', proxyError);
152
+
153
+ function createErrorHandler(proxyReq, url) {
154
+ return function proxyError(err) {
155
+ if (req.socket.destroyed && err.code === 'ECONNRESET') {
156
+ server.emit('econnreset', err, req, res, url);
157
+ return proxyReq.abort();
158
+ }
159
+
160
+ if (clb) {
161
+ clb(err, req, res, url);
162
+ } else {
163
+ server.emit('error', err, req, res, url);
164
+ }
165
+ }
166
+ }
167
+
168
+ (options.buffer || req).pipe(proxyReq);
169
+
170
+ proxyReq.on('response', function(proxyRes) {
171
+ if(server) { server.emit('proxyRes', proxyRes, req, res); }
172
+
173
+ if(!res.headersSent && !options.selfHandleResponse) {
174
+ for(var i=0; i < web_o.length; i++) {
175
+ if(web_o[i](req, res, proxyRes, options)) { break; }
176
+ }
177
+ }
178
+
179
+ if (!res.finished) {
180
+ // Allow us to listen when the proxy has completed
181
+ proxyRes.on('end', function () {
182
+ if (server) server.emit('end', req, res, proxyRes);
183
+ });
184
+ // We pipe to the response unless its expected to be handled by the user
185
+ if (!options.selfHandleResponse) proxyRes.pipe(res);
186
+ } else {
187
+ if (server) server.emit('end', req, res, proxyRes);
188
+ }
189
+ });
190
+ }
191
+
192
+ };