massive update, probably broken
[dotfiles/.git] / .config / coc / extensions / node_modules / coc-json / node_modules / http-proxy-agent / index.js
1
2 /**
3  * Module dependencies.
4  */
5
6 var net = require('net');
7 var tls = require('tls');
8 var url = require('url');
9 var Agent = require('agent-base');
10 var inherits = require('util').inherits;
11 var debug = require('debug')('http-proxy-agent');
12
13 /**
14  * Module exports.
15  */
16
17 module.exports = HttpProxyAgent;
18
19 /**
20  * The `HttpProxyAgent` implements an HTTP Agent subclass that connects to the
21  * specified "HTTP proxy server" in order to proxy HTTP requests.
22  *
23  * @api public
24  */
25
26 function HttpProxyAgent (opts) {
27   if (!(this instanceof HttpProxyAgent)) return new HttpProxyAgent(opts);
28   if ('string' == typeof opts) opts = url.parse(opts);
29   if (!opts) throw new Error('an HTTP(S) proxy server `host` and `port` must be specified!');
30   debug('creating new HttpProxyAgent instance: %o', opts);
31   Agent.call(this, opts);
32
33   var proxy = Object.assign({}, opts);
34
35   // if `true`, then connect to the proxy server over TLS. defaults to `false`.
36   this.secureProxy = proxy.protocol ? /^https:?$/i.test(proxy.protocol) : false;
37
38   // prefer `hostname` over `host`, and set the `port` if needed
39   proxy.host = proxy.hostname || proxy.host;
40   proxy.port = +proxy.port || (this.secureProxy ? 443 : 80);
41
42   if (proxy.host && proxy.path) {
43     // if both a `host` and `path` are specified then it's most likely the
44     // result of a `url.parse()` call... we need to remove the `path` portion so
45     // that `net.connect()` doesn't attempt to open that as a unix socket file.
46     delete proxy.path;
47     delete proxy.pathname;
48   }
49
50   this.proxy = proxy;
51 }
52 inherits(HttpProxyAgent, Agent);
53
54 /**
55  * Called when the node-core HTTP client library is creating a new HTTP request.
56  *
57  * @api public
58  */
59
60 HttpProxyAgent.prototype.callback = function connect (req, opts, fn) {
61   var proxy = this.proxy;
62
63   // change the `http.ClientRequest` instance's "path" field
64   // to the absolute path of the URL that will be requested
65   var parsed = url.parse(req.path);
66   if (null == parsed.protocol) parsed.protocol = 'http:';
67   if (null == parsed.hostname) parsed.hostname = opts.hostname || opts.host;
68   if (null == parsed.port) parsed.port = opts.port;
69   if (parsed.port == 80) {
70     // if port is 80, then we can remove the port so that the
71     // ":80" portion is not on the produced URL
72     delete parsed.port;
73   }
74   var absolute = url.format(parsed);
75   req.path = absolute;
76
77   // inject the `Proxy-Authorization` header if necessary
78   if (proxy.auth) {
79     req.setHeader(
80       'Proxy-Authorization',
81       'Basic ' + Buffer.from(proxy.auth).toString('base64')
82     );
83   }
84
85   // create a socket connection to the proxy server
86   var socket;
87   if (this.secureProxy) {
88     socket = tls.connect(proxy);
89   } else {
90     socket = net.connect(proxy);
91   }
92
93   // at this point, the http ClientRequest's internal `_header` field might have
94   // already been set. If this is the case then we'll need to re-generate the
95   // string since we just changed the `req.path`
96   if (req._header) {
97     debug('regenerating stored HTTP header string for request');
98     req._header = null;
99     req._implicitHeader();
100     if (req.output && req.output.length > 0) {
101       debug('patching connection write() output buffer with updated header');
102       // the _header has already been queued to be written to the socket
103       var first = req.output[0];
104       var endOfHeaders = first.indexOf('\r\n\r\n') + 4;
105       req.output[0] = req._header + first.substring(endOfHeaders);
106       debug('output buffer: %o', req.output);
107     }
108   }
109
110   fn(null, socket);
111 };