mirror of
https://github.com/tiennm99/ccs.git
synced 2026-08-15 18:23:12 +00:00
feat(cliproxy): add proxy target resolver for remote/local routing
- add ProxyTarget interface with host, port, protocol, authToken, isRemote - implement getProxyTarget() to resolve target from unified config - add buildProxyUrl() and buildProxyHeaders() utilities - handle optional auth token (empty = no Authorization header)
This commit is contained in:
@@ -0,0 +1,93 @@
|
|||||||
|
/**
|
||||||
|
* Proxy Target Resolver
|
||||||
|
*
|
||||||
|
* Determines whether CLIProxyAPI requests should go to local or remote
|
||||||
|
* based on unified config. Used by stats-fetcher, auth-routes, and UI.
|
||||||
|
*/
|
||||||
|
|
||||||
|
import { loadOrCreateUnifiedConfig } from '../config/unified-config-loader';
|
||||||
|
import type { CliproxyServerConfig } from '../config/unified-config-types';
|
||||||
|
|
||||||
|
/** Default CLIProxyAPI port */
|
||||||
|
const DEFAULT_CLIPROXY_PORT = 8317;
|
||||||
|
|
||||||
|
/** Resolved proxy target for making requests */
|
||||||
|
export interface ProxyTarget {
|
||||||
|
/** Target hostname or IP */
|
||||||
|
host: string;
|
||||||
|
/** Target port */
|
||||||
|
port: number;
|
||||||
|
/** Protocol (http/https) */
|
||||||
|
protocol: 'http' | 'https';
|
||||||
|
/** Optional auth token - only send header if defined and non-empty */
|
||||||
|
authToken?: string;
|
||||||
|
/** True if targeting remote server, false if local */
|
||||||
|
isRemote: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load cliproxy_server configuration from unified config.
|
||||||
|
* Returns undefined if not configured.
|
||||||
|
*/
|
||||||
|
function loadCliproxyServerConfig(): CliproxyServerConfig | undefined {
|
||||||
|
const config = loadOrCreateUnifiedConfig();
|
||||||
|
return config.cliproxy_server;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the current CLIProxyAPI target based on unified config.
|
||||||
|
* Returns remote server config if enabled, otherwise localhost.
|
||||||
|
*/
|
||||||
|
export function getProxyTarget(): ProxyTarget {
|
||||||
|
const config = loadCliproxyServerConfig();
|
||||||
|
|
||||||
|
if (config?.remote?.enabled && config.remote?.host) {
|
||||||
|
return {
|
||||||
|
host: config.remote.host,
|
||||||
|
port: config.remote.port ?? DEFAULT_CLIPROXY_PORT,
|
||||||
|
protocol: config.remote.protocol ?? 'http',
|
||||||
|
authToken: config.remote.auth_token || undefined, // Empty string -> undefined
|
||||||
|
isRemote: true,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return {
|
||||||
|
host: '127.0.0.1',
|
||||||
|
port: config?.local?.port ?? DEFAULT_CLIPROXY_PORT,
|
||||||
|
protocol: 'http',
|
||||||
|
isRemote: false,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build URL for proxy endpoint
|
||||||
|
* @param target Resolved proxy target
|
||||||
|
* @param path Endpoint path (e.g., '/v0/management/usage')
|
||||||
|
*/
|
||||||
|
export function buildProxyUrl(target: ProxyTarget, path: string): string {
|
||||||
|
return `${target.protocol}://${target.host}:${target.port}${path}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Build request headers for proxy requests
|
||||||
|
* Handles optional auth token - only adds Authorization header if token is set.
|
||||||
|
*
|
||||||
|
* @param target Resolved proxy target
|
||||||
|
* @param additionalHeaders Extra headers to merge
|
||||||
|
*/
|
||||||
|
export function buildProxyHeaders(
|
||||||
|
target: ProxyTarget,
|
||||||
|
additionalHeaders: Record<string, string> = {}
|
||||||
|
): Record<string, string> {
|
||||||
|
const headers: Record<string, string> = {
|
||||||
|
Accept: 'application/json',
|
||||||
|
...additionalHeaders,
|
||||||
|
};
|
||||||
|
|
||||||
|
// Only add auth header if token is configured
|
||||||
|
if (target.authToken) {
|
||||||
|
headers['Authorization'] = `Bearer ${target.authToken}`;
|
||||||
|
}
|
||||||
|
|
||||||
|
return headers;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user