fix: 修复多个功能问题并优化服务器配置
- 将Claude提供商的AXIOS超时恢复为2分钟 - 扩展CORS头以支持更多方法和头部,并添加预检缓存 - 禁用自动链接提供商配置 - 增强服务器配置,设置超时和最大连接数 - 为更新检查添加代理支持,使用undici进行代理请求
This commit is contained in:
parent
51992f30dc
commit
e335a13592
4 changed files with 78 additions and 8 deletions
|
|
@ -44,8 +44,9 @@ export function createRequestHandler(config, providerPoolManager) {
|
||||||
|
|
||||||
// Set CORS headers for all requests
|
// Set CORS headers for all requests
|
||||||
res.setHeader('Access-Control-Allow-Origin', '*');
|
res.setHeader('Access-Control-Allow-Origin', '*');
|
||||||
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS');
|
res.setHeader('Access-Control-Allow-Methods', 'GET, POST, PUT, DELETE, OPTIONS, PATCH');
|
||||||
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization, x-goog-api-key, Model-Provider');
|
res.setHeader('Access-Control-Allow-Headers', 'Content-Type, Authorization, x-goog-api-key, Model-Provider, X-Requested-With, Accept, Origin');
|
||||||
|
res.setHeader('Access-Control-Max-Age', '86400'); // 24 hours cache for preflight
|
||||||
|
|
||||||
// Handle CORS preflight requests
|
// Handle CORS preflight requests
|
||||||
if (method === 'OPTIONS') {
|
if (method === 'OPTIONS') {
|
||||||
|
|
|
||||||
|
|
@ -27,7 +27,7 @@ const KIRO_CONSTANTS = {
|
||||||
AMAZON_Q_URL: 'https://codewhisperer.{{region}}.amazonaws.com/SendMessageStreaming',
|
AMAZON_Q_URL: 'https://codewhisperer.{{region}}.amazonaws.com/SendMessageStreaming',
|
||||||
USAGE_LIMITS_URL: 'https://q.{{region}}.amazonaws.com/getUsageLimits',
|
USAGE_LIMITS_URL: 'https://q.{{region}}.amazonaws.com/getUsageLimits',
|
||||||
DEFAULT_MODEL_NAME: 'claude-opus-4-5',
|
DEFAULT_MODEL_NAME: 'claude-opus-4-5',
|
||||||
AXIOS_TIMEOUT: 300000, // 5 minutes timeout (increased from 2 minutes)
|
AXIOS_TIMEOUT: 120000, // 2 minutes timeout (increased from 2 minutes)
|
||||||
USER_AGENT: 'KiroIDE',
|
USER_AGENT: 'KiroIDE',
|
||||||
KIRO_VERSION: '0.7.5',
|
KIRO_VERSION: '0.7.5',
|
||||||
CONTENT_TYPE_JSON: 'application/json',
|
CONTENT_TYPE_JSON: 'application/json',
|
||||||
|
|
|
||||||
|
|
@ -222,8 +222,8 @@ async function startServer() {
|
||||||
await initializeConfig(process.argv.slice(2), 'configs/config.json');
|
await initializeConfig(process.argv.slice(2), 'configs/config.json');
|
||||||
|
|
||||||
// 自动关联 configs 目录中的配置文件到对应的提供商
|
// 自动关联 configs 目录中的配置文件到对应的提供商
|
||||||
console.log('[Initialization] Checking for unlinked provider configs...');
|
// console.log('[Initialization] Checking for unlinked provider configs...');
|
||||||
await autoLinkProviderConfigs(CONFIG);
|
// await autoLinkProviderConfigs(CONFIG);
|
||||||
|
|
||||||
// Initialize plugin system
|
// Initialize plugin system
|
||||||
console.log('[Initialization] Discovering and initializing plugins...');
|
console.log('[Initialization] Discovering and initializing plugins...');
|
||||||
|
|
@ -253,7 +253,15 @@ async function startServer() {
|
||||||
// Create request handler
|
// Create request handler
|
||||||
const requestHandlerInstance = createRequestHandler(CONFIG, getProviderPoolManager());
|
const requestHandlerInstance = createRequestHandler(CONFIG, getProviderPoolManager());
|
||||||
|
|
||||||
serverInstance = http.createServer(requestHandlerInstance);
|
serverInstance = http.createServer({
|
||||||
|
// 设置服务器级别的超时
|
||||||
|
requestTimeout: 0, // 禁用请求超时(流式响应需要)
|
||||||
|
headersTimeout: 60000, // 头部超时 60 秒
|
||||||
|
keepAliveTimeout: 65000 // Keep-alive 超时
|
||||||
|
}, requestHandlerInstance);
|
||||||
|
|
||||||
|
// 设置服务器的最大连接数
|
||||||
|
serverInstance.maxConnections = 1000;
|
||||||
serverInstance.listen(CONFIG.SERVER_PORT, CONFIG.HOST, async () => {
|
serverInstance.listen(CONFIG.SERVER_PORT, CONFIG.HOST, async () => {
|
||||||
console.log(`--- Unified API Server Configuration ---`);
|
console.log(`--- Unified API Server Configuration ---`);
|
||||||
const configuredProviders = Array.isArray(CONFIG.DEFAULT_MODEL_PROVIDERS) && CONFIG.DEFAULT_MODEL_PROVIDERS.length > 0
|
const configuredProviders = Array.isArray(CONFIG.DEFAULT_MODEL_PROVIDERS) && CONFIG.DEFAULT_MODEL_PROVIDERS.length > 0
|
||||||
|
|
|
||||||
|
|
@ -3,9 +3,70 @@ import { promises as fs } from 'fs';
|
||||||
import path from 'path';
|
import path from 'path';
|
||||||
import { exec } from 'child_process';
|
import { exec } from 'child_process';
|
||||||
import { promisify } from 'util';
|
import { promisify } from 'util';
|
||||||
|
import { CONFIG } from '../core/config-manager.js';
|
||||||
|
import { parseProxyUrl } from '../utils/proxy-utils.js';
|
||||||
|
|
||||||
const execAsync = promisify(exec);
|
const execAsync = promisify(exec);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 获取更新检查使用的代理配置
|
||||||
|
* @returns {Object|null} 代理配置对象或 null
|
||||||
|
*/
|
||||||
|
function getUpdateProxyConfig() {
|
||||||
|
if (!CONFIG || !CONFIG.PROXY_URL) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
const proxyConfig = parseProxyUrl(CONFIG.PROXY_URL);
|
||||||
|
if (proxyConfig) {
|
||||||
|
console.log(`[Update] Using ${proxyConfig.proxyType} proxy for update check: ${CONFIG.PROXY_URL}`);
|
||||||
|
}
|
||||||
|
return proxyConfig;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 带代理支持的 fetch 封装
|
||||||
|
* @param {string} url - 请求 URL
|
||||||
|
* @param {Object} options - fetch 选项
|
||||||
|
* @returns {Promise<Response>}
|
||||||
|
*/
|
||||||
|
async function fetchWithProxy(url, options = {}) {
|
||||||
|
const proxyConfig = getUpdateProxyConfig();
|
||||||
|
|
||||||
|
if (proxyConfig) {
|
||||||
|
// 使用 undici 的 fetch 支持代理
|
||||||
|
const fetchOptions = {
|
||||||
|
...options,
|
||||||
|
dispatcher: undefined
|
||||||
|
};
|
||||||
|
|
||||||
|
// 根据 URL 协议选择合适的 agent
|
||||||
|
const urlObj = new URL(url);
|
||||||
|
if (urlObj.protocol === 'https:') {
|
||||||
|
fetchOptions.agent = proxyConfig.httpsAgent;
|
||||||
|
} else {
|
||||||
|
fetchOptions.agent = proxyConfig.httpAgent;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Node.js 原生 fetch 不直接支持 agent,需要使用 undici 或 node-fetch
|
||||||
|
// 这里使用动态导入 undici 来支持代理
|
||||||
|
try {
|
||||||
|
const { fetch: undiciFetch, ProxyAgent } = await import('undici');
|
||||||
|
const proxyAgent = new ProxyAgent(CONFIG.PROXY_URL);
|
||||||
|
return await undiciFetch(url, {
|
||||||
|
...options,
|
||||||
|
dispatcher: proxyAgent
|
||||||
|
});
|
||||||
|
} catch (importError) {
|
||||||
|
// 如果 undici 不可用,回退到原生 fetch(不使用代理)
|
||||||
|
console.warn('[Update] undici not available, falling back to native fetch without proxy');
|
||||||
|
return await fetch(url, options);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return await fetch(url, options);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 比较版本号
|
* 比较版本号
|
||||||
* @param {string} v1 - 版本号1
|
* @param {string} v1 - 版本号1
|
||||||
|
|
@ -43,7 +104,7 @@ async function getLatestVersionFromGitHub() {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
console.log('[Update] Fetching latest version from GitHub API...');
|
console.log('[Update] Fetching latest version from GitHub API...');
|
||||||
const response = await fetch(apiUrl, {
|
const response = await fetchWithProxy(apiUrl, {
|
||||||
headers: {
|
headers: {
|
||||||
'Accept': 'application/vnd.github.v3+json',
|
'Accept': 'application/vnd.github.v3+json',
|
||||||
'User-Agent': 'AIClient2API-UpdateChecker'
|
'User-Agent': 'AIClient2API-UpdateChecker'
|
||||||
|
|
@ -306,7 +367,7 @@ async function performTarballUpdate(localVersion, latestTag) {
|
||||||
|
|
||||||
// 2. 下载 tarball
|
// 2. 下载 tarball
|
||||||
console.log('[Update] Downloading tarball...');
|
console.log('[Update] Downloading tarball...');
|
||||||
const response = await fetch(tarballUrl, {
|
const response = await fetchWithProxy(tarballUrl, {
|
||||||
headers: {
|
headers: {
|
||||||
'User-Agent': 'AIClient2API-Updater'
|
'User-Agent': 'AIClient2API-Updater'
|
||||||
},
|
},
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue