| import express from 'express';
|
| import { loadConfig, isDevMode, getPort } from './config.js';
|
| import { logInfo, logError } from './logger.js';
|
| import router from './routes.js'; |
| import { initializeAuth, accessKeyMiddleware } 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('/v1', accessKeyMiddleware); |
|
|
| 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);
|
| }
|
| })();
|
|
|