'use strict'; const tls = require('tls'); const http = require('http'); const https = require('https'); const JSStreamSocket = require('../utils/js-stream-socket.js'); const {globalAgent} = require('../agent.js'); const UnexpectedStatusCodeError = require('./unexpected-status-code-error.js'); const initialize = require('./initialize.js'); const getAuthorizationHeaders = require('./get-auth-headers.js'); const createConnection = (self, options, callback) => { (async () => { try { const {proxyOptions} = self; const {url, headers, raw} = proxyOptions; const stream = await globalAgent.request(url, proxyOptions, { ...getAuthorizationHeaders(self), ...headers, ':method': 'CONNECT', ':authority': `${options.host}:${options.port}` }); stream.once('error', callback); stream.once('response', headers => { const statusCode = headers[':status']; if (statusCode !== 200) { callback(new UnexpectedStatusCodeError(statusCode, '')); return; } const encrypted = self instanceof https.Agent; if (raw && encrypted) { options.socket = stream; const secureStream = tls.connect(options); secureStream.once('close', () => { stream.destroy(); }); callback(null, secureStream); return; } const socket = new JSStreamSocket(stream); socket.encrypted = false; socket._handle.getpeername = out => { out.family = undefined; out.address = undefined; out.port = undefined; }; callback(null, socket); }); } catch (error) { callback(error); } })(); }; class HttpOverHttp2 extends http.Agent { constructor(options) { super(options); initialize(this, options.proxyOptions); } createConnection(options, callback) { createConnection(this, options, callback); } } class HttpsOverHttp2 extends https.Agent { constructor(options) { super(options); initialize(this, options.proxyOptions); } createConnection(options, callback) { createConnection(this, options, callback); } } module.exports = { HttpOverHttp2, HttpsOverHttp2 };