feat(protocol): parse and validate binary packet headers

This commit is contained in:
Stanislav N Mikhailov
2026-07-21 22:57:50 +03:00
parent 9f2d7f635e
commit 0f2cb0384c
5 changed files with 120 additions and 54 deletions
+42 -13
View File
@@ -4,7 +4,7 @@ use tokio::io::{AsyncReadExt, AsyncWriteExt};
use tokio::net::{TcpStream};
use std::io;
use crate::protocol::{parce_header, ParseError};
use crate::protocol::parse_header;
pub struct Connection {
id: u64,
client_addr: SocketAddr,
@@ -54,25 +54,54 @@ impl Connection {
}
// 3. Вызываем ваш парсер заголовка
let header = match parce_header(&header_buffer).await {
Ok(h) => h,
Err(ParseError::InvalidFormat) => {
println!("Обработчик {}: Критическая ошибка! Неверный формат заголовка.", self.id);
// В сетевых протоколах при неверном заголовке соединение обычно сразу рвут
return Err(io::Error::new(io::ErrorKind::InvalidData, "Invalid header format"));
let header = match parse_header(&header_buffer) {
Ok((_remaining, header)) => {
println!(
"Обработчик {}: nom оставил {} байт",
self.id,
_remaining.len()
);
header
}
// Если вы добавите новые ошибки, например FilenameTooLong:
Err(e) => {
println!("Обработчик {}: Ошибка парсинга: {}", self.id, e);
return Err(io::Error::new(io::ErrorKind::InvalidData, e.to_string()));
}
};
Err(error) => {
println!(
"Обработчик {}: ошибка парсинга заголовка: {:?}",
self.id, error
);
return Err(io::Error::new(
io::ErrorKind::InvalidData,
format!("Invalid header: {error:?}"),
));
}
};
//
if let Err(error) = header.validate() {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
error,
));
}
self.message_count += 1;
println!("Обработчик {}: Успешно распарсен заголовок №{}: {:?}", self.id, self.message_count, header);
// 4. Используем данные из распарсенного заголовка!
// Теперь мы знаем точный размер тела сообщения благодаря header.body_size
const MAX_BODY_SIZE: u64 = 1024 * 1024; // 1 МиБ
if header.body_size() > MAX_BODY_SIZE {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
format!(
"Размер тела {} превышает лимит {}",
header.body_size(),
MAX_BODY_SIZE,
),
));
}
let body_len = header.body_size() as usize;
// Подгоняем размер буфера под размер тела (чтобы не читать лишнего)