Small refactor for proxying

feature/ssh-config
Kelvin Schoofs 4 years ago
parent 345944c086
commit 7b94fdcac8

@ -194,7 +194,7 @@ export async function calculateActualConfig(config: FileSystemConfig): Promise<F
return config; return config;
} }
export async function createSocket(config: FileSystemConfig): Promise<NodeJS.ReadableStream | null> { export async function createSocket(config: FileSystemConfig): Promise<NodeJS.ReadWriteStream | null> {
config = (await calculateActualConfig(config))!; config = (await calculateActualConfig(config))!;
if (!config) return null; if (!config) return null;
const logging = Logging.scope(`createSocket(${config.name})`); const logging = Logging.scope(`createSocket(${config.name})`);
@ -213,7 +213,7 @@ export async function createSocket(config: FileSystemConfig): Promise<NodeJS.Rea
if (calculatedHops.includes(null)) return null; if (calculatedHops.includes(null)) return null;
const hopConfigs = calculatedHops as FileSystemConfig[]; const hopConfigs = calculatedHops as FileSystemConfig[];
logging.debug(`\tHop configs: client -> ${hopConfigs.map((c, i) => `[${i + 1}] ${c.name}`).join(' -> ')} -> server`); logging.debug(`\tHop configs: client -> ${hopConfigs.map((c, i) => `[${i + 1}] ${c.name}`).join(' -> ')} -> server`);
const stream = await reduceAsync(hopConfigs, async (sock: NodeJS.ReadableStream | null | undefined, hop, index) => { const stream = await reduceAsync(hopConfigs, async (sock: NodeJS.ReadWriteStream | null | undefined, hop, index) => {
if (sock === null) return null; if (sock === null) return null;
const logger = logging.scope(`Hop#${index + 1}`); const logger = logging.scope(`Hop#${index + 1}`);
logger.debug(`Connecting to hop '${hop.name}'`); logger.debug(`Connecting to hop '${hop.name}'`);
@ -241,16 +241,16 @@ export async function createSocket(config: FileSystemConfig): Promise<NodeJS.Rea
default: default:
throw new Error(`Unknown proxy method`); throw new Error(`Unknown proxy method`);
} }
return new Promise<NodeJS.ReadableStream>((resolve, reject) => { return new Promise<NodeJS.ReadWriteStream>((resolve, reject) => {
logging.debug(`Connecting to ${config.host}:${config.port || 22}`); logging.debug(`Connecting to ${config.host}:${config.port || 22}`);
const socket = new Socket(); const socket = new Socket();
socket.connect(config.port || 22, config.host!, () => resolve(socket as NodeJS.ReadableStream)); socket.connect(config.port || 22, config.host!, () => resolve(socket as NodeJS.ReadWriteStream));
socket.once('error', reject); socket.once('error', reject);
}); });
} }
export interface CreateSSHOptions { export interface CreateSSHOptions {
sock?: NodeJS.ReadableStream; sock?: NodeJS.ReadWriteStream;
logger?: Logger; logger?: Logger;
} }
export async function createSSH(config: FileSystemConfig, options: CreateSSHOptions = {}): Promise<Client | null> { export async function createSSH(config: FileSystemConfig, options: CreateSSHOptions = {}): Promise<Client | null> {

@ -1,7 +1,6 @@
import * as dns from 'dns'; import * as dns from 'dns';
import { request } from 'http'; import { request } from 'http';
import { SocksClient } from 'socks';
import type { FileSystemConfig } from './fileSystemConfig'; import type { FileSystemConfig } from './fileSystemConfig';
import { Logging } from './logging'; import { Logging } from './logging';
import { toPromise } from './toPromise'; import { toPromise } from './toPromise';
@ -20,17 +19,18 @@ function validateConfig(config: FileSystemConfig) {
if (!config.proxy.type) throw new Error(`Missing field 'config.proxy.type'`); if (!config.proxy.type) throw new Error(`Missing field 'config.proxy.type'`);
} }
export async function socks(config: FileSystemConfig): Promise<NodeJS.ReadableStream> { export async function socks(config: FileSystemConfig): Promise<NodeJS.ReadWriteStream> {
Logging.info(`Creating socks proxy connection for ${config.name}`); Logging.info(`Creating socks proxy connection for ${config.name}`);
validateConfig(config); validateConfig(config);
if (config.proxy!.type !== 'socks4' && config.proxy!.type !== 'socks5') { const proxy = config.proxy!;
if (proxy!.type !== 'socks4' && proxy!.type !== 'socks5') {
throw new Error(`Expected 'config.proxy.type' to be 'socks4' or 'socks5'`); throw new Error(`Expected 'config.proxy.type' to be 'socks4' or 'socks5'`);
} }
try { try {
const ipaddress = (await resolveHostname(config.proxy!.host)); const ipaddress = (await resolveHostname(proxy!.host));
if (!ipaddress) throw new Error(`Couldn't resolve '${config.proxy!.host}'`); if (!ipaddress) throw new Error(`Couldn't resolve '${proxy!.host}'`);
Logging.debug(`\tConnecting to ${config.host}:${config.port} over ${config.proxy!.type} proxy at ${ipaddress}:${config.proxy!.port}`); Logging.debug(`\tConnecting to ${config.host}:${config.port} over ${proxy!.type} proxy at ${ipaddress}:${proxy!.port}`);
const con = await SocksClient.createConnection({ const con = await (await import('socks')).SocksClient.createConnection({
command: 'connect', command: 'connect',
destination: { destination: {
host: config.host!, host: config.host!,
@ -38,34 +38,35 @@ export async function socks(config: FileSystemConfig): Promise<NodeJS.ReadableSt
}, },
proxy: { proxy: {
ipaddress, ipaddress,
port: config.proxy!.port, port: proxy!.port,
type: config.proxy!.type === 'socks4' ? 4 : 5, type: proxy!.type === 'socks4' ? 4 : 5,
}, },
}); });
return con.socket as NodeJS.ReadableStream; return con.socket as NodeJS.ReadWriteStream;
} catch (e) { } catch (e) {
throw new Error(`Error while connecting to the the proxy: ${e.message}`); throw new Error(`Error while connecting to the the proxy: ${e.message}`);
} }
} }
export function http(config: FileSystemConfig): Promise<NodeJS.ReadableStream> { export function http(config: FileSystemConfig): Promise<NodeJS.ReadWriteStream> {
Logging.info(`Creating http proxy connection for ${config.name}`); Logging.info(`Creating http proxy connection for ${config.name}`);
validateConfig(config); validateConfig(config);
return new Promise<NodeJS.ReadableStream>((resolve, reject) => { return new Promise<NodeJS.ReadWriteStream>((resolve, reject) => {
if (config.proxy!.type !== 'http') { const proxy = config.proxy!;
reject(new Error(`Expected config.proxy.type' to be 'http'`)); if (proxy!.type !== 'http') {
return reject(new Error(`Expected config.proxy.type' to be 'http'`));
} }
try { try {
Logging.debug(`\tConnecting to ${config.host}:${config.port} over http proxy at ${config.proxy!.host}:${config.proxy!.port}`); Logging.debug(`\tConnecting to ${config.host}:${config.port} over http proxy at ${proxy!.host}:${proxy!.port}`);
const req = request({ const req = request({
port: config.proxy!.port, port: proxy!.port,
hostname: config.proxy!.host, hostname: proxy!.host,
method: 'CONNECT', method: 'CONNECT',
path: `${config.host}:${config.port}`, path: `${config.host}:${config.port}`,
}); });
req.end(); req.end();
req.on('connect', (res, socket) => { req.on('connect', (res, socket) => {
resolve(socket as NodeJS.ReadableStream); resolve(socket as NodeJS.ReadWriteStream);
}); });
} catch (e) { } catch (e) {
reject(new Error(`Error while connecting to the the proxy: ${e.message}`)); reject(new Error(`Error while connecting to the the proxy: ${e.message}`));

Loading…
Cancel
Save