From 569446b99a188de6d34a7ababf07b79b75f9a552 Mon Sep 17 00:00:00 2001 From: xion Date: Thu, 29 May 2025 13:47:44 +0800 Subject: [PATCH] temp: add content-type --- .env.example | 21 +++++++++++++++++-- package.json | 7 +++---- src/module/config.ts | 3 ++- src/module/get-content-type.ts | 38 +++++++++++++++++++++++++++++++--- src/module/get-user-app.ts | 2 +- src/module/index.ts | 5 ++++- src/module/proxy/http-proxy.ts | 6 +++++- 7 files changed, 69 insertions(+), 13 deletions(-) diff --git a/.env.example b/.env.example index 23a1c62..8c977e6 100644 --- a/.env.example +++ b/.env.example @@ -1,12 +1,13 @@ # 代理配置 PROXY_PORT=3005 PROXY_DOMAIN=localhost -PROXY_RESOURCES=http://localhost:9000/resources -PROXY_ALLOWED_ORIGINS=localhost,xiongxiao.me,zxj.im +PROXY_ALLOWED_ORIGINS=localhost,xiongxiao.me # 后台代理 API_HOST=http://localhost:4005 API_PATH=/api/router +# API assistant 客户端地址 +API_CLIENT_HOST=https://localhost:51015 # Minio 配置 MINIO_ENDPOINT=localhost @@ -15,3 +16,19 @@ MINIO_BUCKET_NAME=resources MINIO_USE_SSL=false MINIO_ACCESS_KEY=username MINIO_SECRET_KEY=**** + + +# 本地postgres +POSTGRES_HOST=localhost +POSTGRES_PORT=5432 +POSTGRES_USER=root +POSTGRES_PASSWORD=needchange +POSTGRES_DB=postgres + +## Redis +REDIS_HOST=localhost +REDIS_PORT=6379 +REDIS_PASSWORD=needchange + + +DATA_WEBSITE_ID= \ No newline at end of file diff --git a/package.json b/package.json index e91dba4..fa5775c 100644 --- a/package.json +++ b/package.json @@ -12,14 +12,13 @@ "runtime": [ "client", "server" - ], - "files": [ - "dist" ] }, "files": [ - "dist" + "dist", + ".env.example" ], + "home": "", "scripts": { "dev": "bun run --watch --hot --inspect src/index.ts", "cmd": "bun run src/run.ts ", diff --git a/src/module/config.ts b/src/module/config.ts index 9d2ae8b..2eccb54 100644 --- a/src/module/config.ts +++ b/src/module/config.ts @@ -1,5 +1,6 @@ import { useConfig } from '@kevisual/use-config/env'; import { useFileStore } from '@kevisual/use-config/file-store'; +import { minioResources } from './minio.ts'; export const fileStore = useFileStore('pages'); type ConfigType = { @@ -73,7 +74,7 @@ export const config: ConfigType = { proxy: { port: envConfig.PROXY_PORT, domain: envConfig.PROXY_DOMAIN, - resources: envConfig.PROXY_RESOURCES, + resources: minioResources, allowedOrigin: (envConfig.PROXY_ALLOWED_ORIGINS as string)?.split(',') || [], }, redis: { diff --git a/src/module/get-content-type.ts b/src/module/get-content-type.ts index 7dad65c..9107db4 100644 --- a/src/module/get-content-type.ts +++ b/src/module/get-content-type.ts @@ -1,7 +1,30 @@ import path from 'path'; +export const getTextContentType = (ext: string) => { + const textContentTypes = [ + '.tsx', + '.jsx', // + '.conf', + '.env', + '.example', + '.log', + '.mjs', + '.map', + '.json5', + ]; + const include = textContentTypes.includes(ext); + if (!include) { + return {}; + } + const contentType = getContentTypeCore(ext); + if (!contentType) { + return {}; + } + return { + 'Content-Type': contentType, + }; +}; // 获取文件的 content-type -export const getContentType = (filePath: string) => { - const extname = path.extname(filePath); +export const getContentTypeCore = (extname: string) => { const contentType = { '.html': 'text/html; charset=utf-8', '.js': 'text/javascript; charset=utf-8', @@ -11,9 +34,12 @@ export const getContentType = (filePath: string) => { '.ts': 'text/typescript; charset=utf-8', '.jsx': 'text/javascript; charset=utf-8', '.conf': 'text/plain; charset=utf-8', + '.env': 'text/plain; charset=utf-8', + '.example': 'text/plain; charset=utf-8', '.log': 'text/plain; charset=utf-8', '.mjs': 'text/javascript; charset=utf-8', '.map': 'application/json; charset=utf-8', + '.json5': 'application/json5; charset=utf-8', '.json': 'application/json; charset=utf-8', '.png': 'image/png', @@ -52,5 +78,11 @@ export const getContentType = (filePath: string) => { '.yml': 'application/x-yaml; charset=utf-8', // YAML 文件(别名) '.zip': 'application/octet-stream', }; - return contentType[extname] || 'application/octet-stream'; + return contentType[extname]; +}; + +export const getContentType = (filePath: string) => { + const extname = path.extname(filePath).toLowerCase(); + const contentType = getContentTypeCore(extname); + return contentType || 'application/octet-stream'; }; diff --git a/src/module/get-user-app.ts b/src/module/get-user-app.ts index 9049396..ef7c58d 100644 --- a/src/module/get-user-app.ts +++ b/src/module/get-user-app.ts @@ -14,7 +14,7 @@ import { logger } from './logger.ts'; const pipelineAsync = promisify(pipeline); -const { resources } = config?.proxy || { resources: 'https://minio.xiongxiao.me/resources' }; +const { resources } = config?.proxy || { resources: minioResources }; const wrapperResources = (resources: string, urlpath: string) => { if (urlpath.startsWith('http')) { return urlpath; diff --git a/src/module/index.ts b/src/module/index.ts index c1604e8..35a086b 100644 --- a/src/module/index.ts +++ b/src/module/index.ts @@ -284,7 +284,10 @@ export const handleRequest = async (req: http.IncomingMessage, res: http.ServerR appFileUrl = (url + '').replace(`/${user}/${app}/`, ''); } appFileUrl = decodeURIComponent(appFileUrl); // Decode URL components - const appFile = await userApp.getFile(appFileUrl); + let appFile = await userApp.getFile(appFileUrl); + if (!appFile && url.endsWith('/')) { + appFile = await userApp.getFile(appFileUrl + 'index.html'); + } if (isExist.proxy) { let proxyUrl = appFile || isExist.indexFilePath; if (!proxyUrl.startsWith('http')) { diff --git a/src/module/proxy/http-proxy.ts b/src/module/proxy/http-proxy.ts index 3476bba..86a1d1f 100644 --- a/src/module/proxy/http-proxy.ts +++ b/src/module/proxy/http-proxy.ts @@ -7,6 +7,9 @@ import http from 'http'; import https from 'https'; import { UserApp } from '../get-user-app.ts'; import { addStat } from '../html/stat/index.ts'; +import path from 'path'; +import { getTextContentType } from '../get-content-type.ts'; +import { logger } from '../logger.ts'; const pipelineAsync = promisify(pipeline); @@ -50,7 +53,7 @@ export async function minioProxy( const etag = stat.etag; const lastModified = stat.lastModified.toISOString(); const fileName = objectName.split('/').pop(); - + const ext = path.extname(fileName || ''); const objectStream = await minioClient.getObject(bucketName, objectName); const headers = { 'Content-Length': contentLength, @@ -58,6 +61,7 @@ export async function minioProxy( 'last-modified': lastModified, 'file-name': fileName, ...filterMetaData, + ...getTextContentType(ext), }; if (objectName.endsWith('.html') && !isDownload) { const { html, contentLength } = await getTextFromStreamAndAddStat(objectStream);