@@ -117,6 +117,8 @@ export function initializeConnectionHandler(wss: WebSocketServer, sshSuspendServ
|
||||
case 'sftp:realpath':
|
||||
case 'sftp:copy':
|
||||
case 'sftp:move':
|
||||
case 'sftp:compress':
|
||||
case 'sftp:decompress':
|
||||
await handleSftpOperation(ws, type, payload, requestId);
|
||||
break;
|
||||
|
||||
@@ -132,8 +134,6 @@ export function initializeConnectionHandler(wss: WebSocketServer, sshSuspendServ
|
||||
break;
|
||||
|
||||
// --- SSH Suspend Cases ---
|
||||
// 旧的 SSH_SUSPEND_START 逻辑已被新的 SSH_MARK_FOR_SUSPEND 和 SshSuspendService.takeOverMarkedSession 取代
|
||||
// case 'SSH_SUSPEND_START': { ... } // Removed
|
||||
|
||||
case 'SSH_SUSPEND_LIST_REQUEST': {
|
||||
if (!ws.userId) {
|
||||
|
||||
@@ -84,6 +84,35 @@ export async function handleSftpOperation(
|
||||
sftpService.move(sessionId, payload.sources, payload.destination, requestId);
|
||||
} else throw new Error("Missing 'sources' (array) or 'destination' in payload for move");
|
||||
break;
|
||||
case 'sftp:compress':
|
||||
if (Array.isArray(payload?.sources) && payload?.destination && payload?.format && requestId) {
|
||||
const destinationPath = payload.destination as string;
|
||||
// 从 destinationPath 中提取 targetDirectory 和 destinationArchiveName
|
||||
// pathModule.posix 总是使用 / 作为分隔符
|
||||
const pathModule = await import('path'); // 动态导入 path 模块
|
||||
const targetDirectory = pathModule.posix.dirname(destinationPath);
|
||||
const destinationArchiveName = pathModule.posix.basename(destinationPath);
|
||||
|
||||
const compressPayload = {
|
||||
sources: payload.sources as string[],
|
||||
destinationArchiveName: destinationArchiveName,
|
||||
format: payload.format as 'zip' | 'targz' | 'tarbz2',
|
||||
targetDirectory: targetDirectory,
|
||||
requestId: requestId
|
||||
};
|
||||
sftpService.compress(sessionId, compressPayload);
|
||||
} else throw new Error("Missing 'sources' (array), 'destination', 'format', or 'requestId' in payload for compress");
|
||||
break;
|
||||
case 'sftp:decompress':
|
||||
if (payload?.source && requestId) {
|
||||
const decompressPayload = {
|
||||
archivePath: payload.source as string,
|
||||
// destinationDirectory: payload.destination as string, // sftpService.decompress 目前不使用此参数
|
||||
requestId: requestId
|
||||
};
|
||||
sftpService.decompress(sessionId, decompressPayload);
|
||||
} else throw new Error("Missing 'source' or 'requestId' in payload for decompress");
|
||||
break;
|
||||
default:
|
||||
console.warn(`WebSocket: Received unhandled SFTP message type in sftp.handler: ${type}`);
|
||||
if (ws.readyState === WebSocket.OPEN) ws.send(JSON.stringify({ type: 'sftp_error', payload: { message: `内部未处理的 SFTP 类型: ${type}`, requestId } }));
|
||||
|
||||
@@ -251,4 +251,46 @@ export type SshSuspendServerToClientMessages =
|
||||
// export type WebSocketMessage = BaseMessageType | SshSuspendClientToServerMessages | OtherFeatureMessages;
|
||||
// And for outgoing:
|
||||
// export type WebSocketResponse = BaseResponseType | SshSuspendServerToClientMessages | OtherFeatureResponses;
|
||||
// This part depends on the existing structure, so I'm providing the specific types for now.
|
||||
// This part depends on the existing structure, so I'm providing the specific types for now.
|
||||
// --- SFTP Compress/Decompress Message Types ---
|
||||
|
||||
// C -> S: Request to compress files/directories
|
||||
export interface SftpCompressRequestPayload {
|
||||
sources: string[]; // Array of source paths (relative to targetDirectory)
|
||||
destinationArchiveName: string; // Desired name for the archive file
|
||||
format: 'zip' | 'targz' | 'tarbz2'; // Archive format
|
||||
targetDirectory: string; // The directory where sources are located and where the archive will be created
|
||||
requestId: string;
|
||||
}
|
||||
|
||||
// S -> C: Compression success
|
||||
export interface SftpCompressSuccessPayload {
|
||||
message: string;
|
||||
requestId: string;
|
||||
}
|
||||
|
||||
// S -> C: Compression error
|
||||
export interface SftpCompressErrorPayload {
|
||||
error: string;
|
||||
details?: string; // Stderr output or specific error details
|
||||
requestId: string;
|
||||
}
|
||||
|
||||
// C -> S: Request to decompress an archive
|
||||
export interface SftpDecompressRequestPayload {
|
||||
archivePath: string; // Full path to the archive file
|
||||
requestId: string;
|
||||
}
|
||||
|
||||
// S -> C: Decompression success
|
||||
export interface SftpDecompressSuccessPayload {
|
||||
message: string;
|
||||
requestId: string;
|
||||
}
|
||||
|
||||
// S -> C: Decompression error
|
||||
export interface SftpDecompressErrorPayload {
|
||||
error: string;
|
||||
details?: string; // Stderr output or specific error details
|
||||
requestId: string;
|
||||
}
|
||||
@@ -44,7 +44,7 @@ export function initializeUpgradeHandler(
|
||||
// 确保 ipAddress 不是 undefined 或空字符串,否则设为 'unknown'
|
||||
ipAddress = ipAddress || 'unknown';
|
||||
console.log(`[WebSocket Upgrade] Determined IP Address: ${ipAddress}`);
|
||||
// --- 结束修改 ---
|
||||
|
||||
|
||||
console.log(`WebSocket: 升级请求来自 IP: ${ipAddress}, Path: ${pathname}`); // 使用新获取的 ipAddress
|
||||
|
||||
|
||||
Reference in New Issue
Block a user