refactor(upload): route upload commands to dedicated handler

This commit is contained in:
Stanislav N Mikhailov
2026-08-10 14:17:29 +03:00
parent 3c3487b554
commit e45b86cd20
4 changed files with 61 additions and 91 deletions
+42 -84
View File
@@ -8,17 +8,12 @@ use tokio::{
net::TcpStream,
};
use crate::protocol::{
decode_header,
Header,
HEADER_SIZE,
MAX_BODY_SIZE,
Command,
};
use crate::{protocol::{
Command, HEADER_SIZE, Header, MAX_BODY_SIZE, decode_header,
}, upload};
struct IncomingMessage {
header: Header,
body: Vec<u8>,
}
pub struct Connection {
@@ -51,7 +46,7 @@ impl Connection {
while let Some(message) = self.read_message().await? {
self.message_count += 1;
self.handle_message(message).await?;
self.print_message(message).await?;
}
println!(
@@ -69,13 +64,45 @@ impl Connection {
let Some(header) = self.read_header().await? else {
return Ok(None);
};
//Заголовок скачен и валиден. Получаем команду из заголовка
match header.command() {
Command::Upload => {
println!("Команда UPLOAD");
let upl_result=
upload::handle(&mut self.stream, header).await.map_err(|error| {
io::Error::new(
io::ErrorKind::InvalidData,
format!("Ошибка UPLOAD:{error:}")
)
}
);
}
Command::Download => {
println!("Команда DOWNLOAD");
}
Command::Delete => {
println!("Команда DELETE");
}
Command::Stat => {
println!("Команда STAT");
}
Command::FileData => {
println!("Команда FILEDATA");
}
Command::Response => {
println!("Команда RESPONSE");
}
}
let body = self.read_body(header.body_size()).await?;
//let body = self.read_body(header.body_size()).await?;
Ok(Some(IncomingMessage {
header,
body,
}))
Ok(None)
}
async fn read_header(&mut self) -> io::Result<Option<Header>> {
@@ -100,59 +127,10 @@ impl Connection {
format!("Ошибка разбора заголовка: {error:?}"),
)
})?;
//Заголовок скачен и валиден. Получаем команду из заголовка
match header.command() {
Command::Upload => {
println!("Команда UPLOAD");
}
Command::Download => {
println!("Команда DOWNLOAD");
}
Command::Delete => {
println!("Команда DELETE");
}
Command::Stat => {
println!("Команда STAT");
}
Command::FileData => {
println!("Команда FILEDATA");
}
Command::Response => {
println!("Команда RESPONSE");
}
}
Ok(Some(header))
}
async fn read_body( //todo: анахронизм, убрать после реализации storage
&mut self,
body_size: u64,
) -> io::Result<Vec<u8>> {
if body_size > MAX_BODY_SIZE {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
format!(
"Размер тела {body_size} превышает лимит \
{MAX_BODY_SIZE}"
),
));
}
let mut body = vec![0_u8; body_size as usize];
self.stream.read_exact(&mut body).await?;
Ok(body)
}
async fn handle_message(
async fn print_message(
&mut self,
message: IncomingMessage,
) -> io::Result<()> {
@@ -162,26 +140,6 @@ impl Connection {
self.message_count,
message.header
);
// Это знание конкретной команды.
// Позже этот код можно вынести в отдельный handler.rs.
let body_text = String::from_utf8_lossy(&message.body);
println!(
"Соединение {}: тело: {:?}",
self.id,
body_text
);
let response = format!(
"Соединение {}: запрос {} принят, cmd={:?}\n",
self.id,
message.header.request_id(),
message.header.command(),
);
self.stream.write_all(response.as_bytes()).await?;
Ok(())
}
}
+7 -7
View File
@@ -29,21 +29,21 @@
### 2. Создать постоянный модуль загрузки
- [ ] Создать `upload.rs`.
- [ ] Подключить его в `main.rs`:
- [✔] Создать `upload.rs`.
- [✔] Подключить его в `main.rs`:
```rust
mod upload;
```
- [ ] Создать в нём асинхронную функцию `handle()`.
- [ ] Передать в неё:
- [✔ Создать в нём асинхронную функцию `handle()`.
- [✔] Передать в неё:
- `&mut` сетевой поток;
- проверенный `Header`.
- [ ] Пока только вывести заголовок и вернуть `Ok(())`.
- [ ] Убедиться, что после вызова управление возвращается в цикл `Connection`.
- [✔] Пока только вывести заголовок и вернуть `Ok(())`.
- [✔] Убедиться, что после вызова управление возвращается в цикл `Connection`.
Первая форма может иметь такой смысл:
@@ -59,7 +59,7 @@ pub async fn handle(
### 3. Убрать чтение всего тела в `Vec`
- [ ] Не вызывать текущий `read_body()` для команды `UPLOAD`.
- [✔] Не вызывать текущий `read_body()` для команды `UPLOAD`.
- [ ] Не создавать:
```rust
+1
View File
@@ -1,5 +1,6 @@
mod connection; //модуль отвечающий за соединения
mod protocol; //модуль отвечающий за протокол ...
mod upload; //Модуль отвечающий за загрузку файла
use tokio::net::{TcpListener};
use tokio::io;
+11
View File
@@ -0,0 +1,11 @@
use tokio::{io, net::TcpStream, stream};
use crate::protocol::Header;
pub async fn handle(
stream: &mut TcpStream,
header: Header,
) -> io::Result<()> {
println!("Обработчик UPLOAD получил заголовок: {header:?}");
Ok(())
}