|
|
|
@ -32,16 +32,15 @@ pub(crate) async fn parse_multipart(
|
|
|
|
|
let mut password = None;
|
|
|
|
|
let mut size = 0;
|
|
|
|
|
|
|
|
|
|
while let Ok(Some(field)) = payload.try_next().await {
|
|
|
|
|
let name = get_field_name(&field)?;
|
|
|
|
|
let name = name.as_str();
|
|
|
|
|
match name {
|
|
|
|
|
while let Ok(Some(mut field)) = payload.try_next().await {
|
|
|
|
|
let name = get_field_name(&field)?.to_owned();
|
|
|
|
|
match name.as_str() {
|
|
|
|
|
"keep_for" => {
|
|
|
|
|
keep_for_seconds = Some(parse_string(name, field).await?);
|
|
|
|
|
keep_for_seconds = Some(parse_string(&name, &mut field).await?);
|
|
|
|
|
}
|
|
|
|
|
"file" => {
|
|
|
|
|
let (mime, uploaded_name) = get_file_metadata(&field);
|
|
|
|
|
if uploaded_name == None || uploaded_name.as_deref() == Some("") {
|
|
|
|
|
if uploaded_name.is_none() || uploaded_name.as_deref() == Some("") {
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
original_name = uploaded_name;
|
|
|
|
@ -62,10 +61,10 @@ pub(crate) async fn parse_multipart(
|
|
|
|
|
content_type = Some(get_content_type(&first_bytes));
|
|
|
|
|
}
|
|
|
|
|
"delete_on_download" => {
|
|
|
|
|
delete_on_download = parse_string(name, field).await? != "false";
|
|
|
|
|
delete_on_download = parse_string(&name, &mut field).await? != "false";
|
|
|
|
|
}
|
|
|
|
|
"password" => {
|
|
|
|
|
password = Some(parse_string(name, field).await?);
|
|
|
|
|
password = Some(parse_string(&name, &mut field).await?);
|
|
|
|
|
}
|
|
|
|
|
_ => {}
|
|
|
|
|
};
|
|
|
|
@ -77,8 +76,7 @@ pub(crate) async fn parse_multipart(
|
|
|
|
|
.map(|k| k.parse())
|
|
|
|
|
.transpose()
|
|
|
|
|
.map_err(|e| error::ErrorBadRequest(format!("field keep_for is not a number: {e}")))?
|
|
|
|
|
.map(Duration::seconds)
|
|
|
|
|
.unwrap_or(DEFAULT_UPLOAD_DURATION);
|
|
|
|
|
.map_or(DEFAULT_UPLOAD_DURATION, Duration::seconds);
|
|
|
|
|
let valid_till = OffsetDateTime::now_utc() + keep_for;
|
|
|
|
|
|
|
|
|
|
let upload_config = UploadConfig {
|
|
|
|
@ -88,7 +86,7 @@ pub(crate) async fn parse_multipart(
|
|
|
|
|
delete_on_download,
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
check_requirements(&upload_config, size, password, &keep_for, config)?;
|
|
|
|
|
check_requirements(&upload_config, size, &password, &keep_for, config)?;
|
|
|
|
|
|
|
|
|
|
Ok(upload_config)
|
|
|
|
|
}
|
|
|
|
@ -96,7 +94,7 @@ pub(crate) async fn parse_multipart(
|
|
|
|
|
fn check_requirements(
|
|
|
|
|
upload_config: &UploadConfig,
|
|
|
|
|
size: u64,
|
|
|
|
|
password: Option<String>,
|
|
|
|
|
password: &Option<String>,
|
|
|
|
|
keep_for: &Duration,
|
|
|
|
|
config: &config::Config,
|
|
|
|
|
) -> Result<(), error::Error> {
|
|
|
|
@ -127,21 +125,23 @@ fn check_requirements(
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn get_field_name(field: &Field) -> Result<String, error::Error> {
|
|
|
|
|
fn get_field_name(field: &Field) -> Result<&str, error::Error> {
|
|
|
|
|
Ok(field
|
|
|
|
|
.content_disposition()
|
|
|
|
|
.get_name()
|
|
|
|
|
.map(|s| s.to_owned())
|
|
|
|
|
.ok_or(error::ParseError::Incomplete)?)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async fn parse_string(name: &str, field: actix_multipart::Field) -> Result<String, error::Error> {
|
|
|
|
|
async fn parse_string(
|
|
|
|
|
name: &str,
|
|
|
|
|
field: &mut actix_multipart::Field,
|
|
|
|
|
) -> Result<String, error::Error> {
|
|
|
|
|
let data = read_content(field).await?;
|
|
|
|
|
String::from_utf8(data)
|
|
|
|
|
.map_err(|_| error::ErrorBadRequest(format!("could not parse field {name} as utf-8")))
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
async fn read_content(mut field: actix_multipart::Field) -> Result<Vec<u8>, error::Error> {
|
|
|
|
|
async fn read_content(field: &mut actix_multipart::Field) -> Result<Vec<u8>, error::Error> {
|
|
|
|
|
let mut data = Vec::new();
|
|
|
|
|
while let Some(chunk) = field.try_next().await.map_err(error::ErrorBadRequest)? {
|
|
|
|
|
data.extend(chunk);
|
|
|
|
|