feat: add logging support

This commit is contained in:
Michel de Graaf
2025-07-05 23:16:05 +02:00
parent 57dafaf8ab
commit 956cb824bd
28 changed files with 765 additions and 203 deletions
View File
+102 -23
View File
@@ -8,6 +8,25 @@ pub use message_reader::*;
use std::str;
#[derive(Debug, PartialEq)]
pub enum MessageType {
Server,
Peer,
PeerInit,
Distributed,
}
#[derive(Debug)]
pub struct Error(String);
impl std::fmt::Display for Error {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "{}", self.0)
}
}
impl std::error::Error for Error {}
#[derive(Debug, PartialEq, Clone)]
pub struct Message {
data: Vec<u8>,
@@ -62,7 +81,7 @@ impl Message {
}
}
println!();
trace!("");
}
}
//
@@ -122,9 +141,9 @@ impl Message {
pub fn new_with_data(data: Vec<u8>) -> Self {
Self { data, pointer: 0 }
}
// pub fn reset_pointer(&mut self) {
// self.pointer = 0;
// }
pub fn reset_pointer(&mut self) {
self.pointer = 0;
}
pub fn set_pointer(&mut self, pointer: usize) {
self.pointer = pointer;
}
@@ -169,27 +188,16 @@ impl Message {
String::from_utf8(data.to_vec()).expect("Failed to read string")
}
pub fn read_raw_hex_str(&mut self, size: usize) -> String {
let hex_str = self.data[self.pointer..self.pointer + size]
.iter()
.fold(String::new(), |mut acc, byte| {
use std::fmt::Write;
write!(acc, "{:02x}", byte).expect("Failed to write to string");
acc
});
self.pointer += size;
hex_str
}
pub fn read_int8(&mut self) -> i8 {
let val = self.data[self.pointer] as i8;
pub fn read_int8(&mut self) -> u8 {
let val = self.data[self.pointer];
self.pointer += 1;
val
}
#[allow(dead_code)]
pub fn read_int64(&mut self) -> i64 {
let val = i64::from_le_bytes([
pub fn read_int64(&mut self) -> u64 {
let val = u64::from_le_bytes([
self.data[self.pointer],
self.data[self.pointer + 1],
self.data[self.pointer + 2],
@@ -203,12 +211,12 @@ impl Message {
val
}
pub fn read_int32(&mut self) -> i32 {
pub fn read_int32(&mut self) -> u32 {
if self.pointer + 4 > self.data.len() {
return 0;
}
let val = i32::from_le_bytes([
let val = u32::from_le_bytes([
self.data[self.pointer],
self.data[self.pointer + 1],
self.data[self.pointer + 2],
@@ -231,7 +239,12 @@ impl Message {
self
}
pub fn write_int32(&mut self, value: i32) -> &mut Self {
pub fn write_int32(&mut self, value: u32) -> &mut Self {
self.data.extend_from_slice(&value.to_le_bytes());
self
}
pub fn write_int64(&mut self, value: u64) -> &mut Self {
self.data.extend_from_slice(&value.to_le_bytes());
self
}
@@ -240,6 +253,11 @@ impl Message {
self
}
pub fn write_bool(&mut self, value: bool) -> &mut Self {
self.data.push(if value { 1 } else { 0 });
self
}
pub fn write_raw_hex_string(&mut self, val: &str) -> &mut Self {
let mut b = Vec::new();
for i in (0..val.len()).step_by(2) {
@@ -251,6 +269,67 @@ impl Message {
self.pointer += b.len();
self
}
pub fn get_message_name(&self, msg_type: MessageType, code: u32) -> Result<&str, Error> {
match msg_type {
MessageType::Server => match code {
1 => Ok("Login"),
2 => Ok("SetWaitPort"),
3 => Ok("GetPeerAddress"),
5 => Ok("WatchUser"),
6 => Ok("UnwatchUser"),
7 => Ok("GetUserStatus"),
13 => Ok("SayChatroom"),
14 => Ok("JoinRoom"),
15 => Ok("LeaveRoom"),
18 => Ok("ConnectToPeer"),
22 => Ok("MessageUser"),
23 => Ok("MessageAcked"),
26 => Ok("FileSearch"),
28 => Ok("SetStatus"),
32 => Ok("ServerPing"),
35 => Ok("SharedFoldersFiles"),
36 => Ok("GetUserStats"),
41 => Ok("Relogged"),
42 => Ok("UserSearch"),
64 => Ok("RoomList"),
92 => Ok("CheckPrivileges"),
100 => Ok("AcceptChildren"),
102 => Ok("PossibleParents"),
1001 => Ok("CantConnectToPeer"),
_ => Err(Error(format!("Unknown server message code: {}", code))),
},
MessageType::PeerInit => match code {
0 => Ok("PierceFireWall"),
1 => Ok("PeerInit"),
_ => Err(Error(format!("Unknown peer init message code: {}", code))),
},
MessageType::Peer => match code {
4 => Ok("GetShareFileList"),
5 => Ok("SharedFileListResponse"),
9 => Ok("FileSearchResponse"),
15 => Ok("UserInfoRequest"),
16 => Ok("UserInfoResponse"),
36 => Ok("FolderContentsRequest"),
37 => Ok("FolderContentsResponse"),
40 => Ok("TransferRequest"),
41 => Ok("TransferResponse"),
43 => Ok("QueueUpload"),
44 => Ok("PlaceInQueueResponse"),
46 => Ok("UploadFailed"),
50 => Ok("UploadDenied"),
51 => Ok("PlaceInQueueRequest"),
_ => Err(Error(format!("Unknown peer message code: {}", code))),
},
MessageType::Distributed => match code {
3 => Ok("SearchRequest"),
4 => Ok("BranchLevel"),
5 => Ok("BranchRoot"),
93 => Ok("EmbeddedMessage"),
_ => Err(Error(format!("Unknown distributed message code: {}", code))),
},
}
}
// pub fn decode(&self) {
// println!("{:?}", self.data);
// }
@@ -326,4 +405,4 @@ fn test_read_string_invalid_utf8() {
];
let mut test_data = Message::new_with_data(data);
test_data.read_string();
}
}
+2 -49
View File
@@ -1,55 +1,8 @@
use crate::message::{Message, MessageHandler};
use crate::peer::PeerOperation;
use crate::types::{File, FileSearchResult};
use crate::utils::zlib::deflate;
use std::collections::HashMap;
use crate::types::FileSearchResult;
use std::sync::mpsc::Sender;
fn decompress_buffer(buffer: &[u8]) -> Result<Vec<u8>, String> {
deflate(buffer)
}
impl FileSearchResult {
pub fn new_from_message(message: &mut Message) -> Self {
let pointer = message.get_pointer();
let size = message.get_size();
let data: Vec<u8> = message.get_slice(pointer, size);
let deflated = decompress_buffer(&data).unwrap();
let mut message = Message::new_with_data(deflated);
let username = message.read_string();
let token = message.read_raw_hex_str(4);
let n_files = message.read_int32();
let mut files: Vec<File> = Vec::new();
for _ in 0..n_files {
message.read_int8();
let name = message.read_string();
let size = message.read_int32();
message.read_int32();
message.read_string();
let n_attribs = message.read_int32();
let mut attribs: HashMap<i32, i32> = HashMap::new();
for _ in 0..n_attribs {
attribs.insert(message.read_int32(), message.read_int32());
}
files.push(File {
username: username.clone(),
name,
size,
attribs,
});
}
let slots = message.read_int8();
let speed = message.read_int32();
Self {
token,
files,
slots,
speed,
}
}
}
pub struct FileSearchResponse;
impl MessageHandler<PeerOperation> for FileSearchResponse {
fn get_code(&self) -> u8 {
@@ -85,7 +38,7 @@ fn test_new_from_message() {
message.set_pointer(8);
let file_search = FileSearchResult::new_from_message(&mut message);
assert_eq!(file_search.token, "6d2b9434");
assert_eq!(file_search.token, 23);
assert_eq!(file_search.files.len(), 2);
let file = &file_search.files[0];
assert_eq!(
+17
View File
@@ -0,0 +1,17 @@
use crate::{
message::{server::MessageFactory, Message, MessageHandler},
peer::PeerOperation,
};
use std::sync::mpsc::Sender;
pub struct GetShareFileList;
impl MessageHandler<PeerOperation> for GetShareFileList {
fn get_code(&self) -> u8 {
4
}
fn handle(&self, _message: &mut Message, sender: Sender<PeerOperation>) {
let message = MessageFactory::build_shared_folders_message(100, 800);
sender.send(PeerOperation::SendMessage(message)).unwrap();
}
}
+3
View File
@@ -1,3 +1,6 @@
pub mod file_search_response;
pub mod get_share_file_list;
pub mod transfer_request;
pub mod upload_failed;
pub use self::file_search_response::*;
+20
View File
@@ -0,0 +1,20 @@
use crate::{
message::{Message, MessageHandler},
peer::PeerOperation,
types::Transfer,
};
use std::sync::mpsc::Sender;
pub struct TransferRequest;
impl MessageHandler<PeerOperation> for TransferRequest {
fn get_code(&self) -> u8 {
40
}
fn handle(&self, message: &mut Message, sender: Sender<PeerOperation>) {
let transfer = Transfer::new_from_message(message);
sender
.send(PeerOperation::TransferRequest(transfer))
.unwrap();
}
}
+17
View File
@@ -0,0 +1,17 @@
use crate::{
message::{Message, MessageHandler},
peer::PeerOperation,
types::UploadFailed,
};
use std::sync::mpsc::Sender;
pub struct UploadFailedHandler;
impl MessageHandler<PeerOperation> for UploadFailedHandler {
fn get_code(&self) -> u8 {
46
}
fn handle(&self, message: &mut Message, sender: Sender<PeerOperation>) {
let upload_failed = UploadFailed::new_from_message(message);
info!("Upload failed for ${}", upload_failed.filename);
}
}
+7 -1
View File
@@ -1,5 +1,5 @@
use crate::message::{Message, MessageHandler};
use crate::peer::Peer;
use crate::peer::{ConnectionType, Peer};
use crate::server::ServerOperation;
use std::sync::mpsc::Sender;
pub struct ConnectToPeerHandler;
@@ -9,6 +9,12 @@ impl MessageHandler<ServerOperation> for ConnectToPeerHandler {
}
fn handle(&self, message: &mut Message, sender: Sender<ServerOperation>) {
let peer = Peer::new_from_message(message);
match peer.connection_type {
ConnectionType::P => (),
ConnectionType::F => trace!("[server] ConnectToPeer {:?}", peer),
ConnectionType::D => (),
}
sender.send(ServerOperation::ConnectToPeer(peer)).unwrap();
}
}
@@ -20,6 +20,6 @@ impl MessageHandler<ServerOperation> for ExcludedSearchPhrasesHandler {
let phrase = message.read_string();
exluded_phrases.push(phrase);
}
println!("Excluded search phrases: {:?}", exluded_phrases);
debug!("Excluded search phrases: {:?}", exluded_phrases);
}
}
+2 -2
View File
@@ -12,11 +12,11 @@ impl MessageHandler<ServerOperation> for FileSearchHandler {
26
}
fn handle(&self, message: &mut Message, _sender: Sender<ServerOperation>) {
println!("Handling file search message");
debug!("Handling file search message");
let username = message.read_string();
let token = message.read_int32();
let query = message.read_string();
println!(
info!(
"Message search username:{}, token: {}, query: {}",
username, token, query
);
+2 -2
View File
@@ -20,9 +20,9 @@ impl MessageHandler<ServerOperation> for LoginHandler {
return sender.send(ServerOperation::LoginStatus(false)).unwrap();
}
println!("Login successful");
info!("Login successful");
let greeting = message.read_string();
println!("Server greeting: {:?}", greeting);
debug!("Server greeting: {:?}", greeting);
sender.send(ServerOperation::LoginStatus(true)).unwrap();
}
+29 -8
View File
@@ -1,4 +1,4 @@
use crate::{message::Message, utils::md5};
use crate::{message::Message, types::Transfer, utils::md5};
pub struct MessageFactory;
impl MessageFactory {
@@ -18,7 +18,7 @@ impl MessageFactory {
// ]
// .to_vec(),
// )
// .clone()
// .clone()fac
let hash = md5([username, password].join("").as_str());
let mut message = Message::new();
@@ -34,14 +34,14 @@ impl MessageFactory {
message
}
pub fn build_shared_folders_message(folder_count: i32, file_count: i32) -> Message {
pub fn build_shared_folders_message(folder_count: u32, file_count: u32) -> Message {
Message::new()
.write_int32(35)
.write_int32(folder_count)
.write_int32(file_count)
.clone()
}
pub fn build_file_search_message(token: i32, query: &str) -> Message {
pub fn build_file_search_message(token: u32, query: &str) -> Message {
// Message::new_with_data(
// [
// 26, 0, 0, 0, 219, 178, 47, 28, 11, 0, 0, 0, 116, 104, 101, 32, 119, 101, 101, 107, 101,
@@ -56,7 +56,7 @@ impl MessageFactory {
.write_string(query)
.clone()
}
pub fn build_set_status_message(status_code: i32) -> Message {
pub fn build_set_status_message(status_code: u32) -> Message {
Message::new()
.write_int32(28)
.write_int32(status_code)
@@ -68,17 +68,38 @@ impl MessageFactory {
pub fn build_set_wait_port_message() -> Message {
Message::new().write_int32(2).write_int32(2234).clone()
}
pub fn build_watch_user(token: &str) -> Message {
pub fn build_watch_user(token: u32) -> Message {
Message::new()
.write_raw_bytes([5, 0, 0, 0, 0].to_vec())
.write_raw_hex_string(token)
.write_int32(token)
.clone()
}
pub fn build_queue_upload_message(filename: &str) -> Message {
Message::new()
.write_int32(43)
.write_string(filename)
.clone()
}
pub fn build_transfer_response_message(transfer: Transfer) -> Message {
Message::new()
.write_int32(41)
.write_int32(transfer.token)
.write_bool(true)
.clone()
}
pub fn build_pierce_firewall_message(token: u32) -> Message {
Message::new()
.write_int32(0) // PierceFirewall message code
.write_int32(token)
.clone()
}
}
#[test]
fn test_build_watch_user() {
let token = "5b581500";
let token: u32 = 223;
let message = MessageFactory::build_watch_user(token);
let expect: Vec<u8> = [5, 0, 0, 0, 0, 91, 88, 21, 0].to_vec();
+1 -1
View File
@@ -25,7 +25,7 @@ impl MessageHandler<ServerOperation> for MessageUser {
new_message,
);
println!("User message received:",);
info!("User message received:");
user_message.print()
}
}
+1 -1
View File
@@ -15,6 +15,6 @@ impl MessageHandler<ServerOperation> for ParentMinSpeedHandler {
fn handle(&self, message: &mut Message, sender: Sender<ServerOperation>) {
let _ = sender;
let number = message.read_int32();
println!("Parent min speed: {}", number);
debug!("Parent min speed: {}", number);
}
}
+1 -1
View File
@@ -15,6 +15,6 @@ impl MessageHandler<ServerOperation> for ParentSpeedRatioHandler {
fn handle(&self, message: &mut Message, _sender: Sender<ServerOperation>) {
let number = message.read_int32();
println!("Parent min speed: {}", number);
debug!("Parent speed ratio: {}", number);
}
}
+1 -1
View File
@@ -14,6 +14,6 @@ impl MessageHandler<ServerOperation> for PrivilegedUsersHandler {
fn handle(&self, message: &mut Message, _sender: Sender<ServerOperation>) {
let number = message.read_int32();
println!("Number of privilaged users: {}", number);
debug!("Number of privileged users: {}", number);
}
}
+1 -1
View File
@@ -16,6 +16,6 @@ impl MessageHandler<ServerOperation> for WishListIntervalHandler {
fn handle(&self, message: &mut Message, _sender: Sender<ServerOperation>) {
let number = message.read_int32();
println!("Wishlist search interval: {} in seconds", number);
debug!("Wishlist search interval: {} in seconds", number);
}
}