mirror of
https://github.com/tiennm99/ccs.git
synced 2026-10-14 20:17:03 +00:00
fix(cliproxy): harden custom local port handling
This commit is contained in:
1 parent
a7c10be72e
commit
3862411bb7
6 files changed
+155
-8
No files matched your search
@@ -10,6 +10,7 @@ import {
|
||||
CLIPROXY_DEFAULT_PORT,
|
||||
getRemoteDefaultPort,
|
||||
normalizeProtocol,
|
||||
validatePort,
|
||||
validateRemotePort,
|
||||
} from '../config/port-manager';
|
||||
import { getProxyEnvVars } from './proxy-config-resolver';
|
||||
@@ -69,7 +70,7 @@ export function getProxyTarget(): ProxyTarget {
|
||||
};
|
||||
}
|
||||
|
||||
const localPort = config?.local?.port ?? CLIPROXY_DEFAULT_PORT;
|
||||
const localPort = validatePort(config?.local?.port ?? CLIPROXY_DEFAULT_PORT);
|
||||
|
||||
return {
|
||||
host: '127.0.0.1',
|
||||
|
||||
@@ -3,7 +3,7 @@ import { spawn } from 'child_process';
|
||||
import type { CursorConfig } from '../config/unified-config-types';
|
||||
|
||||
import { ensureCliproxyService } from '../cliproxy';
|
||||
import { CLIPROXY_DEFAULT_PORT } from '../cliproxy/config/port-manager';
|
||||
import { resolveLifecyclePort } from '../cliproxy/config/port-manager';
|
||||
import { fail, info, ok } from '../utils/ui';
|
||||
import {
|
||||
appendThirdPartyWebSearchToolArgs,
|
||||
@@ -22,6 +22,13 @@ interface CursorImageAnalysisResolution {
|
||||
warning: string | null;
|
||||
}
|
||||
|
||||
interface CursorImageAnalysisDeps {
|
||||
getImageAnalysisHookEnv?: typeof getImageAnalysisHookEnv;
|
||||
resolveImageAnalysisRuntimeStatus?: typeof resolveImageAnalysisRuntimeStatus;
|
||||
ensureCliproxyService?: typeof ensureCliproxyService;
|
||||
resolveLifecyclePort?: typeof resolveLifecyclePort;
|
||||
}
|
||||
|
||||
export function generateCursorEnv(
|
||||
config: CursorConfig,
|
||||
claudeConfigDir?: string
|
||||
@@ -45,9 +52,16 @@ export function generateCursorEnv(
|
||||
}
|
||||
|
||||
export async function resolveCursorImageAnalysisEnv(
|
||||
verbose = false
|
||||
verbose = false,
|
||||
deps: CursorImageAnalysisDeps = {}
|
||||
): Promise<CursorImageAnalysisResolution> {
|
||||
const env = getImageAnalysisHookEnv({
|
||||
const getImageAnalysisHookEnvFn = deps.getImageAnalysisHookEnv ?? getImageAnalysisHookEnv;
|
||||
const resolveImageAnalysisRuntimeStatusFn =
|
||||
deps.resolveImageAnalysisRuntimeStatus ?? resolveImageAnalysisRuntimeStatus;
|
||||
const ensureCliproxyServiceFn = deps.ensureCliproxyService ?? ensureCliproxyService;
|
||||
const resolveLifecyclePortFn = deps.resolveLifecyclePort ?? resolveLifecyclePort;
|
||||
|
||||
const env = getImageAnalysisHookEnvFn({
|
||||
profileName: 'cursor',
|
||||
profileType: 'cursor',
|
||||
});
|
||||
@@ -56,7 +70,7 @@ export async function resolveCursorImageAnalysisEnv(
|
||||
return { env, warning: null };
|
||||
}
|
||||
|
||||
const status = await resolveImageAnalysisRuntimeStatus({
|
||||
const status = await resolveImageAnalysisRuntimeStatusFn({
|
||||
profileName: 'cursor',
|
||||
profileType: 'cursor',
|
||||
});
|
||||
@@ -73,7 +87,7 @@ export async function resolveCursorImageAnalysisEnv(
|
||||
}
|
||||
|
||||
if (status.proxyReadiness === 'stopped') {
|
||||
const ensureServiceResult = await ensureCliproxyService(CLIPROXY_DEFAULT_PORT, verbose);
|
||||
const ensureServiceResult = await ensureCliproxyServiceFn(resolveLifecyclePortFn(), verbose);
|
||||
if (!ensureServiceResult.started) {
|
||||
return {
|
||||
env: {
|
||||
|
||||
@@ -43,7 +43,7 @@ import {
|
||||
} from '../utils/hooks/image-analyzer-profile-hook-injector';
|
||||
import { resolveCliproxyBridgeMetadata } from '../api/services';
|
||||
import { ensureCliproxyService } from '../cliproxy';
|
||||
import { CLIPROXY_DEFAULT_PORT } from '../cliproxy/config/port-manager';
|
||||
import { resolveLifecyclePort } from '../cliproxy/config/port-manager';
|
||||
import {
|
||||
buildOpenAICompatProxyEnv,
|
||||
resolveOpenAICompatProfileConfig,
|
||||
@@ -212,7 +212,7 @@ export class HeadlessExecutor {
|
||||
imageAnalysisProvider &&
|
||||
imageAnalysisStatus.proxyReadiness === 'stopped'
|
||||
) {
|
||||
const ensureServiceResult = await ensureCliproxyService(CLIPROXY_DEFAULT_PORT, false);
|
||||
const ensureServiceResult = await ensureCliproxyService(resolveLifecyclePort(), false);
|
||||
if (!ensureServiceResult.started) {
|
||||
console.error(
|
||||
warn(
|
||||
|
||||
@@ -12,6 +12,7 @@ import { Router, Request, Response } from 'express';
|
||||
import { testConnection } from '../../cliproxy/services/remote-proxy-client';
|
||||
import { isProxyRunning } from '../../cliproxy/services/proxy-lifecycle-service';
|
||||
import { DEFAULT_BACKEND } from '../../cliproxy/binary/platform-detector';
|
||||
import { validatePort } from '../../cliproxy/config/port-manager';
|
||||
import {
|
||||
DEFAULT_CLIPROXY_SERVER_CONFIG,
|
||||
CliproxyServerConfig,
|
||||
@@ -58,6 +59,36 @@ router.get('/', async (_req: Request, res: Response) => {
|
||||
router.put('/', (req: Request, res: Response) => {
|
||||
try {
|
||||
const updates = req.body as Partial<CliproxyServerConfig>;
|
||||
const currentConfig = loadOrCreateUnifiedConfig();
|
||||
const currentLocalPort = validatePort(
|
||||
currentConfig.cliproxy_server?.local?.port ?? DEFAULT_CLIPROXY_SERVER_CONFIG.local.port
|
||||
);
|
||||
const requestedLocalPort = updates.local?.port;
|
||||
|
||||
if (
|
||||
requestedLocalPort !== undefined &&
|
||||
(!Number.isInteger(requestedLocalPort) ||
|
||||
requestedLocalPort < 1 ||
|
||||
requestedLocalPort > 65535)
|
||||
) {
|
||||
res.status(400).json({
|
||||
error: 'Invalid local port. Must be an integer between 1 and 65535.',
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
const nextLocalPort =
|
||||
requestedLocalPort === undefined ? currentLocalPort : validatePort(requestedLocalPort);
|
||||
|
||||
if (nextLocalPort !== currentLocalPort && isProxyRunning()) {
|
||||
res.status(409).json({
|
||||
error:
|
||||
'Proxy is running on the current local port. Stop CLIProxy before changing local.port.',
|
||||
proxyRunning: true,
|
||||
currentLocalPort,
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// Atomic read-modify-write — avoids race between load and save
|
||||
const updated = mutateConfig((config) => {
|
||||
|
||||
Reference in new issue
Block a user