Better req handling & reading
* Fixed old typos * Fixed problem caused by empty data folder * Included newlines to requests to separate individual messages
This commit is contained in:
parent
44ef3d8db1
commit
530e33867b
@ -29,18 +29,27 @@ pub async fn connect(addr: String, fileroot: PathBuf) -> Result<(), Box<dyn std:
|
|||||||
buf.clear();
|
buf.clear();
|
||||||
|
|
||||||
// ACK buffersize
|
// ACK buffersize
|
||||||
writer.write_all(b"ACK").await.unwrap();
|
writer.write_all(b"ACK\n").await.unwrap();
|
||||||
writer.flush().await?;
|
writer.flush().await?;
|
||||||
|
|
||||||
// Receive file amount
|
// Receive file amount (or termination request if the server does not have any files available)
|
||||||
let _bytes_read = reader.read_buf(&mut buf).await?;
|
let file_amount: usize;
|
||||||
let file_amount = String::from_utf8(buf.clone())?.parse::<usize>()?;
|
let _bytes_read = reader.read_until(b'\n', &mut buf).await?;
|
||||||
println!("[+] Total of {} files available", file_amount);
|
let msg = String::from_utf8(buf.clone())?;
|
||||||
buf.clear();
|
if msg.trim() == "FIN" {
|
||||||
|
println!("[-] Server does not have any files available, closing connection");
|
||||||
|
writer.write_all(b"FIN\n").await?;
|
||||||
|
writer.flush().await?;
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
file_amount = msg.trim().parse::<usize>()?;
|
||||||
|
println!("[+] Total of {} files available", file_amount);
|
||||||
|
buf.clear();
|
||||||
|
|
||||||
// ACK file amount
|
// ACK file amount
|
||||||
writer.write_all(b"ACK").await?;
|
writer.write_all(b"ACK\n").await?;
|
||||||
writer.flush().await?;
|
writer.flush().await?;
|
||||||
|
}
|
||||||
|
|
||||||
// Receive file metadata
|
// Receive file metadata
|
||||||
println!("[+] Receiving file metadata");
|
println!("[+] Receiving file metadata");
|
||||||
@ -64,7 +73,8 @@ pub async fn connect(addr: String, fileroot: PathBuf) -> Result<(), Box<dyn std:
|
|||||||
println!("[+] Requesting files individually");
|
println!("[+] Requesting files individually");
|
||||||
for file in &metadata {
|
for file in &metadata {
|
||||||
println!("[INFO] Current request: [{:?}]", file);
|
println!("[INFO] Current request: [{:?}]", file);
|
||||||
writer.write_all(file.0.as_bytes()).await?;
|
let msg = file.0.to_string() + "\n";
|
||||||
|
writer.write_all(msg.as_bytes()).await?;
|
||||||
writer.flush().await?;
|
writer.flush().await?;
|
||||||
|
|
||||||
// Create file locally
|
// Create file locally
|
||||||
@ -112,7 +122,7 @@ pub async fn connect(addr: String, fileroot: PathBuf) -> Result<(), Box<dyn std:
|
|||||||
}
|
}
|
||||||
|
|
||||||
// ACK file
|
// ACK file
|
||||||
writer.write_all(b"ACK").await?;
|
writer.write_all(b"ACK\n").await?;
|
||||||
writer.flush().await?;
|
writer.flush().await?;
|
||||||
println!(
|
println!(
|
||||||
"[+] Successfully wrote {} bytes to {:#?}\n",
|
"[+] Successfully wrote {} bytes to {:#?}\n",
|
||||||
@ -121,7 +131,7 @@ pub async fn connect(addr: String, fileroot: PathBuf) -> Result<(), Box<dyn std:
|
|||||||
}
|
}
|
||||||
|
|
||||||
println!("[+] All files finished, requesting connection termination");
|
println!("[+] All files finished, requesting connection termination");
|
||||||
writer.write_all(b"FIN").await?;
|
writer.write_all(b"FIN\n").await?;
|
||||||
writer.flush().await?;
|
writer.flush().await?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,7 +9,7 @@ use std::{
|
|||||||
use tokio::{
|
use tokio::{
|
||||||
self,
|
self,
|
||||||
fs::File,
|
fs::File,
|
||||||
io::{AsyncReadExt, AsyncWriteExt, BufReader, BufWriter},
|
io::{AsyncBufReadExt, AsyncReadExt, AsyncWriteExt, BufReader, BufWriter},
|
||||||
net::TcpListener,
|
net::TcpListener,
|
||||||
time::timeout,
|
time::timeout,
|
||||||
};
|
};
|
||||||
@ -36,13 +36,16 @@ pub async fn listen(
|
|||||||
match timeout(Duration::from_secs(timeout_duration), listener.accept()).await {
|
match timeout(Duration::from_secs(timeout_duration), listener.accept()).await {
|
||||||
Ok(n) => n?,
|
Ok(n) => n?,
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
println!("\nConnection timed out after {} seconds", timeout_duration);
|
println!(
|
||||||
|
"\n[-] Connection timed out after {} seconds",
|
||||||
|
timeout_duration
|
||||||
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
println!("\n[+] New client: {}", addr);
|
println!("\n[+] New client: {}", addr);
|
||||||
|
|
||||||
tokio::spawn(async move {
|
let task = tokio::spawn(async move {
|
||||||
let (reader, writer) = socket.split();
|
let (reader, writer) = socket.split();
|
||||||
let mut reader = BufReader::new(reader);
|
let mut reader = BufReader::new(reader);
|
||||||
let mut writer = BufWriter::new(writer);
|
let mut writer = BufWriter::new(writer);
|
||||||
@ -54,23 +57,49 @@ pub async fn listen(
|
|||||||
writer.flush().await?;
|
writer.flush().await?;
|
||||||
|
|
||||||
// Read ACK
|
// Read ACK
|
||||||
let _bytes_read = reader.read_buf(&mut vec_buf).await?;
|
//let _bytes_read = reader.read_buf(&mut vec_buf).await?;
|
||||||
if String::from_utf8(vec_buf.clone())? != "ACK" {
|
let _bytes_read = reader.read_until(b'\n', &mut vec_buf).await?;
|
||||||
panic!("ACK not received (buffersize)");
|
let msg = String::from_utf8(vec_buf.clone())?;
|
||||||
|
if msg.trim() != "ACK" {
|
||||||
|
panic!("ACK not received (buffersize), instead got {}", msg);
|
||||||
} else {
|
} else {
|
||||||
vec_buf.clear();
|
vec_buf.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
let (metadata_list, file_amount) = get_metadata().await?;
|
let (metadata_list, file_amount) = get_metadata(alt_fileroot.clone()).await?;
|
||||||
|
if file_amount == 0 {
|
||||||
|
println!(
|
||||||
|
"[-] No files available inside fileroot {:#?}, shutting down",
|
||||||
|
alt_fileroot
|
||||||
|
);
|
||||||
|
// No files available, request connection termination
|
||||||
|
writer.write_all(b"FIN\n").await?;
|
||||||
|
writer.flush().await?;
|
||||||
|
|
||||||
// Send file amount
|
// Read FIN
|
||||||
writer.write_all(file_amount.to_string().as_bytes()).await?;
|
//let _bytes_read = reader.read_buf(&mut vec_buf).await?;
|
||||||
writer.flush().await?;
|
let _bytes_read = reader.read_until(b'\n', &mut vec_buf).await?;
|
||||||
|
let msg = String::from_utf8(vec_buf.clone())?;
|
||||||
|
if msg.trim() != "FIN" {
|
||||||
|
panic!("ACK not received (server-side-termination)");
|
||||||
|
} else {
|
||||||
|
// Empty error as error's reason is already logged with println
|
||||||
|
let e: Box<dyn std::error::Error + Send + Sync> = "".into();
|
||||||
|
return Err::<(), Box<dyn std::error::Error + Send + Sync>>(e);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Send file amount
|
||||||
|
let msg = file_amount.to_string() + "\n";
|
||||||
|
writer.write_all(msg.as_bytes()).await?;
|
||||||
|
writer.flush().await?;
|
||||||
|
}
|
||||||
|
|
||||||
// Read ACK
|
// Read ACK
|
||||||
let _bytes_read = reader.read_buf(&mut vec_buf).await?;
|
//let _bytes_read = reader.read_buf(&mut vec_buf).await?;
|
||||||
if String::from_utf8(vec_buf.clone())? != "ACK" {
|
let _bytes_read = reader.read_until(b'\n', &mut vec_buf).await?;
|
||||||
panic!("ACK not received (amount)");
|
let msg = String::from_utf8(vec_buf.clone())?;
|
||||||
|
if msg.trim() != "ACK" {
|
||||||
|
panic!("ACK not received (amount), instead got {}", msg);
|
||||||
} else {
|
} else {
|
||||||
vec_buf.clear();
|
vec_buf.clear();
|
||||||
}
|
}
|
||||||
@ -86,22 +115,24 @@ pub async fn listen(
|
|||||||
// Handle file request(s)
|
// Handle file request(s)
|
||||||
println!("[+] Ready to serve files");
|
println!("[+] Ready to serve files");
|
||||||
loop {
|
loop {
|
||||||
let bytes_read = reader.read_buf(&mut vec_buf).await?;
|
//let bytes_read = reader.read_buf(&mut vec_buf).await?;
|
||||||
|
let bytes_read = reader.read_until(b'\n', &mut vec_buf).await?;
|
||||||
|
|
||||||
if bytes_read == 0 {
|
if bytes_read == 0 {
|
||||||
println!("File request never received");
|
println!("[-] File request never received");
|
||||||
|
vec_buf.clear();
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
let msg = String::from_utf8(vec_buf.clone())?;
|
let msg = String::from_utf8(vec_buf.clone())?;
|
||||||
vec_buf.clear();
|
vec_buf.clear();
|
||||||
|
|
||||||
if msg == "FIN" {
|
if msg.trim() == "FIN" {
|
||||||
println!("[+] FIN received, terminating individual connection...");
|
println!("[+] FIN received, terminating individual connection...");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut input_path = alt_fileroot.clone();
|
let mut input_path = alt_fileroot.clone();
|
||||||
input_path.push(msg);
|
input_path.push(msg.trim());
|
||||||
|
|
||||||
println!("\n[+] File requested: {:#?}", input_path);
|
println!("\n[+] File requested: {:#?}", input_path);
|
||||||
let mut file = File::open(input_path.clone()).await?;
|
let mut file = File::open(input_path.clone()).await?;
|
||||||
@ -122,9 +153,11 @@ pub async fn listen(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Read ACK
|
// Read ACK
|
||||||
let _bytes_read = reader.read_buf(&mut vec_buf).await?;
|
//let _bytes_read = reader.read_buf(&mut vec_buf).await?;
|
||||||
if String::from_utf8(vec_buf.clone())? != "ACK" {
|
let _bytes_read = reader.read_until(b'\n', &mut vec_buf).await?;
|
||||||
panic!("ACK not received (amount)");
|
let msg = String::from_utf8(vec_buf.clone())?;
|
||||||
|
if msg.trim() != "ACK" {
|
||||||
|
panic!("ACK not received (file), instead got {}", msg);
|
||||||
} else {
|
} else {
|
||||||
println!("[+] File transfer successfully done");
|
println!("[+] File transfer successfully done");
|
||||||
vec_buf.clear();
|
vec_buf.clear();
|
||||||
@ -133,15 +166,21 @@ pub async fn listen(
|
|||||||
|
|
||||||
Ok::<(), Box<dyn std::error::Error + Send + Sync>>(())
|
Ok::<(), Box<dyn std::error::Error + Send + Sync>>(())
|
||||||
});
|
});
|
||||||
|
|
||||||
|
match task.await? {
|
||||||
|
Ok(_) => continue,
|
||||||
|
Err(_) => break,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
async fn get_metadata(
|
async fn get_metadata(
|
||||||
|
fileroot: PathBuf,
|
||||||
) -> Result<(Vec<(String, u64)>, usize), Box<dyn std::error::Error + Send + Sync>> {
|
) -> Result<(Vec<(String, u64)>, usize), Box<dyn std::error::Error + Send + Sync>> {
|
||||||
let mut metadata = Vec::<(String, u64)>::new();
|
let mut metadata = Vec::<(String, u64)>::new();
|
||||||
let paths = read_dir("./data")?;
|
let paths = read_dir(fileroot)?;
|
||||||
|
|
||||||
for filename in paths {
|
for filename in paths {
|
||||||
let filepath = filename?.path().display().to_string();
|
let filepath = filename?.path().display().to_string();
|
||||||
|
Loading…
Reference in New Issue
Block a user