Compare commits

..

2 Commits

8 changed files with 50 additions and 50 deletions

View File

@@ -48,7 +48,7 @@
"@kevisual/logger": "^0.0.4", "@kevisual/logger": "^0.0.4",
"@kevisual/query": "0.0.33", "@kevisual/query": "0.0.33",
"@kevisual/query-login": "0.0.7", "@kevisual/query-login": "0.0.7",
"@kevisual/router": "^0.0.47", "@kevisual/router": "^0.0.48",
"@kevisual/types": "^0.0.10", "@kevisual/types": "^0.0.10",
"@kevisual/use-config": "^1.0.21", "@kevisual/use-config": "^1.0.21",
"@types/bun": "^1.3.5", "@types/bun": "^1.3.5",

View File

@@ -1,4 +1,5 @@
import { App } from '@kevisual/router'; import { App } from '@kevisual/router';
// import { App } from '@kevisual/router/src/app.ts';
import { HttpsPem } from '@/module/assistant/https/sign.ts'; import { HttpsPem } from '@/module/assistant/https/sign.ts';
// import { AssistantConfig } from '@/module/assistant/index.ts'; // import { AssistantConfig } from '@/module/assistant/index.ts';
import { AssistantInit, parseHomeArg } from '@/services/init/index.ts'; import { AssistantInit, parseHomeArg } from '@/services/init/index.ts';

View File

@@ -2,12 +2,16 @@ import http from 'node:http';
import https from 'node:https'; import https from 'node:https';
import { rewriteCookieDomain } from '../https/cookie-rewrite.ts'; import { rewriteCookieDomain } from '../https/cookie-rewrite.ts';
import { ProxyInfo } from './proxy.ts'; import { ProxyInfo } from './proxy.ts';
import { pipeProxyReq, pipeIncoming, pipeStream } from './pipe.ts'; import { pipeProxyReq, pipeProxyRes, pipeStream } from './pipe.ts';
export const defaultApiProxy = [ export const defaultApiProxy = [
{ {
path: '/api/router', path: '/api/router',
target: 'https://kevisual.cn', target: 'https://kevisual.cn',
}, },
{
path: '/api/s1',
target: 'https://kevisual.cn',
},
{ {
path: '/v1', path: '/v1',
target: 'https://kevisual.cn', target: 'https://kevisual.cn',
@@ -101,7 +105,7 @@ export const httpProxy = (req: http.IncomingMessage, res: http.ServerResponse, p
res.writeHead(proxyRes.statusCode, responseHeaders); res.writeHead(proxyRes.statusCode, responseHeaders);
// 将代理响应流写入客户端响应 // 将代理响应流写入客户端响应
// proxyRes.pipe(res, { end: true }); // proxyRes.pipe(res, { end: true });
pipeIncoming(proxyRes, res); pipeProxyRes(proxyRes, res);
}); });
// 处理代理请求的错误事件 // 处理代理请求的错误事件
proxyReq.on('error', (err) => { proxyReq.on('error', (err) => {
@@ -111,5 +115,5 @@ export const httpProxy = (req: http.IncomingMessage, res: http.ServerResponse, p
}); });
// 处理 POST 请求的请求体(传递数据到目标服务器),end:true 表示当请求体结束时,关闭请求 // 处理 POST 请求的请求体(传递数据到目标服务器),end:true 表示当请求体结束时,关闭请求
// req.pipe(proxyReq, { end: true }); // req.pipe(proxyReq, { end: true });
pipeProxyReq(req, proxyReq); pipeProxyReq(req, proxyReq, res);
} }

View File

@@ -42,16 +42,17 @@ export const pipeStream = (readStream: fs.ReadStream, res: http.ServerResponse)
* @param proxyRes 代理服务器的响应对象 * @param proxyRes 代理服务器的响应对象
* @param res HTTP服务器响应对象 * @param res HTTP服务器响应对象
*/ */
export const pipeIncoming = (proxyRes: http.IncomingMessage, res: http.ServerResponse) => { export const pipeProxyRes = (proxyRes: http.IncomingMessage, res: http.ServerResponse) => {
if (isBun) { if (isBun) {
// Bun环境下需要手动收集数据并end因为Bun的pipe机制与Node.js不同 // Bun环境下需要手动收集数据并end因为Bun的pipe机制与Node.js不同
const chunks: Buffer[] = []; const chunks: Buffer[] = [];
// 监听数据到达事件,收集所有数据块 // 监听数据到达事件,收集所有数据块
proxyRes.on('data', (chunk: Buffer) => { proxyRes.on('data', (chunk: Buffer) => {
chunks.push(chunk); chunks.push(chunk);
}); });
if (proxyRes.url === '/api/router') {
console.log(proxyRes.url, proxyRes.statusCode);
}
// 监听数据结束事件,将收集的数据合并并发送给客户端 // 监听数据结束事件,将收集的数据合并并发送给客户端
proxyRes.on('end', () => { proxyRes.on('end', () => {
const result = Buffer.concat(chunks).toString(); const result = Buffer.concat(chunks).toString();
@@ -77,43 +78,37 @@ export const pipeIncoming = (proxyRes: http.IncomingMessage, res: http.ServerRes
* @param req 客户端的请求对象 * @param req 客户端的请求对象
* @param proxyReq 代理服务器的请求对象 * @param proxyReq 代理服务器的请求对象
*/ */
export const pipeProxyReq = (req: http.IncomingMessage, proxyReq: http.ClientRequest) => { export const pipeProxyReq = async (req: http.IncomingMessage, proxyReq: http.ClientRequest, res: any) => {
if (isBun) { if (isBun) {
// 检查 req 对象是否具有必要的事件监听方法,如果没有,说明可能已经被处理过 try {
if (typeof req.on !== 'function') { // @ts-ignore
// 如果 req.on 不存在,直接结束代理请求 const bunRequest = req.bun.request;
const contentType = req.headers['content-type'] || '';
if (contentType.includes('multipart/form-data')) {
console.log('Processing multipart/form-data');
const arrayBuffer = await bunRequest.arrayBuffer();
// 设置请求头(在写入数据之前)
proxyReq.setHeader('content-type', contentType);
proxyReq.setHeader('content-length', arrayBuffer.byteLength.toString());
// 写入数据并结束请求
if (arrayBuffer.byteLength > 0) {
proxyReq.write(Buffer.from(arrayBuffer));
}
proxyReq.end();
return;
}
console.log('Bun pipeProxyReq content-type', contentType);
// @ts-ignore
const bodyString = req.body;
bodyString && proxyReq.write(bodyString);
proxyReq.end(); proxyReq.end();
return; } catch (error) {
}
// Bun环境下需要手动收集请求数据并发送
const chunks: Buffer[] = [];
// 监听请求数据到达事件,收集所有数据块
req.on('data', (chunk: Buffer) => {
chunks.push(chunk);
});
// 监听请求数据结束事件,将收集的数据合并后发送给目标服务器
req.on('end', () => {
const result = Buffer.concat(chunks);
proxyReq.end(result);
});
// 监听请求错误事件,处理请求传输过程中的错误
req.on('error', (error) => {
// ClientRequest没有writeHead方法直接销毁请求以触发错误处理
proxyReq.destroy(error); proxyReq.destroy(error);
});
} else {
// 非 Bun 环境下使用标准的pipe方法进行流传输
// 同样检查 pipe 方法是否存在以确保兼容性
if (typeof req.pipe === 'function') {
req.pipe(proxyReq, { end: true });
} else {
// 如果 pipe 方法不存在,直接结束代理请求
proxyReq.end();
} }
} else {
// Node.js标准环境下直接使用pipe进行流传输
req.pipe(proxyReq, { end: true });
} }
} }

View File

@@ -39,8 +39,8 @@ export const runServer = async (port: number = 51015, listenPath = '127.0.0.1')
}); });
} }
app.server.on([{ app.server.on([{
id: 'all', id: 'handle-all',
func: proxyRoute as any func: proxyRoute as any,
}, },
...proxyWs() ...proxyWs()
]); ]);

View File

@@ -8,7 +8,7 @@
"dev": "astro dev", "dev": "astro dev",
"build": "astro build", "build": "astro build",
"preview": "astro preview", "preview": "astro preview",
"pub": "envision deploy ./dist -k cli -v 0.0.3 -u", "pub": "envision deploy ./dist -k cli -v 0.0.3 -u -y y",
"slide:dev": "slidev --open slides/index.md", "slide:dev": "slidev --open slides/index.md",
"slide:build": "slidev build slides/index.md --base /root/cli-slide/", "slide:build": "slidev build slides/index.md --base /root/cli-slide/",
"slide:pub": "envision deploy ./slides/dist -k cli-slide -v 0.0.3 -u", "slide:pub": "envision deploy ./slides/dist -k cli-slide -v 0.0.3 -u",

10
pnpm-lock.yaml generated
View File

@@ -146,8 +146,8 @@ importers:
specifier: 0.0.7 specifier: 0.0.7
version: 0.0.7(@kevisual/query@0.0.33) version: 0.0.7(@kevisual/query@0.0.33)
'@kevisual/router': '@kevisual/router':
specifier: ^0.0.47 specifier: ^0.0.48
version: 0.0.47(supports-color@10.2.2) version: 0.0.48(supports-color@10.2.2)
'@kevisual/types': '@kevisual/types':
specifier: ^0.0.10 specifier: ^0.0.10
version: 0.0.10 version: 0.0.10
@@ -1310,8 +1310,8 @@ packages:
'@kevisual/router@0.0.39': '@kevisual/router@0.0.39':
resolution: {integrity: sha512-jE7/csRkMUuuSWl5RZHbOY44xL/2RI/vAJzCsqt150taW5CAri3efdaQJOQlzghlOqqA+1ZyGajxUAYv/HaQxA==} resolution: {integrity: sha512-jE7/csRkMUuuSWl5RZHbOY44xL/2RI/vAJzCsqt150taW5CAri3efdaQJOQlzghlOqqA+1ZyGajxUAYv/HaQxA==}
'@kevisual/router@0.0.47': '@kevisual/router@0.0.48':
resolution: {integrity: sha512-j6/IHQ7hjyJxoSjNbygfrBXi1w7tmGvcNqcLRJwpmSaks65uN6NC9H7Wxna2+/TRtLnRUghHUMIL1pm1uhHeOg==} resolution: {integrity: sha512-WsSvT+NpfC/bZbaAzE3WSKD2DRZP0JuPQJGr4YucSdO/lOLB4cEpOZRbPlV3l7G064ow8QJRAN2DUW+bRjrp1A==}
'@kevisual/types@0.0.10': '@kevisual/types@0.0.10':
resolution: {integrity: sha512-Q73uzzjk9UidumnmCvOpgzqDDvQxsblz22bIFuoiioUFJWwaparx8bpd8ArRyFojicYL1YJoFDzDZ9j9NN8grA==} resolution: {integrity: sha512-Q73uzzjk9UidumnmCvOpgzqDDvQxsblz22bIFuoiioUFJWwaparx8bpd8ArRyFojicYL1YJoFDzDZ9j9NN8grA==}
@@ -6459,7 +6459,7 @@ snapshots:
transitivePeerDependencies: transitivePeerDependencies:
- supports-color - supports-color
'@kevisual/router@0.0.47(supports-color@10.2.2)': '@kevisual/router@0.0.48(supports-color@10.2.2)':
dependencies: dependencies:
path-to-regexp: 8.3.0 path-to-regexp: 8.3.0
selfsigned: 5.2.0 selfsigned: 5.2.0

View File

@@ -1,4 +1,4 @@
import { App } from '@kevisual/app'; import { App } from '@kevisual/app/mod.ts';
import { storage } from '../module/query.ts'; import { storage } from '../module/query.ts';
import { sessionStorage } from '../module/cache.ts'; import { sessionStorage } from '../module/cache.ts';
export const app = new App({ token: storage.getItem('token') || '', storage: sessionStorage }); export const app = new App({ token: storage.getItem('token') || '', storage: sessionStorage });