核心功能: - ✅ 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)
428 lines
11 KiB
Markdown
428 lines
11 KiB
Markdown
# 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行)
|
||
|
||
**重写内容**:
|
||
```rust
|
||
// 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行)
|
||
|
||
**重写内容**:
|
||
```rust
|
||
// 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行)
|
||
|
||
**重写内容**:
|
||
```rust
|
||
// 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行)
|
||
|
||
**重写内容**:
|
||
```rust
|
||
// 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 Handler(300行)
|
||
│ ├── scp_handler.rs # SCP Handler(200行)
|
||
│ ├── rsync_handler.rs # rsync Handler(300行)
|
||
│ └── 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连接**:
|
||
```bash
|
||
ssh -p 2023 warren@127.0.0.1
|
||
```
|
||
|
||
**SFTP操作**:
|
||
```bash
|
||
sftp -P 2023 warren@127.0.0.1
|
||
sftp> ls
|
||
sftp> get file.txt
|
||
sftp> put file.txt
|
||
```
|
||
|
||
**SCP操作**:
|
||
```bash
|
||
# 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操作**:
|
||
```bash
|
||
# 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
|
||
|