暂存
This commit is contained in:
		@@ -8,9 +8,11 @@ import { useConfig } from '@abearxiong/use-config';
 | 
			
		||||
import { redis } from './redis/redis.ts';
 | 
			
		||||
import { getContentType } from './get-content-type.ts';
 | 
			
		||||
import { sleep } from '@/utils/sleep.ts';
 | 
			
		||||
import { handleProxyRequest } from './proxy.ts';
 | 
			
		||||
const { api, domain, allowedOrigins } = useConfig<{
 | 
			
		||||
  api: {
 | 
			
		||||
    host: string;
 | 
			
		||||
    port?: number;
 | 
			
		||||
  };
 | 
			
		||||
  domain: string;
 | 
			
		||||
  allowedOrigins: string[];
 | 
			
		||||
@@ -19,6 +21,60 @@ const { api, domain, allowedOrigins } = useConfig<{
 | 
			
		||||
const fileStore = useFileStore('upload');
 | 
			
		||||
const noProxyUrl = ['/', '/favicon.ico'];
 | 
			
		||||
export const handleRequest = async (req: http.IncomingMessage, res: http.ServerResponse) => {
 | 
			
		||||
  if (req.url === '/favicon.ico') {
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
  if (req.url.startsWith('/api/router')) {
 | 
			
		||||
    // 代理到 http://codeflow.xiongxiao.me/api
 | 
			
		||||
    const _u = new URL(req.url, `http://${api.host}`);
 | 
			
		||||
    // 设置代理请求的目标 URL 和请求头
 | 
			
		||||
    let header: any = {};
 | 
			
		||||
    if (req.headers?.['Authroization']) {
 | 
			
		||||
      header.Authorization = req.headers?.['Authroization'];
 | 
			
		||||
    }
 | 
			
		||||
    if (req.headers?.['Content-Type']) {
 | 
			
		||||
      header['Content-Type'] = req.headers?.['Content-Type'];
 | 
			
		||||
    }
 | 
			
		||||
    const options = {
 | 
			
		||||
      host: _u.hostname,
 | 
			
		||||
      path: req.url,
 | 
			
		||||
      method: req.method,
 | 
			
		||||
      headers: {
 | 
			
		||||
        ...header,
 | 
			
		||||
      },
 | 
			
		||||
    };
 | 
			
		||||
    if (_u.port) {
 | 
			
		||||
      // @ts-ignore
 | 
			
		||||
      options.port = _u.port;
 | 
			
		||||
    }
 | 
			
		||||
    // 创建代理请求
 | 
			
		||||
    const proxyReq = http.request(options, (proxyRes) => {
 | 
			
		||||
      // 将代理服务器的响应头和状态码返回给客户端
 | 
			
		||||
      res.writeHead(proxyRes.statusCode, proxyRes.headers);
 | 
			
		||||
      // 将代理响应流写入客户端响应
 | 
			
		||||
      proxyRes.pipe(res, { end: true });
 | 
			
		||||
    });
 | 
			
		||||
    // 处理代理请求的错误事件
 | 
			
		||||
    proxyReq.on('error', (err) => {
 | 
			
		||||
      console.error(`Proxy request error: ${err.message}`);
 | 
			
		||||
      res.writeHead(500, { 'Content-Type': 'text/plain' });
 | 
			
		||||
      res.write(`Proxy request error: ${err.message}`);
 | 
			
		||||
    });
 | 
			
		||||
    // 处理 POST 请求的请求体(传递数据到目标服务器)
 | 
			
		||||
    req.pipe(proxyReq, { end: true });
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
  if (req.url.startsWith('/api/proxy')) {
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
  if (req.url.startsWith('/api')) {
 | 
			
		||||
    res.end('not catch api');
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
  if (req.url.startsWith('/test')) {
 | 
			
		||||
    handleProxyRequest(req, res);
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
  const dns = getDNS(req);
 | 
			
		||||
  // 配置可以跨域
 | 
			
		||||
  // 配置可以访问的域名 localhost, xiongxiao.me
 | 
			
		||||
@@ -87,42 +143,7 @@ export const handleRequest = async (req: http.IncomingMessage, res: http.ServerR
 | 
			
		||||
    user = _user;
 | 
			
		||||
    app = _app;
 | 
			
		||||
  }
 | 
			
		||||
  const [_, _api] = req.url.split('/');
 | 
			
		||||
  if (_api === 'api') {
 | 
			
		||||
    // 代理到 http://codeflow.xiongxiao.me/api
 | 
			
		||||
    // 设置代理请求的目标 URL 和请求头
 | 
			
		||||
    let header: any = {};
 | 
			
		||||
    if (req.headers?.['Authroization']) {
 | 
			
		||||
      header.Authorization = req.headers?.['Authroization'];
 | 
			
		||||
    }
 | 
			
		||||
    if (req.headers?.['Content-Type']) {
 | 
			
		||||
      header['Content-Type'] = req.headers?.['Content-Type'];
 | 
			
		||||
    }
 | 
			
		||||
    const options = {
 | 
			
		||||
      host: api.host,
 | 
			
		||||
      path: req.url,
 | 
			
		||||
      method: 'POST',
 | 
			
		||||
      headers: {
 | 
			
		||||
        ...header,
 | 
			
		||||
      },
 | 
			
		||||
    };
 | 
			
		||||
    // 创建代理请求
 | 
			
		||||
    const proxyReq = http.request(options, (proxyRes) => {
 | 
			
		||||
      // 将代理服务器的响应头和状态码返回给客户端
 | 
			
		||||
      res.writeHead(proxyRes.statusCode, proxyRes.headers);
 | 
			
		||||
      // 将代理响应流写入客户端响应
 | 
			
		||||
      proxyRes.pipe(res, { end: true });
 | 
			
		||||
    });
 | 
			
		||||
    // 处理代理请求的错误事件
 | 
			
		||||
    proxyReq.on('error', (err) => {
 | 
			
		||||
      console.error(`Proxy request error: ${err.message}`);
 | 
			
		||||
      res.writeHead(500, { 'Content-Type': 'text/plain' });
 | 
			
		||||
      res.write(`Proxy request error: ${err.message}`);
 | 
			
		||||
    });
 | 
			
		||||
    // 处理 POST 请求的请求体(传递数据到目标服务器)
 | 
			
		||||
    req.pipe(proxyReq, { end: true });
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const userApp = new UserApp({ user, app });
 | 
			
		||||
  let isExist = await userApp.getExist();
 | 
			
		||||
  if (!isExist) {
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										64
									
								
								src/module/proxy.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										64
									
								
								src/module/proxy.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,64 @@
 | 
			
		||||
import http from 'http';
 | 
			
		||||
import httpProxy from 'http-proxy';
 | 
			
		||||
import { useConfig } from '@abearxiong/use-config';
 | 
			
		||||
 | 
			
		||||
const { resources, api } = useConfig<{
 | 
			
		||||
  resources: string;
 | 
			
		||||
  api: { host: string };
 | 
			
		||||
}>();
 | 
			
		||||
const proxy = httpProxy.createProxyServer({});
 | 
			
		||||
const fetchTest = async (id: string) => {
 | 
			
		||||
  const fetchUrl = 'http://' + api.host + '/api/router';
 | 
			
		||||
  const fetchRes = await fetch(fetchUrl, {
 | 
			
		||||
    method: 'POST',
 | 
			
		||||
    headers: {
 | 
			
		||||
      'Content-Type': 'application/json',
 | 
			
		||||
    },
 | 
			
		||||
    body: JSON.stringify({
 | 
			
		||||
      path: 'user-app',
 | 
			
		||||
      key: 'test',
 | 
			
		||||
      id: id,
 | 
			
		||||
    }),
 | 
			
		||||
  }).then((res) => res.json());
 | 
			
		||||
  return fetchRes;
 | 
			
		||||
};
 | 
			
		||||
// 60939f5e-f51b-4563-8c96-7a98ac5ac259
 | 
			
		||||
export const handleProxyRequest = async (req: http.IncomingMessage, res: http.ServerResponse) => {
 | 
			
		||||
  const url = req.url;
 | 
			
		||||
  const urls = url.split('/');
 | 
			
		||||
  const [_, test, id] = urls;
 | 
			
		||||
  const error = (msg: string) => {
 | 
			
		||||
    res.writeHead(404, { 'Content-Type': 'text/plain' });
 | 
			
		||||
    res.write(msg);
 | 
			
		||||
    res.end();
 | 
			
		||||
  };
 | 
			
		||||
  if (test !== 'test') {
 | 
			
		||||
    error('Not Found');
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
  if (!id) {
 | 
			
		||||
    error('Need Test ID');
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
  // 判断id是uuid
 | 
			
		||||
  if (!isUUID(id)) {
 | 
			
		||||
    error('Need Test ID is UUID');
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
  const result = await fetchTest(id);
 | 
			
		||||
  console.log('data', result);
 | 
			
		||||
  if (result.code !== 200) {
 | 
			
		||||
    error('fetch error');
 | 
			
		||||
    return;
 | 
			
		||||
  }
 | 
			
		||||
  const files = result.data?.data?.files;
 | 
			
		||||
  const appFileUrl = (url + '').replace(`/${test}/${id}/`, '');
 | 
			
		||||
  const pathFile = files.find((file: any) => file.name === appFileUrl);
 | 
			
		||||
  const target = `https://${resources}/${pathFile.path}`;
 | 
			
		||||
  console.log('target', target);
 | 
			
		||||
  proxy.web(req, res, { target: target, secure: false });
 | 
			
		||||
};
 | 
			
		||||
function isUUID(id: string): boolean {
 | 
			
		||||
  const uuidRegex = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;
 | 
			
		||||
  return uuidRegex.test(id);
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										40
									
								
								src/module/query/get-router.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										40
									
								
								src/module/query/get-router.ts
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,40 @@
 | 
			
		||||
import { useConfig } from '@abearxiong/use-config';
 | 
			
		||||
 | 
			
		||||
const { resources, api } = useConfig<{
 | 
			
		||||
  resources: string;
 | 
			
		||||
  api: { host: string };
 | 
			
		||||
}>();
 | 
			
		||||
 | 
			
		||||
export const fetchTest = async (id: string) => {
 | 
			
		||||
  const fetchUrl = 'http://' + api.host + '/api/router';
 | 
			
		||||
  const fetchRes = await fetch(fetchUrl, {
 | 
			
		||||
    method: 'POST',
 | 
			
		||||
    headers: {
 | 
			
		||||
      'Content-Type': 'application/json',
 | 
			
		||||
    },
 | 
			
		||||
    body: JSON.stringify({
 | 
			
		||||
      path: 'user-app',
 | 
			
		||||
      key: 'test',
 | 
			
		||||
      id: id,
 | 
			
		||||
    }),
 | 
			
		||||
  }).then((res) => res.json());
 | 
			
		||||
  return fetchRes;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
export const fetchDomain = async (domain: string) => {
 | 
			
		||||
  const fetchUrl = 'http://' + api.host + '/api/router';
 | 
			
		||||
  const fetchRes = await fetch(fetchUrl, {
 | 
			
		||||
    method: 'POST',
 | 
			
		||||
    headers: {
 | 
			
		||||
      'Content-Type': 'application/json',
 | 
			
		||||
    },
 | 
			
		||||
    body: JSON.stringify({
 | 
			
		||||
      path: 'app',
 | 
			
		||||
      key: 'getDomainApp',
 | 
			
		||||
      data: {
 | 
			
		||||
        domain,
 | 
			
		||||
      },
 | 
			
		||||
    }),
 | 
			
		||||
  }).then((res) => res.json());
 | 
			
		||||
  return fetchRes;
 | 
			
		||||
};
 | 
			
		||||
		Reference in New Issue
	
	Block a user