90 lines
		
	
	
	
		
			2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			90 lines
		
	
	
	
		
			2 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| '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
 | |
| };
 |