File upload working

This commit is contained in:
Cameron Cordes
2020-09-11 19:32:10 -04:00
parent fe23586059
commit 426c695b47
4 changed files with 123 additions and 0 deletions

View File

@@ -3,13 +3,17 @@ extern crate diesel;
extern crate rayon;
use actix_files::NamedFile;
use actix_multipart as mp;
use actix_web::web::{HttpRequest, HttpResponse, Json};
use actix_web::{get, post, web, App, HttpServer, Responder};
use chrono::{Duration, Utc};
use data::{AddFavoriteRequest, LoginRequest, ThumbnailRequest};
use futures::stream::StreamExt;
use jsonwebtoken::{encode, EncodingKey, Header};
use rayon::prelude::*;
use serde::Serialize;
use std::fs::File;
use std::io::prelude::*;
use std::path::{Path, PathBuf};
use crate::data::{secret_key, Claims, CreateAccountRequest, Token};
@@ -119,6 +123,56 @@ async fn get_image(
}
}
#[post("/image")]
async fn upload_image(_: Claims, mut payload: mp::Multipart) -> impl Responder {
let mut file_content: Vec<_> = Vec::new();
let mut file_name: Option<String> = None;
let mut file_path: Option<String> = None;
while let Some(Ok(mut part)) = payload.next().await {
if let Some(content_type) = part.content_disposition() {
println!("{:?}", content_type);
if let Some(filename) = content_type.get_filename() {
println!("Name: {:?}", filename);
file_name = Some(filename.to_string());
while let Some(Ok(data)) = part.next().await {
file_content.extend_from_slice(data.as_ref());
}
} else if content_type.get_name().map_or(false, |name| name == "path") {
while let Some(Ok(data)) = part.next().await {
if let Ok(path) = std::str::from_utf8(&data) {
file_path = Some(path.to_string())
}
}
}
}
}
let path = file_path.unwrap_or_else(|| dotenv::var("BASE_PATH").unwrap());
if !file_content.is_empty() {
let full_path = PathBuf::from(&path);
if let Some(mut full_path) = is_valid_path(full_path.to_str().unwrap_or("")) {
// TODO: Validate this file_name as is subject to path traversals which could lead to
// writing outside the base dir.
full_path = full_path.join(file_name.unwrap());
if !full_path.is_file() {
let mut file = File::create(full_path).unwrap();
file.write_all(&file_content).unwrap();
} else {
return HttpResponse::BadRequest().body("File already exists");
}
} else {
return HttpResponse::BadRequest().body("Path was not valid");
}
} else {
return HttpResponse::BadRequest().body("No file body read");
}
HttpResponse::Ok().finish()
}
#[post("/video/generate")]
async fn generate_video(_claims: Claims, body: web::Json<ThumbnailRequest>) -> impl Responder {
let filename = PathBuf::from(&body.path);
@@ -257,6 +311,7 @@ async fn main() -> std::io::Result<()> {
.service(login)
.service(list_photos)
.service(get_image)
.service(upload_image)
.service(generate_video)
.service(stream_video)
.service(get_video_part)