* Called when the node-core HTTP client library is creating a * new HTTP request.
(req: http.ClientRequest, opts: AgentConnectOpts)
| 102 | * new HTTP request. |
| 103 | */ |
| 104 | async connect(req: http.ClientRequest, opts: AgentConnectOpts): Promise<net.Socket> { |
| 105 | const { proxy } = this; |
| 106 | |
| 107 | if (!opts.host) { |
| 108 | throw new TypeError('No "host" provided'); |
| 109 | } |
| 110 | |
| 111 | // Create a socket connection to the proxy server. |
| 112 | let socket: net.Socket; |
| 113 | if (proxy.protocol === 'https:') { |
| 114 | debugLog('Creating `tls.Socket`: %o', this.connectOpts); |
| 115 | const servername = this.connectOpts.servername || this.connectOpts.host; |
| 116 | socket = tls.connect({ |
| 117 | ...this.connectOpts, |
| 118 | servername: servername && net.isIP(servername) ? undefined : servername, |
| 119 | }); |
| 120 | } else { |
| 121 | debugLog('Creating `net.Socket`: %o', this.connectOpts); |
| 122 | socket = net.connect(this.connectOpts); |
| 123 | } |
| 124 | |
| 125 | const headers: OutgoingHttpHeaders = |
| 126 | typeof this.proxyHeaders === 'function' ? this.proxyHeaders() : { ...this.proxyHeaders }; |
| 127 | const host = net.isIPv6(opts.host) ? `[${opts.host}]` : opts.host; |
| 128 | let payload = `CONNECT ${host}:${opts.port} HTTP/1.1\r\n`; |
| 129 | |
| 130 | // Inject the `Proxy-Authorization` header if necessary. |
| 131 | if (proxy.username || proxy.password) { |
| 132 | const auth = `${decodeURIComponent(proxy.username)}:${decodeURIComponent(proxy.password)}`; |
| 133 | headers['Proxy-Authorization'] = `Basic ${Buffer.from(auth).toString('base64')}`; |
| 134 | } |
| 135 | |
| 136 | headers.Host = `${host}:${opts.port}`; |
| 137 | |
| 138 | if (!headers['Proxy-Connection']) { |
| 139 | headers['Proxy-Connection'] = this.keepAlive ? 'Keep-Alive' : 'close'; |
| 140 | } |
| 141 | for (const name of Object.keys(headers)) { |
| 142 | payload += `${name}: ${headers[name]}\r\n`; |
| 143 | } |
| 144 | |
| 145 | const proxyResponsePromise = parseProxyResponse(socket); |
| 146 | |
| 147 | socket.write(`${payload}\r\n`); |
| 148 | |
| 149 | const { connect, buffered } = await proxyResponsePromise; |
| 150 | req.emit('proxyConnect', connect); |
| 151 | // eslint-disable-next-line @typescript-eslint/ban-ts-comment |
| 152 | // @ts-ignore Not EventEmitter in Node types |
| 153 | this.emit('proxyConnect', connect, req); |
| 154 | |
| 155 | if (connect.statusCode === 200) { |
| 156 | req.once('socket', resume); |
| 157 | |
| 158 | if (opts.secureEndpoint) { |
| 159 | // The proxy is connecting to a TLS server, so upgrade |
| 160 | // this socket connection to a TLS connection. |
| 161 | debugLog('Upgrading socket connection to TLS'); |
nothing calls this directly
no test coverage detected