mirror of
https://github.com/tiennm99/ccs.git
synced 2026-07-16 04:18:05 +00:00
fix(cliproxy): clear stale cleanup timer and fix session/tunnel edge cases
- Stop cleanup interval when all auth sessions are removed (unregister, cancel, cancelAll) so the Node event loop isn't held alive. - getActiveSessionForProvider now returns the most recent session by startedAt instead of the first map entry. - HTTPS tunnel includes port in Host header when non-443.
This commit is contained in:
@@ -39,14 +39,18 @@ function startCleanupInterval(): void {
|
||||
authSessionEvents.emit('session:expired', sessionId);
|
||||
}
|
||||
}
|
||||
// Stop interval if no active sessions
|
||||
if (activeSessions.size === 0 && cleanupInterval) {
|
||||
clearInterval(cleanupInterval);
|
||||
cleanupInterval = null;
|
||||
}
|
||||
stopCleanupIfEmpty();
|
||||
}, 60000); // Check every minute
|
||||
}
|
||||
|
||||
/** Clear the cleanup interval when no sessions remain. */
|
||||
function stopCleanupIfEmpty(): void {
|
||||
if (activeSessions.size === 0 && cleanupInterval) {
|
||||
clearInterval(cleanupInterval);
|
||||
cleanupInterval = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register an active OAuth session
|
||||
*/
|
||||
@@ -82,6 +86,7 @@ export function attachProcessToSession(sessionId: string, process: ChildProcess)
|
||||
export function unregisterAuthSession(sessionId: string): void {
|
||||
activeSessions.delete(sessionId);
|
||||
authSessionEvents.emit('session:ended', sessionId);
|
||||
stopCleanupIfEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -101,6 +106,7 @@ export function cancelAuthSession(sessionId: string): boolean {
|
||||
|
||||
activeSessions.delete(sessionId);
|
||||
authSessionEvents.emit('session:cancelled', sessionId);
|
||||
stopCleanupIfEmpty();
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -112,15 +118,16 @@ export function getActiveSession(sessionId: string): ActiveAuthSession | null {
|
||||
}
|
||||
|
||||
/**
|
||||
* Get active session for a provider (most recent)
|
||||
* Get active session for a provider (most recent by startedAt)
|
||||
*/
|
||||
export function getActiveSessionForProvider(provider: string): ActiveAuthSession | null {
|
||||
let latest: ActiveAuthSession | null = null;
|
||||
for (const session of activeSessions.values()) {
|
||||
if (session.provider === provider) {
|
||||
return session;
|
||||
if (session.provider === provider && (!latest || session.startedAt > latest.startedAt)) {
|
||||
latest = session;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return latest;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -145,5 +152,6 @@ export function cancelAllSessionsForProvider(provider: string): number {
|
||||
count++;
|
||||
}
|
||||
}
|
||||
stopCleanupIfEmpty();
|
||||
return count;
|
||||
}
|
||||
|
||||
@@ -162,8 +162,12 @@ export class HttpsTunnelProxy {
|
||||
headers[key] = value;
|
||||
}
|
||||
|
||||
// Set correct host header for remote
|
||||
headers['Host'] = this.config.remoteHost;
|
||||
// Set correct host header for remote (include port when non-default)
|
||||
if (this.config.remotePort === 443) {
|
||||
headers['Host'] = this.config.remoteHost;
|
||||
} else {
|
||||
headers['Host'] = `${this.config.remoteHost}:${this.config.remotePort}`;
|
||||
}
|
||||
|
||||
// Inject Authorization header if not present but authToken is configured
|
||||
// This is a fallback - normally the client (CodexReasoningProxy) forwards the header
|
||||
|
||||
Reference in New Issue
Block a user