Looking for some variants how to upload file and meta-data in one request, I find out that I can use multipart/form-data content-type.
In rust rocket documentation, I found example where TempFile
was used, but it's saved without any obvious file extension. Just like data-file.
Then I created a route and trying to get a file name (full, with extension), and then I saw .name
and .raw_name
methods.
First returns pure name without extension and the second returns &FileName
, that I can perform to str (but it's equivalent to .name()
).
Then I saw dangerous_unsafe_unsanitized_raw()
method in documentation, and I don't get it, should I use it or no?
Maybe there is a more proper way how to upload files? (Like with Data<'_>
but there are no methods to use with filename at all, and I should know proper file size.. ) or I shouldn't save files with obvious extension..?
Any suggestions, please?
Update:
#[post("/upload", data = <file>)]
async fn upload_route(data: TempFile<'_>) -> (Status, Value) {
//I need to save file (ex. test.zip), somehow. For properly saving i need:
//1) Filename (-> test)
//2) File extension (-> .zip)
let pure_name = file.name().unwrap(); //returns "test", but not .zip
let file_name = file.raw_name().unwrap(); //returns &FileName("test.zip")
let file_name = file_name.as_str().unwrap(); //returns "test" (I expected "test.zip"!)
let real_full_name = file.raw_name().unwrap().dangerous_unsage_unsanitized_raw().as_str();
data.persist_to("temp/dir/to/<filename>").await?;
(Status::Ok, Value::String(String::from("File successfully saved")))
}
Looking at the source code file.name.unwrap()
is equivalent to file.raw_name().unwrap().as_str().unwrap()
. And the FileName::as_str
docs do state that they strip the extension as part of the process for sanitizing the name.
You can get a safe name with as_str
and use the content type to get a valid extension:
fn get_name (file: &TempFile<'_>) -> Option<String> {
format!("{}.{}", file.name()?, file.content_type()?.extension()?)
}