const express = require('express'); const morgan = require('morgan'); const { createProxyMiddleware } = require('http-proxy-middleware'); const axios = require('axios'); const fs = require('fs'); const url = require('url'); const app = express(); app.use(morgan('dev')); // 全局代理池 let proxyPool = process.env.PROXY ? process.env.PROXY.split(',').map(p => p.trim()) : []; console.log('Initial proxy pool:', proxyPool); // 从代理池中随机选择一个代理 function getRandomProxy() { if (proxyPool.length === 0) return null; const randomIndex = Math.floor(Math.random() * proxyPool.length); const proxyUrl = proxyPool[randomIndex]; const parsedUrl = url.parse(proxyUrl); return { host: parsedUrl.hostname, port: parsedUrl.port || 80, auth: parsedUrl.auth ? { username: parsedUrl.auth.split(':')[0], password: parsedUrl.auth.split(':')[1] } : undefined }; } // 配置 axios 的代理 function configureAxiosProxy() { const proxy = getRandomProxy(); if (proxy) { axios.defaults.proxy = proxy; console.log(`Axios using proxy: ${proxy.host}:${proxy.port}`); } else { delete axios.defaults.proxy; console.log('No proxy available for axios'); } } // 从外部 API 更新代理池 async function updateProxyPool() { const proxyApiUrl = process.env.PROXY_API_URL || 'http://example.com/api/proxies'; try { const response = await axios.get(proxyApiUrl); // 假设 API 返回格式为 { proxies: ["http://user:pass@host:port", ...] } const newProxies = response.data.proxies || []; if (newProxies.length > 0) { proxyPool = newProxies; console.log('Proxy pool updated:', proxyPool); configureAxiosProxy(); // 更新 axios 代理 } else { console.warn('No proxies received from API'); } } catch (error) { console.error('Failed to update proxy pool:', error.message); } } // 定期更新代理池 const updateInterval = parseInt(process.env.PROXY_UPDATE_INTERVAL) || 300; // 默认 5 分钟 if (updateInterval > 0) { setInterval(updateProxyPool, updateInterval * 1000); console.log(`Proxy pool will update every ${updateInterval} seconds`); // 启动时立即更新一次 updateProxyPool(); } // 模型列表 API app.get('/hf/v1/models', (req, res) => { const models = { "object": "list", "data": [ { "id": "claude-3.5-sonnet", "object": "model", "created": 1706745938, "owned_by": "cursor" }, { "id": "gpt-4", "object": "model", "created": 1706745938, "owned_by": "cursor" }, { "id": "gpt-4o", "object": "model", "created": 1706745938, "owned_by": "cursor" }, { "id": "claude-3-opus", "object": "model", "created": 1706745938, "owned_by": "cursor" }, { "id": "gpt-3.5-turbo", "object": "model", "created": 1706745938, "owned_by": "cursor" }, { "id": "gpt-4-turbo-2024-04-09", "object": "model", "created": 1706745938, "owned_by": "cursor" }, { "id": "gpt-4o-128k", "object": "model", "created": 1706745938, "owned_by": "cursor" }, { "id": "gemini-1.5-flash-500k", "object": "model", "created": 1706745938, "owned_by": "cursor" }, { "id": "claude-3-haiku-200k", "object": "model", "created": 1706745938, "owned_by": "cursor" }, { "id": "claude-3-5-sonnet-200k", "object": "model", "created": 1706745938, "owned_by": "cursor" }, { "id": "claude-3-5-sonnet-20241022", "object": "model", "created": 1706745938, "owned_by": "cursor" }, { "id": "gpt-4o-mini", "object": "model", "created": 1706745938, "owned_by": "cursor" }, { "id": "o1-mini", "object": "model", "created": 1706745938, "owned_by": "cursor" }, { "id": "o1-preview", "object": "model", "created": 1706745938, "owned_by": "cursor" }, { "id": "o1", "object": "model", "created": 1706745938, "owned_by": "cursor" }, { "id": "claude-3.5-haiku", "object": "model", "created": 1706745938, "owned_by": "cursor" }, { "id": "gemini-exp-1206", "object": "model", "created": 1706745938, "owned_by": "cursor" }, { "id": "gemini-2.0-flash-thinking-exp", "object": "model", "created": 1706745938, "owned_by": "cursor" }, { "id": "gemini-2.0-flash-exp", "object": "model", "created": 1706745938, "owned_by": "cursor" }, { "id": "deepseek-v3", "object": "model", "created": 1706745938, "owned_by": "cursor" }, { "id": "deepseek-r1", "object": "model", "created": 1706745938, "owned_by": "cursor" } ] }; res.json(models); }); // 代理转发,使用动态代理池 app.use('/hf/v1/chat/completions', (req, res, next) => { const proxy = getRandomProxy(); const middleware = createProxyMiddleware({ target: 'http://localhost:3010/v1/chat/completions', // 可替换为实际目标服务 changeOrigin: true, proxy: proxy ? proxy : undefined, timeout: 30000, // 超时 30 秒 proxyTimeout: 30000, // 代理超时 30 秒 onProxyReq: (proxyReq, req, res) => { if (req.body) { const bodyData = JSON.stringify(req.body); proxyReq.setHeader('Content-Type', 'application/json'); proxyReq.setHeader('Content-Length', Buffer.byteLength(bodyData)); proxyReq.write(bodyData); proxyReq.end(); } }, onError: (err, req, res) => { console.error('Proxy error:', err); res.status(500).send('Proxy error occurred'); } }); if (proxy) { console.log(`Request proxied via ${proxy.host}:${proxy.port}`); } else { console.log('No proxy available, direct connection'); } middleware(req, res, next); }); // 首页 app.get('/', (req, res) => { const htmlContent = ` Cursor To OpenAI

Cursor To OpenAI Server

高性能 AI 模型代理服务

配置信息

聊天来源
自定义(兼容 OpenAI)
自定义端点(基本URL)
自定义API密钥
抓取的Cursor Cookie,格式为user_...

支持的模型列表

`; res.send(htmlContent); }); // 启动服务前配置初始 axios 代理 configureAxiosProxy(); const port = process.env.HF_PORT || 7860; app.listen(port, () => { console.log(`HF Proxy server is running at PORT: ${port}`); });