mirror of
https://github.com/szabodanika/microbin
synced 2024-11-13 20:57:06 +00:00
Merge pull request #277 from dvdsk/streaming_file_up_down
Awnser Range requests and stream files downloads
This commit is contained in:
commit
d3a7eaf072
2 changed files with 23 additions and 24 deletions
|
@ -70,6 +70,10 @@ pub fn expiration_to_timestamp(expiration: &str, timenow: i64) -> i64 {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// receives a file through http Post on url /upload/a-b-c with a, b and c
|
||||||
|
/// different animals. The client sends the post in response to a form.
|
||||||
|
// TODO: form field order might need to be changed. In my testing the attachment
|
||||||
|
// data is nestled between password encryption key etc <21-10-24, dvdsk>
|
||||||
pub async fn create(
|
pub async fn create(
|
||||||
data: web::Data<AppState>,
|
data: web::Data<AppState>,
|
||||||
mut payload: Multipart,
|
mut payload: Multipart,
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use std::fs::{self, File};
|
use std::fs::File;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use crate::args::ARGS;
|
use crate::args::ARGS;
|
||||||
|
@ -8,6 +8,7 @@ use crate::util::misc::remove_expired;
|
||||||
use crate::util::{animalnumbers::to_u64, misc::decrypt_file};
|
use crate::util::{animalnumbers::to_u64, misc::decrypt_file};
|
||||||
use crate::AppState;
|
use crate::AppState;
|
||||||
use actix_multipart::Multipart;
|
use actix_multipart::Multipart;
|
||||||
|
use actix_web::http::header;
|
||||||
use actix_web::{get, post, web, Error, HttpResponse};
|
use actix_web::{get, post, web, Error, HttpResponse};
|
||||||
|
|
||||||
#[post("/secure_file/{id}")]
|
#[post("/secure_file/{id}")]
|
||||||
|
@ -49,6 +50,8 @@ pub async fn post_secure_file(
|
||||||
pastas[index].id_as_animals()
|
pastas[index].id_as_animals()
|
||||||
))?;
|
))?;
|
||||||
|
|
||||||
|
// Not compatible with NamedFile from actix_files (it needs a File
|
||||||
|
// to work therefore secure files do not support streaming
|
||||||
let decrypted_data: Vec<u8> = decrypt_file(&password, &file)?;
|
let decrypted_data: Vec<u8> = decrypt_file(&password, &file)?;
|
||||||
|
|
||||||
// Set the content type based on the file extension
|
// Set the content type based on the file extension
|
||||||
|
@ -63,6 +66,7 @@ pub async fn post_secure_file(
|
||||||
"Content-Disposition",
|
"Content-Disposition",
|
||||||
format!("attachment; filename=\"{}\"", pasta_file.name()),
|
format!("attachment; filename=\"{}\"", pasta_file.name()),
|
||||||
))
|
))
|
||||||
|
// TODO: make streaming <21-10-24, dvdsk>
|
||||||
.body(decrypted_data);
|
.body(decrypted_data);
|
||||||
return Ok(response);
|
return Ok(response);
|
||||||
}
|
}
|
||||||
|
@ -72,8 +76,9 @@ pub async fn post_secure_file(
|
||||||
|
|
||||||
#[get("/file/{id}")]
|
#[get("/file/{id}")]
|
||||||
pub async fn get_file(
|
pub async fn get_file(
|
||||||
data: web::Data<AppState>,
|
request: actix_web::HttpRequest,
|
||||||
id: web::Path<String>,
|
id: web::Path<String>,
|
||||||
|
data: web::Data<AppState>,
|
||||||
) -> Result<HttpResponse, Error> {
|
) -> Result<HttpResponse, Error> {
|
||||||
// get access to the pasta collection
|
// get access to the pasta collection
|
||||||
let mut pastas = data.pastas.lock().unwrap();
|
let mut pastas = data.pastas.lock().unwrap();
|
||||||
|
@ -118,28 +123,18 @@ pub async fn get_file(
|
||||||
);
|
);
|
||||||
let file_path = PathBuf::from(file_path);
|
let file_path = PathBuf::from(file_path);
|
||||||
|
|
||||||
// Read the contents of the file into memory
|
// This will stream the file and set the content type based on the
|
||||||
// let mut file_content = Vec::new();
|
// file path
|
||||||
// let mut file = File::open(&file_path)?;
|
let file_reponse = actix_files::NamedFile::open(file_path)?;
|
||||||
// file.read_exact(&mut file_content)?;
|
let file_reponse = file_reponse.set_content_disposition(header::ContentDisposition {
|
||||||
|
disposition: header::DispositionType::Attachment,
|
||||||
let file_contents = fs::read(&file_path)?;
|
parameters: vec![header::DispositionParam::Filename(
|
||||||
|
pasta_file.name().to_string(),
|
||||||
// Set the content type based on the file extension
|
)],
|
||||||
let content_type = mime_guess::from_path(&file_path)
|
});
|
||||||
.first_or_octet_stream()
|
// This takes care of streaming/seeking using the Range
|
||||||
.to_string();
|
// header in the request.
|
||||||
|
return Ok(file_reponse.into_response(&request));
|
||||||
// Create an HttpResponse object with the file contents as the response body
|
|
||||||
let response = HttpResponse::Ok()
|
|
||||||
.content_type(content_type)
|
|
||||||
.append_header((
|
|
||||||
"Content-Disposition",
|
|
||||||
format!("attachment; filename=\"{}\"", pasta_file.name()),
|
|
||||||
))
|
|
||||||
.body(file_contents);
|
|
||||||
|
|
||||||
return Ok(response);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue