暂存
This commit is contained in:
		| @@ -1,7 +1,7 @@ | |||||||
| { | { | ||||||
|   port: 3005, |   port: 3005, | ||||||
|   api: { |   api: { | ||||||
|     host: 'localhost:4000', // 后台代理 |     host: 'localhost:4002', // 后台代理 | ||||||
|     path: '/api/router', |     path: '/api/router', | ||||||
|   }, |   }, | ||||||
|   allowedOrigins: ['localhost', 'xiongxiao.me', 'zxj.im'], |   allowedOrigins: ['localhost', 'xiongxiao.me', 'zxj.im'], | ||||||
|   | |||||||
| @@ -19,6 +19,7 @@ | |||||||
|     "@rollup/plugin-json": "^6.1.0", |     "@rollup/plugin-json": "^6.1.0", | ||||||
|     "@rollup/plugin-node-resolve": "^15.3.0", |     "@rollup/plugin-node-resolve": "^15.3.0", | ||||||
|     "@rollup/plugin-typescript": "^12.1.0", |     "@rollup/plugin-typescript": "^12.1.0", | ||||||
|  |     "@types/http-proxy": "^1.17.15", | ||||||
|     "@types/node": "^22.7.5", |     "@types/node": "^22.7.5", | ||||||
|     "cross-env": "^7.0.3", |     "cross-env": "^7.0.3", | ||||||
|     "nodemon": "^3.1.7", |     "nodemon": "^3.1.7", | ||||||
| @@ -28,9 +29,10 @@ | |||||||
|     "typescript": "^5.6.3" |     "typescript": "^5.6.3" | ||||||
|   }, |   }, | ||||||
|   "dependencies": { |   "dependencies": { | ||||||
|     "@abearxiong/router": "0.0.1-alpha.40", |     "@abearxiong/router": "0.0.1-alpha.43", | ||||||
|     "@abearxiong/use-config": "^0.0.2", |     "@abearxiong/use-config": "^0.0.2", | ||||||
|     "@abearxiong/use-file-store": "^0.0.1", |     "@abearxiong/use-file-store": "^0.0.1", | ||||||
|  |     "http-proxy": "^1.18.1", | ||||||
|     "ioredis": "^5.4.1", |     "ioredis": "^5.4.1", | ||||||
|     "nanoid": "^5.0.7" |     "nanoid": "^5.0.7" | ||||||
|   }, |   }, | ||||||
|   | |||||||
							
								
								
									
										67
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										67
									
								
								pnpm-lock.yaml
									
									
									
										generated
									
									
									
								
							| @@ -11,6 +11,9 @@ importers: | |||||||
|  |  | ||||||
|   .: |   .: | ||||||
|     dependencies: |     dependencies: | ||||||
|  |       '@abearxiong/router': | ||||||
|  |         specifier: 0.0.1-alpha.43 | ||||||
|  |         version: 0.0.1-alpha.43 | ||||||
|       '@abearxiong/use-config': |       '@abearxiong/use-config': | ||||||
|         specifier: ^0.0.2 |         specifier: ^0.0.2 | ||||||
|         version: 0.0.2 |         version: 0.0.2 | ||||||
| @@ -60,6 +63,9 @@ importers: | |||||||
|  |  | ||||||
| packages: | packages: | ||||||
|  |  | ||||||
|  |   '@abearxiong/router@0.0.1-alpha.43': | ||||||
|  |     resolution: {integrity: sha512-umwi4T5s54Zb8ItseGw3uB7PDG8BqnHyAughlXH2dhub4f49fO+rwR+Zth7scUONkmc21Z27/lPgLBHXrYOkYw==, tarball: https://npm.pkg.github.com/download/@abearxiong/router/0.0.1-alpha.43/287c6e2597b36c5e3ed351b473e38f468b5f49ea} | ||||||
|  |  | ||||||
|   '@abearxiong/use-config@0.0.2': |   '@abearxiong/use-config@0.0.2': | ||||||
|     resolution: {integrity: sha512-IBOmeP46ykbDlkplFS65UsAHjyPDKnvS2oqbkpLWhbSwDbF5zhBnD4ibsFZKPCyc3lMlPeRqYva4x6puX3E/qQ==, tarball: https://npm.pkg.github.com/download/@abearxiong/use-config/0.0.2/59fbeec8c8e086ec48e55024fe39020b079e6fa5} |     resolution: {integrity: sha512-IBOmeP46ykbDlkplFS65UsAHjyPDKnvS2oqbkpLWhbSwDbF5zhBnD4ibsFZKPCyc3lMlPeRqYva4x6puX3E/qQ==, tarball: https://npm.pkg.github.com/download/@abearxiong/use-config/0.0.2/59fbeec8c8e086ec48e55024fe39020b079e6fa5} | ||||||
|  |  | ||||||
| @@ -231,6 +237,9 @@ packages: | |||||||
|   '@types/estree@1.0.6': |   '@types/estree@1.0.6': | ||||||
|     resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} |     resolution: {integrity: sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==} | ||||||
|  |  | ||||||
|  |   '@types/http-proxy@1.17.15': | ||||||
|  |     resolution: {integrity: sha512-25g5atgiVNTIv0LBDTg1H74Hvayx0ajtJPLLcYE3whFv75J0pWNtOBzaXJQgDTmrX1bx5U9YC2w/n65BN1HwRQ==} | ||||||
|  |  | ||||||
|   '@types/json-schema@7.0.15': |   '@types/json-schema@7.0.15': | ||||||
|     resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} |     resolution: {integrity: sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==} | ||||||
|  |  | ||||||
| @@ -433,6 +442,9 @@ packages: | |||||||
|   estree-walker@2.0.2: |   estree-walker@2.0.2: | ||||||
|     resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} |     resolution: {integrity: sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w==} | ||||||
|  |  | ||||||
|  |   eventemitter3@4.0.7: | ||||||
|  |     resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} | ||||||
|  |  | ||||||
|   events@3.3.0: |   events@3.3.0: | ||||||
|     resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} |     resolution: {integrity: sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==} | ||||||
|     engines: {node: '>=0.8.x'} |     engines: {node: '>=0.8.x'} | ||||||
| @@ -455,6 +467,15 @@ packages: | |||||||
|     resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} |     resolution: {integrity: sha512-YsGpe3WHLK8ZYi4tWDg2Jy3ebRz2rXowDxnld4bkQB00cc/1Zw9AWnC0i9ztDJitivtQvaI9KaLyKrc+hBW0yg==} | ||||||
|     engines: {node: '>=8'} |     engines: {node: '>=8'} | ||||||
|  |  | ||||||
|  |   follow-redirects@1.15.9: | ||||||
|  |     resolution: {integrity: sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==} | ||||||
|  |     engines: {node: '>=4.0'} | ||||||
|  |     peerDependencies: | ||||||
|  |       debug: '*' | ||||||
|  |     peerDependenciesMeta: | ||||||
|  |       debug: | ||||||
|  |         optional: true | ||||||
|  |  | ||||||
|   fsevents@2.3.3: |   fsevents@2.3.3: | ||||||
|     resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} |     resolution: {integrity: sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==} | ||||||
|     engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} |     engines: {node: ^8.16.0 || ^10.6.0 || >=11.0.0} | ||||||
| @@ -485,6 +506,10 @@ packages: | |||||||
|     resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} |     resolution: {integrity: sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==} | ||||||
|     engines: {node: '>= 0.4'} |     engines: {node: '>= 0.4'} | ||||||
|  |  | ||||||
|  |   http-proxy@1.18.1: | ||||||
|  |     resolution: {integrity: sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==} | ||||||
|  |     engines: {node: '>=8.0.0'} | ||||||
|  |  | ||||||
|   ignore-by-default@1.0.1: |   ignore-by-default@1.0.1: | ||||||
|     resolution: {integrity: sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==} |     resolution: {integrity: sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==} | ||||||
|  |  | ||||||
| @@ -626,6 +651,9 @@ packages: | |||||||
|     resolution: {integrity: sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==} |     resolution: {integrity: sha512-DJnGAeenTdpMEH6uAJRK/uiyEIH9WVsUmoLwzudwGJUwZPp80PDBWPHXSAGNPwNvIXAbe7MSUB1zQFugFml66A==} | ||||||
|     engines: {node: '>=4'} |     engines: {node: '>=4'} | ||||||
|  |  | ||||||
|  |   requires-port@1.0.0: | ||||||
|  |     resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} | ||||||
|  |  | ||||||
|   resolve@1.22.8: |   resolve@1.22.8: | ||||||
|     resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} |     resolution: {integrity: sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==} | ||||||
|     hasBin: true |     hasBin: true | ||||||
| @@ -781,8 +809,27 @@ packages: | |||||||
|     engines: {node: '>= 8'} |     engines: {node: '>= 8'} | ||||||
|     hasBin: true |     hasBin: true | ||||||
|  |  | ||||||
|  |   ws@8.18.0: | ||||||
|  |     resolution: {integrity: sha512-8VbfWfHLbbwu3+N6OKsOMpBdT4kXPDDB9cJk2bJ6mh9ucxdlnNvH1e+roYkKmN9Nxw2yjz7VzeO9oOz2zJ04Pw==} | ||||||
|  |     engines: {node: '>=10.0.0'} | ||||||
|  |     peerDependencies: | ||||||
|  |       bufferutil: ^4.0.1 | ||||||
|  |       utf-8-validate: '>=5.0.2' | ||||||
|  |     peerDependenciesMeta: | ||||||
|  |       bufferutil: | ||||||
|  |         optional: true | ||||||
|  |       utf-8-validate: | ||||||
|  |         optional: true | ||||||
|  |  | ||||||
| snapshots: | snapshots: | ||||||
|  |  | ||||||
|  |   '@abearxiong/router@0.0.1-alpha.43': | ||||||
|  |     dependencies: | ||||||
|  |       ws: 8.18.0 | ||||||
|  |     transitivePeerDependencies: | ||||||
|  |       - bufferutil | ||||||
|  |       - utf-8-validate | ||||||
|  |  | ||||||
|   '@abearxiong/use-config@0.0.2': {} |   '@abearxiong/use-config@0.0.2': {} | ||||||
|  |  | ||||||
|   '@abearxiong/use-file-store@0.0.1(typescript@5.6.3)': |   '@abearxiong/use-file-store@0.0.1(typescript@5.6.3)': | ||||||
| @@ -916,6 +963,10 @@ snapshots: | |||||||
|  |  | ||||||
|   '@types/estree@1.0.6': {} |   '@types/estree@1.0.6': {} | ||||||
|  |  | ||||||
|  |   '@types/http-proxy@1.17.15': | ||||||
|  |     dependencies: | ||||||
|  |       '@types/node': 22.7.5 | ||||||
|  |  | ||||||
|   '@types/json-schema@7.0.15': {} |   '@types/json-schema@7.0.15': {} | ||||||
|  |  | ||||||
|   '@types/node@22.7.5': |   '@types/node@22.7.5': | ||||||
| @@ -1133,6 +1184,8 @@ snapshots: | |||||||
|  |  | ||||||
|   estree-walker@2.0.2: {} |   estree-walker@2.0.2: {} | ||||||
|  |  | ||||||
|  |   eventemitter3@4.0.7: {} | ||||||
|  |  | ||||||
|   events@3.3.0: {} |   events@3.3.0: {} | ||||||
|  |  | ||||||
|   fast-deep-equal@3.1.3: {} |   fast-deep-equal@3.1.3: {} | ||||||
| @@ -1147,6 +1200,8 @@ snapshots: | |||||||
|     dependencies: |     dependencies: | ||||||
|       to-regex-range: 5.0.1 |       to-regex-range: 5.0.1 | ||||||
|  |  | ||||||
|  |   follow-redirects@1.15.9: {} | ||||||
|  |  | ||||||
|   fsevents@2.3.3: |   fsevents@2.3.3: | ||||||
|     optional: true |     optional: true | ||||||
|  |  | ||||||
| @@ -1168,6 +1223,14 @@ snapshots: | |||||||
|     dependencies: |     dependencies: | ||||||
|       function-bind: 1.1.2 |       function-bind: 1.1.2 | ||||||
|  |  | ||||||
|  |   http-proxy@1.18.1: | ||||||
|  |     dependencies: | ||||||
|  |       eventemitter3: 4.0.7 | ||||||
|  |       follow-redirects: 1.15.9 | ||||||
|  |       requires-port: 1.0.0 | ||||||
|  |     transitivePeerDependencies: | ||||||
|  |       - debug | ||||||
|  |  | ||||||
|   ignore-by-default@1.0.1: {} |   ignore-by-default@1.0.1: {} | ||||||
|  |  | ||||||
|   ioredis@5.4.1: |   ioredis@5.4.1: | ||||||
| @@ -1296,6 +1359,8 @@ snapshots: | |||||||
|     dependencies: |     dependencies: | ||||||
|       redis-errors: 1.2.0 |       redis-errors: 1.2.0 | ||||||
|  |  | ||||||
|  |   requires-port@1.0.0: {} | ||||||
|  |  | ||||||
|   resolve@1.22.8: |   resolve@1.22.8: | ||||||
|     dependencies: |     dependencies: | ||||||
|       is-core-module: 2.15.1 |       is-core-module: 2.15.1 | ||||||
| @@ -1467,3 +1532,5 @@ snapshots: | |||||||
|   which@2.0.2: |   which@2.0.2: | ||||||
|     dependencies: |     dependencies: | ||||||
|       isexe: 2.0.0 |       isexe: 2.0.0 | ||||||
|  |  | ||||||
|  |   ws@8.18.0: {} | ||||||
|   | |||||||
							
								
								
									
										9
									
								
								src/app.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								src/app.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,9 @@ | |||||||
|  | import { App } from '@abearxiong/router'; | ||||||
|  |  | ||||||
|  | export const app = new App({ | ||||||
|  |   serverOptions: { | ||||||
|  |     path: '/api/proxy', | ||||||
|  |   }, | ||||||
|  | }); | ||||||
|  |  | ||||||
|  | // app.server.on(callback); | ||||||
							
								
								
									
										25
									
								
								src/index.ts
									
									
									
									
									
								
							
							
						
						
									
										25
									
								
								src/index.ts
									
									
									
									
									
								
							| @@ -1,14 +1,21 @@ | |||||||
| import http from 'http'; |  | ||||||
| import { handleRequest } from './module/index.ts'; | import { handleRequest } from './module/index.ts'; | ||||||
| import { useConfig } from '@abearxiong/use-config'; | import { useConfig } from '@abearxiong/use-config'; | ||||||
|  | import { app } from './app.ts'; | ||||||
|  | import './route/route.ts' | ||||||
| const { port } = useConfig<{ port: number }>(); | const { port } = useConfig<{ port: number }>(); | ||||||
| const server = http.createServer((req, res) => { |  | ||||||
|   // res.writeHead(200, { 'Content-Type': 'text/plain' }); | app | ||||||
|   // const pathname = new URL(req.url, `http://${dns.hostName}`).pathname; |   .route({ | ||||||
|   handleRequest(req, res); |     path: 'hello', | ||||||
|   // res.write(`Request from ${dns.hostName} with IP: ${dns.ip}\n`); |     key: '0', | ||||||
|   // res.end('Hello World\n'); |   }) | ||||||
| }); |   .define(async (ctx) => { | ||||||
| server.listen(port, () => { |     ctx.body = 'hello world'; | ||||||
|  |   }) | ||||||
|  |   .addTo(app); | ||||||
|  |  | ||||||
|  | app.listen(port, () => { | ||||||
|   console.log(`Server running at http://localhost:${port}/`); |   console.log(`Server running at http://localhost:${port}/`); | ||||||
| }); | }); | ||||||
|  |  | ||||||
|  | app.server.on(handleRequest); | ||||||
|   | |||||||
| @@ -8,9 +8,11 @@ import { useConfig } from '@abearxiong/use-config'; | |||||||
| import { redis } from './redis/redis.ts'; | import { redis } from './redis/redis.ts'; | ||||||
| import { getContentType } from './get-content-type.ts'; | import { getContentType } from './get-content-type.ts'; | ||||||
| import { sleep } from '@/utils/sleep.ts'; | import { sleep } from '@/utils/sleep.ts'; | ||||||
|  | import { handleProxyRequest } from './proxy.ts'; | ||||||
| const { api, domain, allowedOrigins } = useConfig<{ | const { api, domain, allowedOrigins } = useConfig<{ | ||||||
|   api: { |   api: { | ||||||
|     host: string; |     host: string; | ||||||
|  |     port?: number; | ||||||
|   }; |   }; | ||||||
|   domain: string; |   domain: string; | ||||||
|   allowedOrigins: string[]; |   allowedOrigins: string[]; | ||||||
| @@ -19,6 +21,60 @@ const { api, domain, allowedOrigins } = useConfig<{ | |||||||
| const fileStore = useFileStore('upload'); | const fileStore = useFileStore('upload'); | ||||||
| const noProxyUrl = ['/', '/favicon.ico']; | const noProxyUrl = ['/', '/favicon.ico']; | ||||||
| export const handleRequest = async (req: http.IncomingMessage, res: http.ServerResponse) => { | 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); |   const dns = getDNS(req); | ||||||
|   // 配置可以跨域 |   // 配置可以跨域 | ||||||
|   // 配置可以访问的域名 localhost, xiongxiao.me |   // 配置可以访问的域名 localhost, xiongxiao.me | ||||||
| @@ -87,42 +143,7 @@ export const handleRequest = async (req: http.IncomingMessage, res: http.ServerR | |||||||
|     user = _user; |     user = _user; | ||||||
|     app = _app; |     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 }); |   const userApp = new UserApp({ user, app }); | ||||||
|   let isExist = await userApp.getExist(); |   let isExist = await userApp.getExist(); | ||||||
|   if (!isExist) { |   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; | ||||||
|  | }; | ||||||
							
								
								
									
										1
									
								
								src/route/app/index.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								src/route/app/index.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | import './list.ts' | ||||||
							
								
								
									
										72
									
								
								src/route/app/list.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										72
									
								
								src/route/app/list.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,72 @@ | |||||||
|  | import { UserApp } from '@/module/get-user-app.ts'; | ||||||
|  | import { app } from '../../app.ts'; | ||||||
|  | import { redis } from '@/module/redis/redis.ts'; | ||||||
|  | import { CustomError } from '@abearxiong/router'; | ||||||
|  | import fs from 'fs'; | ||||||
|  | import { useFileStore } from '@abearxiong/use-file-store'; | ||||||
|  | const fileStore = useFileStore('upload'); | ||||||
|  |  | ||||||
|  | app | ||||||
|  |   .route({ | ||||||
|  |     path: 'app', | ||||||
|  |     key: 'list', | ||||||
|  |   }) | ||||||
|  |   .define(async (ctx) => { | ||||||
|  |     const keys = await redis.keys('user:app:*'); | ||||||
|  |     // const keys = await redis.keys('user:app:exist:*'); | ||||||
|  |     // const data = await redis.mget(...keys); | ||||||
|  |     ctx.body = { | ||||||
|  |       // data: data, | ||||||
|  |       keys, | ||||||
|  |     }; | ||||||
|  |   }) | ||||||
|  |   .addTo(app); | ||||||
|  |  | ||||||
|  | app | ||||||
|  |   .route({ | ||||||
|  |     path: 'app', | ||||||
|  |     key: 'delete', | ||||||
|  |   }) | ||||||
|  |   .define(async (ctx) => { | ||||||
|  |     const { user, app } = ctx.query; | ||||||
|  |     try { | ||||||
|  |       const userApp = new UserApp({ user, app }); | ||||||
|  |       await userApp.clearCacheData(); | ||||||
|  |     } catch (error) { | ||||||
|  |       console.error(error); | ||||||
|  |       throw new CustomError('删除失败'); | ||||||
|  |     } | ||||||
|  |     ctx.body = 'successfully'; | ||||||
|  |   }) | ||||||
|  |   .addTo(app); | ||||||
|  |  | ||||||
|  | app | ||||||
|  |   .route({ | ||||||
|  |     path: 'app', | ||||||
|  |     key: 'deleteAll', | ||||||
|  |   }) | ||||||
|  |   .define(async (ctx) => { | ||||||
|  |     const keys = await redis.keys('user:app:*'); | ||||||
|  |     for (const key of keys) { | ||||||
|  |       await redis.set(key, '', 'EX', 1); | ||||||
|  |     } | ||||||
|  |     ctx.body = { | ||||||
|  |       keys, | ||||||
|  |     }; | ||||||
|  |   }) | ||||||
|  |   .addTo(app); | ||||||
|  |  | ||||||
|  | app | ||||||
|  |   .route({ | ||||||
|  |     path: 'app', | ||||||
|  |     key: 'deleteAllForce', | ||||||
|  |   }) | ||||||
|  |   .define(async (ctx) => { | ||||||
|  |     const keys = await redis.keys('user:app:*'); | ||||||
|  |     await redis.del(...keys); | ||||||
|  |     fs.rmSync(fileStore, { recursive: true }); | ||||||
|  |  | ||||||
|  |     ctx.body = { | ||||||
|  |       keys, | ||||||
|  |     }; | ||||||
|  |   }); | ||||||
							
								
								
									
										1
									
								
								src/route/route.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								src/route/route.ts
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | |||||||
|  | import './app/index.ts' | ||||||
		Reference in New Issue
	
	Block a user