UNPKG

@proton/ccxt

Version:

A JavaScript / TypeScript / Python / C# / PHP cryptocurrency trading library with support for 130+ exchanges

119 lines (116 loc) 4.73 kB
// ---------------------------------------------------------------------------- // PLEASE DO NOT EDIT THIS FILE, IT IS GENERATED AND WILL BE OVERWRITTEN: // https://github.com/ccxt/ccxt/blob/master/CONTRIBUTING.md#how-to-contribute-code // EDIT THE CORRESPONDENT .ts FILE INSTEAD import * as net from 'net'; import * as tls from 'tls'; import createDebug from 'debug'; import { once } from 'events'; import { Agent } from './../agent-base/index.js'; const debug = createDebug('http-proxy-agent'); function isHTTPS(protocol) { return typeof protocol === 'string' ? /^https:?$/i.test(protocol) : false; } /** * The `HttpProxyAgent` implements an HTTP Agent subclass that connects * to the specified "HTTP proxy server" in order to proxy HTTP requests. */ export class HttpProxyAgent extends Agent { constructor(proxy, opts) { super(opts); this.proxy = typeof proxy === 'string' ? new URL(proxy) : proxy; this.proxyHeaders = opts?.headers ?? {}; debug('Creating new HttpProxyAgent instance: %o', this.proxy.href); // Trim off the brackets from IPv6 addresses const host = (this.proxy.hostname || this.proxy.host).replace(/^\[|\]$/g, ''); const port = this.proxy.port ? parseInt(this.proxy.port, 10) : this.secureProxy ? 443 : 80; this.connectOpts = { ...(opts ? omit(opts, 'headers') : null), host, port, }; } get secureProxy() { return isHTTPS(this.proxy.protocol); } async connect(req, opts) { const { proxy } = this; const protocol = opts.secureEndpoint ? 'https:' : 'http:'; const hostname = req.getHeader('host') || 'localhost'; const base = `${protocol}//${hostname}`; const url = new URL(req.path, base); if (opts.port !== 80) { url.port = String(opts.port); } // Change the `http.ClientRequest` instance's "path" field // to the absolute path of the URL that will be requested. req.path = String(url); // Inject the `Proxy-Authorization` header if necessary. req._header = null; const headers = typeof this.proxyHeaders === 'function' ? this.proxyHeaders() : { ...this.proxyHeaders }; if (proxy.username || proxy.password) { const auth = `${decodeURIComponent(proxy.username)}:${decodeURIComponent(proxy.password)}`; headers['Proxy-Authorization'] = `Basic ${Buffer.from(auth).toString('base64')}`; } if (!headers['Proxy-Connection']) { headers['Proxy-Connection'] = this.keepAlive ? 'Keep-Alive' : 'close'; } for (const name of Object.keys(headers)) { const value = headers[name]; if (value) { req.setHeader(name, value); } } // Create a socket connection to the proxy server. let socket; if (this.secureProxy) { debug('Creating `tls.Socket`: %o', this.connectOpts); socket = tls.connect(this.connectOpts); } else { debug('Creating `net.Socket`: %o', this.connectOpts); socket = net.connect(this.connectOpts); } // At this point, the http ClientRequest's internal `_header` field // might have already been set. If this is the case then we'll need // to re-generate the string since we just changed the `req.path`. let first; let endOfHeaders; debug('Regenerating stored HTTP header string for request'); req._implicitHeader(); if (req.outputData && req.outputData.length > 0) { // Node >= 12 debug('Patching connection write() output buffer with updated header'); first = req.outputData[0].data; endOfHeaders = first.indexOf('\r\n\r\n') + 4; req.outputData[0].data = req._header + first.substring(endOfHeaders); debug('Output buffer: %o', req.outputData[0].data); } // Wait for the socket's `connect` event, so that this `callback()` // function throws instead of the `http` request machinery. This is // important for i.e. `PacProxyAgent` which determines a failed proxy // connection via the `callback()` function throwing. await once(socket, 'connect'); return socket; } } HttpProxyAgent.protocols = ['http', 'https']; function omit(obj, ...keys) { const ret = {}; let key; for (key in obj) { if (!keys.includes(key)) { ret[key] = obj[key]; } } return ret; }