| import express from 'express'; |
| import { loadConfig, isDevMode, getPort } from './config.js'; |
| import { logInfo, logError } from './logger.js'; |
| import router from './routes.js'; |
| import { initializeAuth } from './auth.js'; |
|
|
| const app = express(); |
|
|
| app.use(express.json({ limit: '50mb' })); |
| app.use(express.urlencoded({ extended: true, limit: '50mb' })); |
|
|
| app.use((req, res, next) => { |
| res.header('Access-Control-Allow-Origin', '*'); |
| res.header('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS'); |
| res.header('Access-Control-Allow-Headers', 'Content-Type, Authorization, X-API-Key, anthropic-version'); |
| |
| if (req.method === 'OPTIONS') { |
| return res.sendStatus(200); |
| } |
| next(); |
| }); |
|
|
| app.use(router); |
|
|
| app.get('/', (req, res) => { |
| res.json({ |
| name: 'droid2api', |
| version: '1.0.0', |
| description: 'OpenAI Compatible API Proxy', |
| endpoints: [ |
| 'GET /v1/models', |
| 'POST /v1/chat/completions', |
| 'POST /v1/responses', |
| 'POST /v1/messages' |
| ] |
| }); |
| }); |
|
|
| |
| app.use((req, res, next) => { |
| const errorInfo = { |
| timestamp: new Date().toISOString(), |
| method: req.method, |
| url: req.originalUrl || req.url, |
| path: req.path, |
| query: req.query, |
| params: req.params, |
| body: req.body, |
| headers: { |
| 'content-type': req.headers['content-type'], |
| 'user-agent': req.headers['user-agent'], |
| 'origin': req.headers['origin'], |
| 'referer': req.headers['referer'] |
| }, |
| ip: req.ip || req.connection.remoteAddress |
| }; |
|
|
| console.error('\n' + '='.repeat(80)); |
| console.error('❌ 非法请求地址'); |
| console.error('='.repeat(80)); |
| console.error(`时间: ${errorInfo.timestamp}`); |
| console.error(`方法: ${errorInfo.method}`); |
| console.error(`地址: ${errorInfo.url}`); |
| console.error(`路径: ${errorInfo.path}`); |
| |
| if (Object.keys(errorInfo.query).length > 0) { |
| console.error(`查询参数: ${JSON.stringify(errorInfo.query, null, 2)}`); |
| } |
| |
| if (errorInfo.body && Object.keys(errorInfo.body).length > 0) { |
| console.error(`请求体: ${JSON.stringify(errorInfo.body, null, 2)}`); |
| } |
| |
| console.error(`客户端IP: ${errorInfo.ip}`); |
| console.error(`User-Agent: ${errorInfo.headers['user-agent'] || 'N/A'}`); |
| |
| if (errorInfo.headers.referer) { |
| console.error(`来源: ${errorInfo.headers.referer}`); |
| } |
| |
| console.error('='.repeat(80) + '\n'); |
|
|
| logError('Invalid request path', errorInfo); |
|
|
| res.status(404).json({ |
| error: 'Not Found', |
| message: `路径 ${req.method} ${req.path} 不存在`, |
| timestamp: errorInfo.timestamp, |
| availableEndpoints: [ |
| 'GET /v1/models', |
| 'POST /v1/chat/completions', |
| 'POST /v1/responses', |
| 'POST /v1/messages' |
| ] |
| }); |
| }); |
|
|
| |
| app.use((err, req, res, next) => { |
| logError('Unhandled error', err); |
| res.status(500).json({ |
| error: 'Internal server error', |
| message: isDevMode() ? err.message : undefined |
| }); |
| }); |
|
|
| (async () => { |
| try { |
| loadConfig(); |
| logInfo('Configuration loaded successfully'); |
| logInfo(`Dev mode: ${isDevMode()}`); |
| |
| |
| |
| await initializeAuth(); |
| |
| const PORT = getPort(); |
| logInfo(`Starting server on port ${PORT}...`); |
| |
| const server = app.listen(PORT) |
| .on('listening', () => { |
| logInfo(`Server running on http://localhost:${PORT}`); |
| logInfo('Available endpoints:'); |
| logInfo(' GET /v1/models'); |
| logInfo(' POST /v1/chat/completions'); |
| logInfo(' POST /v1/responses'); |
| logInfo(' POST /v1/messages'); |
| }) |
| .on('error', (err) => { |
| if (err.code === 'EADDRINUSE') { |
| console.error(`\n${'='.repeat(80)}`); |
| console.error(`ERROR: Port ${PORT} is already in use!`); |
| console.error(''); |
| console.error('Please choose one of the following options:'); |
| console.error(` 1. Stop the process using port ${PORT}:`); |
| console.error(` lsof -ti:${PORT} | xargs kill`); |
| console.error(''); |
| console.error(' 2. Change the port in config.json:'); |
| console.error(' Edit config.json and modify the "port" field'); |
| console.error(`${'='.repeat(80)}\n`); |
| process.exit(1); |
| } else { |
| logError('Failed to start server', err); |
| process.exit(1); |
| } |
| }); |
| } catch (error) { |
| logError('Failed to start server', error); |
| process.exit(1); |
| } |
| })(); |
|
|