fix(sftp): cache SFTP channel per session to prevent channel exhaustion
This commit is contained in:
parent
3b1c1aeda1
commit
e3a978b639
@ -157,6 +157,7 @@ export class SshConnectionService {
|
|||||||
session.stream?.close();
|
session.stream?.close();
|
||||||
session.client.end();
|
session.client.end();
|
||||||
this.sessions.delete(sessionId);
|
this.sessions.delete(sessionId);
|
||||||
|
this.sftpChannels.delete(sessionId);
|
||||||
|
|
||||||
// Update connection log with disconnect time
|
// Update connection log with disconnect time
|
||||||
this.prisma.connectionLog.updateMany({
|
this.prisma.connectionLog.updateMany({
|
||||||
@ -170,21 +171,32 @@ export class SshConnectionService {
|
|||||||
return this.sessions.get(sessionId);
|
return this.sessions.get(sessionId);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private sftpChannels = new Map<string, any>();
|
||||||
|
|
||||||
getSftpChannel(sessionId: string): Promise<any> {
|
getSftpChannel(sessionId: string): Promise<any> {
|
||||||
const logger = this.logger;
|
const logger = this.logger;
|
||||||
|
const cached = this.sftpChannels.get(sessionId);
|
||||||
|
if (cached) {
|
||||||
|
return Promise.resolve(cached);
|
||||||
|
}
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
const session = this.sessions.get(sessionId);
|
const session = this.sessions.get(sessionId);
|
||||||
if (!session) {
|
if (!session) {
|
||||||
logger.error(`[SFTP] Session ${sessionId} not found in sessions map (${this.sessions.size} active sessions)`);
|
logger.error(`[SFTP] Session ${sessionId} not found in sessions map (${this.sessions.size} active sessions)`);
|
||||||
return reject(new Error('Session not found'));
|
return reject(new Error('Session not found'));
|
||||||
}
|
}
|
||||||
logger.log(`[SFTP] Requesting SFTP subsystem on session ${sessionId}, client connected: ${(session.client as any)._sock?.readable ?? 'unknown'}`);
|
logger.log(`[SFTP] Requesting SFTP subsystem on session ${sessionId}`);
|
||||||
session.client.sftp((err, sftp) => {
|
session.client.sftp((err, sftp) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
logger.error(`[SFTP] client.sftp() callback error: ${err.message}`);
|
logger.error(`[SFTP] client.sftp() callback error: ${err.message}`);
|
||||||
return reject(err);
|
return reject(err);
|
||||||
}
|
}
|
||||||
logger.log(`[SFTP] SFTP subsystem opened successfully for session ${sessionId}`);
|
logger.log(`[SFTP] SFTP subsystem opened successfully for session ${sessionId}`);
|
||||||
|
sftp.on('close', () => {
|
||||||
|
this.sftpChannels.delete(sessionId);
|
||||||
|
logger.log(`[SFTP] Channel closed for session ${sessionId}`);
|
||||||
|
});
|
||||||
|
this.sftpChannels.set(sessionId, sftp);
|
||||||
resolve(sftp);
|
resolve(sftp);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user