Skip to content

Instantly share code, notes, and snippets.

@uint0
Created July 14, 2021 12:39
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save uint0/43a821ee59271328361239293aea1be2 to your computer and use it in GitHub Desktop.
Save uint0/43a821ee59271328361239293aea1be2 to your computer and use it in GitHub Desktop.
Rust File Upload

Rust File Upload

A simple file upload server I wrote to learn rust.

[package]
name = "file-receiver"
version = "0.1.0"
authors = ["uint0 <uint0@zeta-mechanic>"]
edition = "2018"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
actix-web = "3"
actix-multipart="0.3"
futures = "0.3"
human_id = "0.1"
use std::fs;
use std::io::Write;
use std::time::{SystemTime, UNIX_EPOCH};
use futures::StreamExt;
use human_id;
use actix_web::{get, post, web, Error, App, HttpResponse, HttpServer, Responder};
use actix_multipart::Multipart;
#[get("/")]
async fn upload_ui() -> impl Responder {
HttpResponse::Ok()
.header("Content-Type", "text/html")
.body(r#"
<form action="/upload" method="post" enctype="multipart/form-data">
<input type="file" name="file">
<input type="submit">
</form>
"#)
}
#[post("/upload")]
async fn upload(req: web::HttpRequest, bytes: web::Payload) -> Result<HttpResponse, Error> {
let mut multipart = Multipart::new(
req.headers(),
bytes
);
let name_id = human_id::id("", true);
let name_time = SystemTime::now()
.duration_since(UNIX_EPOCH)
.expect("Give me your time machine")
.as_micros();
let uploaded_name = format!("{}-{:?}", name_id, name_time);
let mut upload_file = fs::File::create(format!("uploads/{}", uploaded_name))?;
while let Some(chunk) = multipart.next().await {
let mut chunk = chunk?;
for chunk_content in chunk.next().await {
let content = chunk_content.ok().unwrap_or_default();
upload_file.write(&content)?;
}
}
Ok(HttpResponse::Ok().content_type("text/plain").body(uploaded_name))
}
#[actix_web::main]
async fn main() -> std::io::Result<()> {
fs::create_dir_all("./uploads")?;
HttpServer::new(|| {
App::new()
.service(upload_ui)
.service(upload)
})
.bind("127.0.0.1:8080")?
.run()
.await
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment