Files
markbase/docs/SSH2_REFACTOR_MODULES.md
Warren 1300a4e223
Some checks failed
Test / test (push) Has been cancelled
Test / build (push) Has been cancelled
MarkBase架构升级:Multi-Volume Virtual Tree + Dual-View Management + Git Remote修正
核心功能:
-  Categories/Series双视图管理(category_view.rs + import_markdown.rs)
-  FUSE Multi-Volume支持(tree_type参数)
-  SSH/SFTP/SCP/rsync协议完整实现(4042行)
-  NFS/SMB Module Phase 1-3完成
-  Archive Module Phase 1-4完成(2916行)
-  Download Center API完整实现
-  S3兼容API实现(560行)

Git配置修正:
-  删除错误origin(gitea.momentry.ddns.net)
-  删除m5max128(指向机器名)
-  设置origin = m5max128gitea.momentry.ddns.net/admin/markbase
-  设置m4minigitea = m4minigitea.momentry.ddns.net/warren/markbase

数据清理:
-  删除38个临时SQLite(保留accusys.sqlite、demo.sqlite)
-  删除.bak、test_*.bin、调试脚本等临时文件
-  删除临时目录(build/、download files/、raid_test/等)
-  更新.gitignore排除临时文件

架构优化:
- 52个文件修改,2434行新增,4739行删除
- Workspace成员整合(16个crate)
- 数据库状态:accusys.sqlite保留(主demo测试)

远程同步:
-  准备推送到m5max128gitea(远程Gitea)
-  准备推送到m4minigitea(本地Gitea)
2026-06-12 12:59:54 +08:00

11 KiB
Raw Blame History

ssh2重构模块清单

分析日期: 2026-06-10 01:40


一、现有模块分析

需要重写的模块

模块 文件 代码行数 重写方式
SSH Server sftp/server.rs 478行 完全重写ssh2
SFTP Handler sftp/handler.rs 约500行 完全重写ssh2
SFTP Auth sftp/auth.rs 37行 复用bcrypt
SFTP Config sftp/config.rs 133行 复用
SFTP FileTree sftp/filetree.rs 141行 复用
SCP Sender sftp/scp_sender.rs 89行 移植到ssh2
SCP Handler ssh2_mod/scp_handler.rs 174行 移植到主模块
rsync Receiver ssh2_mod/rsync_receiver.rs 109行 移植到主模块
rsync算法 rsync/*.rs 801行 复用

二、可复用代码

100%复用(无需改动)

模块 文件 说明
Auth系统 sftp/auth.rs bcrypt验证逻辑
Config系统 sftp/config.rs SftpConfig结构
FileTree映射 sftp/filetree.rs 路径映射逻辑
rsync checksum rsync/checksum.rs Rolling checksum算法
rsync delta rsync/delta.rs Delta算法
rsync protocol rsync/protocol.rs rsync协议常量
SQLite数据库 data/auth.sqlite 用户认证数据

部分复用(需要适配)

模块 文件 改动量
SCP Sender scp_sender.rs 约20行适配ssh2::Channel
SCP Handler scp_handler.rs 约30行适配ssh2::Channel
rsync Handler rsync/handler.rs 约50行适配ssh2::Channel

三、需要完全重写的模块

SSH Server约200行

重写内容

// ssh2_server.rs新文件
use ssh2::Session;
use std::net::{TcpListener, TcpStream};

pub struct Ssh2Server {
    config: Arc<SftpConfig>,
}

impl Ssh2Server {
    pub fn run(&self, port: u16) -> Result<()> {
        let listener = TcpListener::bind(("127.0.0.1", port))?;
        
        for stream in listener.incoming() {
            let stream = stream?;
            self.handle_connection(stream)?;
        }
        
        Ok(())
    }
    
    fn handle_connection(&self, stream: TcpStream) -> Result<()> {
        let mut session = Session::new()?;
        session.set_tcp_stream(stream);
        session.handshake()?;
        
        // 认证
        self.authenticate(&session)?;
        
        // 处理channel请求
        self.handle_channels(&session)?;
        
        Ok(())
    }
}

SFTP Handler约300行

重写内容

// sftp2_handler.rs新文件
use ssh2::Channel;

pub struct Sftp2Handler {
    user_id: String,
    config: Arc<SftpConfig>,
}

impl Sftp2Handler {
    pub fn handle_sftp(&self, channel: &mut Channel) -> Result<()> {
        // 14个SFTP操作
        self.handle_init(channel)?;
        self.handle_open(channel)?;
        self.handle_read(channel)?;
        self.handle_write(channel)?;
        self.handle_close(channel)?;
        self.handle_mkdir(channel)?;
        self.handle_rmdir(channel)?;
        self.handle_remove(channel)?;
        self.handle_rename(channel)?;
        self.handle_opendir(channel)?;
        self.handle_readdir(channel)?;
        self.handle_realpath(channel)?;
        self.handle_stat(channel)?;
        self.handle_lstat(channel)?;
        
        Ok(())
    }
}

关键改动

  • russh-sftp → 直接实现SFTP协议packet
  • 或使用ssh2::Channel::exec("sftp-server")

SCP Handler约200行

重写内容

// scp2_handler.rs新文件
use ssh2::Channel;

pub struct Scp2Handler {
    user_id: String,
    config: Arc<SftpConfig>,
}

impl Scp2Handler {
    pub fn handle_scp(&self, channel: &mut Channel, command: &str) -> Result<()> {
        if command.contains("-f") {
            self.handle_scp_sender(channel, command)?;
        } else if command.contains("-t") {
            self.handle_scp_receiver(channel, command)?;
        } else if command.contains("-r") {
            self.handle_scp_recursive(channel, command)?;
        }
        
        Ok(())
    }
    
    fn handle_scp_sender(&self, channel: &mut Channel, command: &str) -> Result<()> {
        // scp -f发送文件write
        let file_path = self.parse_path(command)?;
        let file_content = std::fs::read(&file_path)?;
        
        // 发送SCP header
        let header = self.build_scp_header(&file_path)?;
        channel.write_all(header.as_bytes())?;
        
        // 发送文件内容
        channel.write_all(&file_content)?;
        
        // 发送结束标志
        channel.write_all(&[0x00])?;
        channel.write_all("E\n".as_bytes())?;
        
        Ok(())
    }
    
    fn handle_scp_receiver(&self, channel: &mut Channel, command: &str) -> Result<()> {
        // scp -t接收文件read ⭐新增
        channel.write_all(&[0x00])?; // 确认
        
        // 读取SCP header
        let mut buf = vec![0u8; 8192];
        let len = channel.read(&mut buf)?;
        let header = String::from_utf8_lossy(&buf[..len]);
        
        // 解析header获取文件名和大小
        let (filename, size) = self.parse_scp_header(&header)?;
        
        // 读取文件内容
        let mut file = File::create(&filename)?;
        let mut received = 0;
        while received < size {
            let len = channel.read(&mut buf)?;
            file.write_all(&buf[..len])?;
            received += len as u64;
        }
        
        Ok(())
    }
}

rsync Handler约300行

重写内容

// rsync2_handler.rs新文件
use ssh2::Channel;
use crate::rsync::{ChecksumEngine, DeltaEngine};

pub struct Rsync2Handler {
    user_id: String,
    config: Arc<SftpConfig>,
}

impl Rsync2Handler {
    pub fn handle_rsync(&self, channel: &mut Channel, command: &str) -> Result<()> {
        if command.contains("--sender") {
            self.handle_rsync_sender(channel, command)?;
        } else if command.contains("--receiver") {
            self.handle_rsync_receiver(channel, command)?;
        }
        
        Ok(())
    }
    
    fn handle_rsync_sender(&self, channel: &mut Channel, command: &str) -> Result<()> {
        // rsync sender已有算法可移植
        let file_path = self.parse_path(command)?;
        let checksums = ChecksumEngine::compute(&file_path)?;
        
        // 发送checksum
        channel.write_all(&checksums)?;
        
        // 接收delta请求
        let mut buf = vec![0u8; 4096];
        let len = channel.read(&mut buf)?; // ⭐ssh2支持read
        
        // 发送delta数据
        let delta = DeltaEngine::compute(&file_path, &buf[..len])?;
        channel.write_all(&delta)?;
        
        Ok(())
    }
    
    fn handle_rsync_receiver(&self, channel: &mut Channel, command: &str) -> Result<()> {
        // rsync receiver ⭐新增
        let dest_path = self.parse_path(command)?;
        
        // 发送checksum请求
        channel.write_all(&[RSYNC_CHECKSUM_REQUEST])?;
        
        // 接收checksum
        let mut checksums = vec![0u8; 4096];
        channel.read_exact(&mut checksums)?; // ⭐ssh2支持read
        
        // 计算本地checksum
        let local_checksums = ChecksumEngine::compute(&dest_path)?;
        
        // 发送delta请求
        let delta_request = self.build_delta_request(&checksums, &local_checksums)?;
        channel.write_all(&delta_request)?;
        
        // 接收delta数据
        let mut delta_data = vec![0u8; 8192];
        channel.read(&mut delta_data)?; // ⭐ssh2支持read
        
        // 应用delta
        DeltaEngine::apply(&dest_path, &delta_data)?;
        
        Ok(())
    }
}

四、代码统计

重写工作量

类别 代码行数 工作量
SSH Server 约200行 Day 1
SFTP Handler 约300行 Day 2
SCP Handler 约200行 Day 3
rsync Handler 约300行 Day 4
测试 约200行 Day 5
总计 约1200行 5天

可复用代码

类别 代码行数 复用率
Auth 37行 100%
Config 133行 100%
FileTree 141行 100%
rsync算法 801行 100%
总计 约1112行 100%复用

五、文件结构规划

新文件结构

markbase-core/src/
├── ssh2_server/           # 新目录
│   ├── mod.rs             # 模块导出
│   ├── server.rs          # SSH Server核心200行
│   ├── sftp_handler.rs    # SFTP Handler300行
│   ├── scp_handler.rs     # SCP Handler200行
│   ├── rsync_handler.rs   # rsync Handler300行
│   └── channel.rs         # Channel管理100行
│
├── sftp/                  # 保留部分
│   ├── auth.rs            # 复用 ✅
│   ├── config.rs          # 复用 ✅
│   ├── filetree.rs        # 复用 ✅
│   └── server.rs          # 删除 ❌
│   └── handler.rs         # 删除 ❌
│   └── scp_sender.rs      # 删除 ❌
│
├── ssh2_mod/              # 合并到ssh2_server
│   ├── scp_handler.rs     # 合并 ⚠️
│   └── rsync_receiver.rs  # 合并 ⚠️
│
└── rsync/                 # 复用 ✅
    ├── checksum.rs        # 复用
    ├── delta.rs           # 复用
    ├── protocol.rs        # 复用
    └── handler.rs         # 需适配

六、迁移策略

阶段性迁移

Step 1创建ssh2_server目录

  • 新建ssh2_server/mod.rs
  • 新建ssh2_server/server.rs

Step 2实现SSH Server核心

  • Auth逻辑复用sftp/auth.rs
  • Config复用sftp/config.rs

Step 3实现SFTP Handler

  • 重写14个操作
  • FileTree映射复用

Step 4实现SCP Handler

  • 合并scp_sender.rs和scp_handler.rs
  • 完整sender + receiver

Step 5实现rsync Handler

  • 合并rsync算法
  • 完整sender + receiver

Step 6删除旧russh代码

  • 删除sftp/server.rs
  • 删除sftp/handler.rs
  • 删除ssh2_mod目录

七、测试计划

单元测试

测试项 文件
SSH连接测试 tests/ssh2_connection_test.sh
Auth测试 tests/auth_test.sh复用
SFTP测试 tests/sftp_test.sh适配
SCP测试 tests/scp_test.sh新增
rsync测试 tests/rsync_test.sh新增

功能测试

SSH连接

ssh -p 2023 warren@127.0.0.1

SFTP操作

sftp -P 2023 warren@127.0.0.1
sftp> ls
sftp> get file.txt
sftp> put file.txt

SCP操作

# SCP下载sender
scp -P 2023 warren@127.0.0.1:/path/file.txt /tmp/

# SCP上传receiver⭐新增
scp -P 2023 /tmp/file.txt warren@127.0.0.1:/path/

rsync操作

# rsync下载sender
rsync -av -e "ssh -p 2023" warren@127.0.0.1:/path/ /tmp/

# rsync上传receiver⭐新增
rsync -av -e "ssh -p 2023" /tmp/ warren@127.0.0.1:/path/

模块清单完成时间: 2026-06-10 01:45 版本: 1.0