模块路径:
src/proxy/生成时间: 2026-05-11
src/proxy/
├── index.ts # 主入口:initializeProxies, proxyMap, defaultProxy
└── director.ts # 请求改写:createDirector, 认证注入
import { createProxyMiddleware } from 'http-proxy-middleware';
function createBackendProxy(backend: BackendConfig, apiKey: string | null): RequestHandler {
return createProxyMiddleware({
target: backend.base_url,
changeOrigin: true,
selfHandleResponse: false, // SSE 流式直通
on: {
proxyReq: createDirector(backend, apiKey),
proxyRes: handleProxyResponse,
},
onError: handleProxyError,
});
}
后端认证注入 (onProxyReq):
│
├── require_api_key = true?
│ ├── api_key 有值?
│ │ ├── 是 `${env:VAR_NAME}` 语法? → process.env[VAR_NAME] → 设置 Authorization: Bearer <key>
│ │ └── 是直接值? → 直接设置 Authorization: Bearer <key>
│ ├── api_key 为空且后端名含 "openai"? → 回退 OPENAI_API_KEY
│ └── 无法获取密钥? → 不设置认证头
│
└── require_api_key = false?
└── 移除 Authorization 头
interface ProxyInstances {
proxyMap: Map<string, RequestHandler>; // prefix → proxy
defaultProxy: RequestHandler | null;
}
function initializeProxies(config: Config, logger: Logger): ProxyInstances {
const proxyMap = new Map<string, RequestHandler>();
let defaultProxy: RequestHandler | null = null;
for (const backend of config.backends) {
const apiKey = resolveBackendApiKey(backend);
const proxy = createBackendProxy(backend, apiKey);
proxyMap.set(backend.prefix, proxy);
if (backend.default) defaultProxy = proxy;
}
return { proxyMap, defaultProxy };
}
function handleProxyError(err: Error, req: Request, res: Response) {
logger.error(`Proxy error: ${err.message}`, { method: req.method, url: req.url });
if (!res.headersSent) {
res.status(502).json({
error: { message: 'Backend service unavailable', type: 'server_error', code: 'backend_unreachable' }
});
}
}
| 方向 | 说明 | 优先级 |
|---|---|---|
| 连接池配置 | 超时、keep-alive、最大连接数 | P2 |
| 后端健康检查 | 定期检查后端可用性 | P3 |
| 响应录制 | 非流式响应录制用于日志 | P2 |