refactor🎨: (阅读代码):proxy.ts增加注释

master
yetao 2 weeks ago
parent 670e9ba7dc
commit 2fe823977d

@ -1,75 +1,149 @@
// 导入 FileSystemConfig 类型,用于定义文件系统配置
import type { FileSystemConfig } from 'common/fileSystemConfig';
// 导入 dns 模块,用于域名解析
import * as dns from 'dns';
// 导入 http 模块中的 request 函数,用于发送 HTTP 请求
import { request } from 'http';
// 导入 socks 模块中的 SocksClient 类,用于创建 SOCKS 代理客户端
import { SocksClient } from 'socks';
// 导入 Logging 模块,用于日志记录
import { Logging } from './logging';
// 导入 toPromise 和 validatePort 函数,用于将回调函数转换为 Promise 和验证端口号
import { toPromise, validatePort } from './utils';
/**
* IP
*
* @param hostname -
* @returns IP
* @throws {Error}
*/
async function resolveHostname(hostname: string): Promise<string> {
// 使用 toPromise 函数将 dns.lookup 方法转换为 Promise
return toPromise<string>(cb => dns.lookup(hostname, cb)).then((ip) => {
// 记录调试信息,显示已解析的主机名和 IP 地址
Logging.debug`Resolved hostname "${hostname}" to: ${ip}`;
// 返回解析后的 IP 地址
return ip;
});
}
/**
*
*
* @param config -
* @throws {Error}
*/
function validateConfig(config: FileSystemConfig) {
// 检查 config.proxy 是否存在,如果不存在则抛出错误
if (!config.proxy) throw new Error(`Missing field 'config.proxy'`);
// 检查 config.proxy.type 是否存在,如果不存在则抛出错误
if (!config.proxy.type) throw new Error(`Missing field 'config.proxy.type'`);
// 检查 config.proxy.host 是否存在,如果不存在则抛出错误
if (!config.proxy.host) throw new Error(`Missing field 'config.proxy.host'`);
// 检查 config.proxy.port 是否存在,如果不存在则抛出错误
if (!config.proxy.port) throw new Error(`Missing field 'config.proxy.port'`);
// 验证 config.proxy.port 是否为有效的端口号,并更新 config.proxy.port 的值
config.proxy.port = validatePort(config.proxy.port);
}
/**
* SOCKS
*
* @param config -
* @returns
* @throws {Error}
*/
export async function socks(config: FileSystemConfig): Promise<NodeJS.ReadableStream> {
// 记录创建 SOCKS 代理连接的信息
Logging.info`Creating socks proxy connection for ${config.name}`;
// 验证配置对象的有效性
validateConfig(config);
// 检查代理类型是否为 socks4 或 socks5
if (config.proxy!.type !== 'socks4' && config.proxy!.type !== 'socks5') {
// 如果不是,抛出错误
throw new Error(`Expected 'config.proxy.type' to be 'socks4' or 'socks5'`);
}
try {
// 解析代理主机名为 IP 地址
const ipaddress = (await resolveHostname(config.proxy!.host));
// 如果解析失败,抛出错误
if (!ipaddress) throw new Error(`Couldn't resolve '${config.proxy!.host}'`);
// 记录连接信息
Logging.debug`\tConnecting to ${config.host}:${config.port} over ${config.proxy!.type} proxy at ${ipaddress}:${config.proxy!.port}`;
// 创建到目标主机的 SOCKS 连接
const con = await SocksClient.createConnection({
// 定义要执行的命令为 'connect',即建立连接
command: 'connect',
// 目标地址,即要连接的主机和端口
destination: {
// 目标主机,使用配置中的 host 值,该值是必需的
host: config.host!,
// 目标端口,使用配置中的 port 值,该值是必需的
port: config.port!,
},
// 代理服务器的配置
proxy: {
// 代理服务器的 IP 地址,通过解析配置中的 proxy.host 得到
ipaddress,
// 代理服务器的端口号,使用配置中的 proxy.port 值,该值是必需的
port: config.proxy!.port,
// 代理服务器的类型,根据配置中的 proxy.type 确定,支持 socks4 和 socks5
type: config.proxy!.type === 'socks4' ? 4 : 5,
},
});
// 返回连接的可读流
return con.socket as NodeJS.ReadableStream;
} catch (e) {
// 如果连接失败,抛出错误
throw new Error(`Error while connecting to the the proxy: ${e.message}`);
}
}
/**
* HTTP
*
* @param config -
* @returns
* @throws {Error}
*/
export function http(config: FileSystemConfig): Promise<NodeJS.ReadableStream> {
// 记录创建 HTTP 代理连接的信息
Logging.info`Creating http proxy connection for ${config.name}`;
// 验证配置对象的有效性
validateConfig(config);
// 返回一个 Promise用于处理连接结果
return new Promise<NodeJS.ReadableStream>((resolve, reject) => {
// 检查代理类型是否为 http
if (config.proxy!.type !== 'http') {
// 如果不是,拒绝 Promise 并抛出错误
reject(new Error(`Expected config.proxy.type' to be 'http'`));
}
try {
// 记录连接信息
Logging.debug`\tConnecting to ${config.host}:${config.port} over http proxy at ${config.proxy!.host}:${config.proxy!.port}`;
// 创建到目标主机的 HTTP 连接
const req = request({
// 代理服务器的端口号,使用配置中的 proxy.port 值,该值是必需的
port: config.proxy!.port,
// 代理服务器的主机名,使用配置中的 proxy.host 值,该值是必需的
hostname: config.proxy!.host,
// 使用 CONNECT 方法建立隧道
method: 'CONNECT',
// 目标主机和端口,使用配置中的 host 和 port 值,该值是必需的
path: `${config.host}:${config.port}`,
});
// 结束请求
req.end();
// 监听连接事件
req.on('connect', (res, socket) => {
// 连接成功,解析 socket 并返回可读流
resolve(socket as NodeJS.ReadableStream);
});
} catch (e) {
// 如果连接失败,拒绝 Promise 并抛出错误
reject(new Error(`Error while connecting to the the proxy: ${e.message}`));
}
});
}
}
Loading…
Cancel
Save