refactor(upload): route upload commands to dedicated handler
This commit is contained in:
+42
-84
@@ -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:}")
|
||||
)
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
let body = self.read_body(header.body_size()).await?;
|
||||
Command::Download => {
|
||||
println!("Команда DOWNLOAD");
|
||||
}
|
||||
|
||||
Ok(Some(IncomingMessage {
|
||||
header,
|
||||
body,
|
||||
}))
|
||||
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?;
|
||||
|
||||
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
@@ -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,5 +1,6 @@
|
||||
mod connection; //модуль отвечающий за соединения
|
||||
mod protocol; //модуль отвечающий за протокол ...
|
||||
mod upload; //Модуль отвечающий за загрузку файла
|
||||
|
||||
use tokio::net::{TcpListener};
|
||||
use tokio::io;
|
||||
|
||||
@@ -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(())
|
||||
}
|
||||
Reference in New Issue
Block a user