MCPcopy
hub / github.com/ZToolsCenter/ZTools / startInternalPluginServer

Function startInternalPluginServer

src/main/core/internalPluginServer.ts:34–102  ·  view source on GitHub ↗
()

Source from the content-addressed store, hash-verified

32 * 用于解决 file:// 协议下第三方 iframe CSP 限制问题
33 */
34export async function startInternalPluginServer(): Promise<number> {
35 if (!app.isPackaged) return 0
36
37 const basePath = path.join(process.resourcesPath, 'app.asar.unpacked', 'internal-plugins')
38
39 if (!fs.existsSync(basePath)) {
40 console.warn('[InternalPluginServer] 内置插件目录不存在:', basePath)
41 return 0
42 }
43
44 server = createServer((req, res) => {
45 if (!req.url || req.method !== 'GET') {
46 res.writeHead(405)
47 res.end()
48 return
49 }
50
51 // 解析 URL,去掉 query string
52 const urlPath = decodeURIComponent(req.url.split('?')[0])
53
54 // 映射到文件系统路径
55 const filePath = path.resolve(path.join(basePath, urlPath))
56
57 // 安全检查:防止目录穿越
58 if (!filePath.startsWith(basePath)) {
59 res.writeHead(403)
60 res.end()
61 return
62 }
63
64 // 检查文件是否存在
65 if (!fs.existsSync(filePath) || !fs.statSync(filePath).isFile()) {
66 res.writeHead(404)
67 res.end()
68 return
69 }
70
71 // 确定 MIME 类型
72 const ext = path.extname(filePath).toLowerCase()
73 const contentType = MIME_TYPES[ext] || 'application/octet-stream'
74
75 try {
76 const content = fs.readFileSync(filePath)
77 res.writeHead(200, { 'Content-Type': contentType })
78 res.end(content)
79 } catch {
80 res.writeHead(500)
81 res.end()
82 }
83 })
84
85 return new Promise((resolve, reject) => {
86 server!.listen(0, '127.0.0.1', () => {
87 const addr = server!.address()
88 if (addr && typeof addr === 'object') {
89 serverPort = addr.port
90 console.log(`[InternalPluginServer] 已启动: http://127.0.0.1:${serverPort}`)
91 resolve(serverPort)

Callers 1

index.tsFile · 0.90

Calls 2

resolveMethod · 0.80
onMethod · 0.80

Tested by

no test coverage detected