the code I have written isn’t very idiomatic or efficient. I am still new to Rust so I am learning things. I am amazed that I can write a pastebin in just 60 lines of Rust code. It’s awesome. I am thinking about deploying it on my server.
any suggestions would be appreciated :)
code:
use axum::{extract::Path, routing::get, Router};
use std::fs::{read_to_string, File};
use std::io::prelude::*;
use std::net::{TcpListener, TcpStream};
use std::str;
const MAX_FILE_SIZE: usize = 1024 * 1024 * 10;
static mut FILE_COUNT: usize = 0;
fn handle_client(stream: &mut TcpStream) -> std::io::Result<()> {
let mut buf = vec![0; 1024];
unsafe {
let file_name = FILE_COUNT.to_string();
FILE_COUNT += 1;
let mut file = File::create(file_name)?;
let mut size: usize = 0;
loop {
let read_data = stream.read(&mut buf).unwrap();
size += read_data;
if size >= MAX_FILE_SIZE {
return Ok(())
}
if read_data == 0 {
return Ok(());
}
stream.write_all(&buf[..read_data]).unwrap();
write!(file, "{}", str::from_utf8(&buf[..read_data]).unwrap())?;
}
}
}
async fn upload_handle() -> std::io::Result<()> {
let listener = TcpListener::bind("127.0.0.1:8080")?;
// accept connections and process them serially
for stream in listener.incoming() {
handle_client(&mut stream?)?;
}
Ok(())
}
async fn handle(Path(id): Path<String>) -> String {
if let Ok(content) = read_to_string(id) {
return content;
}
return String::from("ERROR: File not found");
}
#[tokio::main]
async fn main() {
tokio::spawn(upload_handle());
let app = Router::new()
.route("/", get(|| async { "Paste something in pastebin!" }))
.route("/{id}", get(handle));
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
axum::serve(listener, app).await.unwrap();
}
Atomics are not free, and there is no need to make access to FILE_COUNT thread-safe in this case. Though of course this code has many other issues.