Spaces:
Running
Running
const express = require('express'); | |
const morgan = require('morgan'); | |
const { createProxyMiddleware } = require('http-proxy-middleware'); | |
const url = require('url'); | |
const app = express(); | |
app.use(morgan('dev')); | |
// 从环境变量获取代理配置 | |
const proxyUrl = process.env.PROXY || ''; | |
console.log(`Proxy configuration: ${proxyUrl ? '已配置' : '未配置'}`); | |
// 解析代理URL | |
let proxyConfig = null; | |
if (proxyUrl) { | |
try { | |
const parsedUrl = url.parse(proxyUrl); | |
proxyConfig = { | |
host: parsedUrl.hostname, | |
port: parsedUrl.port || 80, | |
auth: parsedUrl.auth ? { | |
username: parsedUrl.auth.split(':')[0], | |
password: parsedUrl.auth.split(':')[1] | |
} : undefined | |
}; | |
// 打印代理配置(安全处理密码) | |
const maskedConfig = { | |
...proxyConfig, | |
auth: proxyConfig.auth ? { | |
username: proxyConfig.auth.username, | |
password: '******' | |
} : undefined | |
}; | |
console.log('Using proxy:', JSON.stringify(maskedConfig)); | |
} catch (error) { | |
console.error('Failed to parse proxy URL:', error.message); | |
} | |
} | |
// 配置代理中间件 | |
app.use('/hf/v1/chat/completions', createProxyMiddleware({ | |
target: 'http://localhost:3010/v1/chat/completions', | |
changeOrigin: true, | |
// 添加代理配置 | |
proxy: proxyConfig, | |
// 增加错误处理 | |
onError: (err, req, res) => { | |
console.error('Proxy error:', err); | |
res.status(500).send('Proxy error occurred: ' + err.message); | |
}, | |
onProxyReq: (proxyReq, req, res) => { | |
console.log(`Proxying request to chat completions ${proxyConfig ? 'using proxy' : 'directly'}`); | |
}, | |
onProxyRes: (proxyRes, req, res) => { | |
console.log(`Received response with status: ${proxyRes.statusCode}`); | |
} | |
})); | |
app.get('/', (req, res) => { | |
const htmlContent = ` | |
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8"> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | |
<title>Cursor To OpenAI</title> | |
<style> | |
body { | |
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif; | |
max-width: 800px; | |
margin: 0 auto; | |
padding: 20px; | |
line-height: 1.6; | |
} | |
.container { | |
background: #f9f9f9; | |
border-radius: 10px; | |
padding: 20px; | |
box-shadow: 0 2px 10px rgba(0,0,0,0.1); | |
} | |
.info-item { | |
margin-bottom: 10px; | |
} | |
.status { | |
background: ${proxyConfig ? '#e1f5e1' : '#fff3cd'}; | |
padding: 10px; | |
border-radius: 5px; | |
margin-top: 20px; | |
border: 1px solid ${proxyConfig ? '#c3e6cb' : '#ffeeba'}; | |
} | |
</style> | |
</head> | |
<body> | |
<div class="container"> | |
<h1>Cursor To OpenAI Server</h1> | |
<div class="info-item"> | |
<strong>聊天来源:</strong> 自定义(兼容 OpenAI) | |
</div> | |
<div class="info-item"> | |
<strong>自定义端点(基本URL):</strong><span id="endpoint-url"></span> | |
</div> | |
<div class="info-item"> | |
<strong>自定义API密钥:</strong>[抓取的Cursor Cookie,格式为user_...] | |
</div> | |
<div class="status"> | |
<strong>代理状态:</strong> ${proxyConfig ? '已启用' : '未启用'} | |
${proxyConfig ? `<p>代理服务器: ${proxyConfig.host}:${proxyConfig.port}</p>` : ''} | |
</div> | |
</div> | |
<script> | |
const url = new URL(window.location.href); | |
const link = url.protocol + '//' + url.host + '/hf/v1'; | |
document.getElementById('endpoint-url').textContent = link; | |
</script> | |
</body> | |
</html> | |
`; | |
res.send(htmlContent); | |
}); | |
const port = process.env.HF_PORT || 7860; | |
app.listen(port, () => { | |
console.log(`HF Proxy server is running at PORT: ${port}`); | |
console.log(`Proxy status: ${proxyConfig ? 'Enabled' : 'Disabled'}`); | |
}); | |