fix: 配置修改,添加socket代理

This commit is contained in:
2025-03-06 22:11:34 +08:00
parent d548d3ab04
commit bb86a7c507
10 changed files with 867 additions and 161 deletions

View File

@@ -11,6 +11,17 @@ type ConfigType = {
path?: string;
port?: number;
};
apiList: {
path: string;
/**
* url或者相对路径
*/
target: string;
/**
* 类型
*/
type?: 'static' | 'dynamic' | 'minio';
}[];
proxy: {
port?: number;
/**

View File

@@ -6,6 +6,8 @@ import path from 'path';
import fs from 'fs';
import { getContentType } from './get-content-type.ts';
import { createRefreshHtml } from './html/create-refresh-html.ts';
import { fileProxy } from './proxy/file-proxy.ts';
import net from 'net';
const api = config?.api || { host: 'kevisual.xiongxiao.me', path: '/api/router' };
const domain = config?.proxy?.domain || 'kevisual.xiongxiao.me';
@@ -20,11 +22,18 @@ export const handleRequest = async (req: http.IncomingMessage, res: http.ServerR
return;
}
if (req.url.startsWith('/api/proxy')) {
// 已经代理过了
return;
}
if (req.url.startsWith('/api')) {
// 代理到 http://codeflow.xiongxiao.me/api
const _u = new URL(req.url, `http://${api.host}`);
console.log('req', req.url, 'len', config?.apiList?.length);
const proxyApiList = config?.apiList || [];
const proxyApi = proxyApiList.find((item) => req.url.startsWith(item.path));
if (proxyApi && proxyApi?.type === 'static') {
return fileProxy(req, res, proxyApi);
}
if (proxyApi) {
const _u = new URL(req.url, `${proxyApi.target}`);
console.log('proxyApi', req.url, _u.href);
// 设置代理请求的目标 URL 和请求头
let header: any = {};
if (req.headers?.['Authorization']) {
@@ -32,9 +41,11 @@ export const handleRequest = async (req: http.IncomingMessage, res: http.ServerR
} else if (req.headers?.['authorization']) {
header.authorization = req.headers['authorization'];
}
if (req.headers?.['Content-Type']) {
header['Content-Type'] = req.headers?.['Content-Type'];
}
// 提取req的headers中的非HOST的header
const headers = Object.keys(req.headers).filter((item) => item && item.toLowerCase() !== 'host');
headers.forEach((item) => {
header[item] = req.headers[item];
});
const options = {
host: _u.hostname,
path: req.url,
@@ -64,7 +75,7 @@ export const handleRequest = async (req: http.IncomingMessage, res: http.ServerR
req.pipe(proxyReq, { end: true });
return;
}
if (req.url.startsWith('/api')) {
if (req.url.startsWith('/api') || req.url.startsWith('/v1')) {
res.end('not catch api');
return;
}
@@ -244,3 +255,4 @@ export const handleRequest = async (req: http.IncomingMessage, res: http.ServerR
console.error('getFile error', error);
}
};

24
src/module/minio.ts Normal file
View File

@@ -0,0 +1,24 @@
import { Client, ClientOptions } from 'minio';
import { useConfig } from '@kevisual/use-config';
type MinioConfig = {
minio: ClientOptions & { bucketName: string };
};
const config = useConfig<MinioConfig>();
const { bucketName, ...minioRest } = config.minio;
export const minioClient = new Client(minioRest);
export { bucketName };
if (!minioClient) {
throw new Error('Minio client not initialized');
}
// 验证权限
// (async () => {
// const bucketExists = await minioClient.bucketExists(bucketName);
// if (!bucketExists) {
// await minioClient.makeBucket(bucketName);
// }
// const res = await minioClient.putObject(bucketName, 'private/test/a.b', 'test');
// console.log('minio putObject', res);
// })();

View File

@@ -0,0 +1,26 @@
import http from 'http';
import send from 'send';
import fs from 'fs';
import { fileIsExist } from '@kevisual/use-config';
import path from 'path';
export type ProxyInfo = {
path?: string;
target: string;
type?: 'static' | 'dynamic' | 'minio';
};
export const fileProxy = (req: http.IncomingMessage, res: http.ServerResponse, proxyApi: ProxyInfo) => {
// url开头的文件
const url = new URL(req.url, 'http://localhost');
const pathname = url.pathname;
// 检测文件是否存在如果文件不存在则返回404
const filePath = path.join(process.cwd(), proxyApi.target, pathname);
if (!fileIsExist(filePath)) {
res.statusCode = 404;
res.end('Not Found File');
return;
}
const file = send(req, pathname, {
root: proxyApi.target,
});
file.pipe(res);
};

View File

@@ -0,0 +1,24 @@
import http from 'http';
import { minioClient } from '../minio.ts';
export type ProxyInfo = {
path?: string;
target: string;
type?: 'static' | 'dynamic' | 'minio';
};
export const minioProxy = async (req: http.IncomingMessage, res: http.ServerResponse, proxyApi: ProxyInfo) => {
try {
const requestUrl = new URL(req.url, 'http://localhost');
const objectPath = requestUrl.pathname;
const bucketName = proxyApi.target;
let objectName = objectPath.slice(1);
if (objectName.startsWith(bucketName)) {
objectName = objectName.slice(bucketName.length);
}
const objectStream = await minioClient.getObject(bucketName, objectName);
objectStream.pipe(res);
} catch (error) {
console.error('Error fetching object from MinIO:', error);
res.statusCode = 500;
res.end('Internal Server Error');
}
};