fix: harden compression boundaries and target search
This commit is contained in:
@@ -293,7 +293,11 @@ async fn compress_json(
|
||||
} else {
|
||||
(saved_bytes as f64) * 100.0 / (original_size as f64)
|
||||
};
|
||||
let skip_charge = req.compression_rate == Some(100);
|
||||
let skip_charge = req.compression_rate == Some(100)
|
||||
&& req.target_size_bytes.is_none()
|
||||
&& format_in == format_out
|
||||
&& req.max_width.is_none()
|
||||
&& req.max_height.is_none();
|
||||
let charge_units = !skip_charge && compressed_size < original_size;
|
||||
|
||||
if charge_units {
|
||||
@@ -660,7 +664,11 @@ async fn compress_direct(
|
||||
} else {
|
||||
(saved_bytes as f64) * 100.0 / (original_size as f64)
|
||||
};
|
||||
let skip_charge = req.compression_rate == Some(100);
|
||||
let skip_charge = req.compression_rate == Some(100)
|
||||
&& req.target_size_bytes.is_none()
|
||||
&& format_in == format_out
|
||||
&& req.max_width.is_none()
|
||||
&& req.max_height.is_none();
|
||||
let charge_units = !skip_charge && compressed_size < original_size;
|
||||
|
||||
if !state.config.storage_type.eq_ignore_ascii_case("local") {
|
||||
@@ -893,6 +901,12 @@ async fn parse_single_file_request(multipart: &mut Multipart) -> Result<Compress
|
||||
})? {
|
||||
let name = field.name().unwrap_or("").to_string();
|
||||
if name == "file" {
|
||||
if file_bytes.is_some() {
|
||||
return Err(AppError::new(
|
||||
ErrorCode::InvalidRequest,
|
||||
"单文件压缩接口仅允许一个 file 字段",
|
||||
));
|
||||
}
|
||||
file_name = Some(field.file_name().unwrap_or("upload").to_string());
|
||||
let bytes = field.bytes().await.map_err(|err| {
|
||||
AppError::new(ErrorCode::InvalidRequest, "读取文件失败").with_source(err)
|
||||
@@ -924,17 +938,13 @@ async fn parse_single_file_request(multipart: &mut Multipart) -> Result<Compress
|
||||
"max_width" => {
|
||||
let v = text.trim();
|
||||
if !v.is_empty() {
|
||||
max_width = Some(v.parse::<u32>().map_err(|_| {
|
||||
AppError::new(ErrorCode::InvalidRequest, "max_width 格式错误")
|
||||
})?);
|
||||
max_width = Some(compress::parse_dimension(v, "max_width")?);
|
||||
}
|
||||
}
|
||||
"max_height" => {
|
||||
let v = text.trim();
|
||||
if !v.is_empty() {
|
||||
max_height = Some(v.parse::<u32>().map_err(|_| {
|
||||
AppError::new(ErrorCode::InvalidRequest, "max_height 格式错误")
|
||||
})?);
|
||||
max_height = Some(compress::parse_dimension(v, "max_height")?);
|
||||
}
|
||||
}
|
||||
"preserve_metadata" => {
|
||||
@@ -971,6 +981,13 @@ async fn parse_single_file_request(multipart: &mut Multipart) -> Result<Compress
|
||||
file_bytes.ok_or_else(|| AppError::new(ErrorCode::InvalidRequest, "缺少 file"))?;
|
||||
let file_name = file_name.unwrap_or_else(|| "upload".to_string());
|
||||
|
||||
if compression_rate.is_some() && target_size_bytes.is_some() {
|
||||
return Err(AppError::new(
|
||||
ErrorCode::InvalidRequest,
|
||||
"compression_rate 与 target_size_bytes 不能同时指定",
|
||||
));
|
||||
}
|
||||
|
||||
Ok(CompressRequest {
|
||||
file_name,
|
||||
file_bytes,
|
||||
|
||||
@@ -530,13 +530,13 @@ async fn parse_batch_request(
|
||||
"max_width" => {
|
||||
let v = text.trim();
|
||||
if !v.is_empty() {
|
||||
opts.max_width = Some(match v.parse::<u32>() {
|
||||
opts.max_width = Some(match compress::parse_dimension(v, "max_width") {
|
||||
Ok(n) => n,
|
||||
Err(_) => {
|
||||
cleanup_file_paths(&files).await;
|
||||
return Err(AppError::new(
|
||||
ErrorCode::InvalidRequest,
|
||||
"max_width 格式错误",
|
||||
"max_width 必须为大于 0 的整数",
|
||||
));
|
||||
}
|
||||
});
|
||||
@@ -545,13 +545,13 @@ async fn parse_batch_request(
|
||||
"max_height" => {
|
||||
let v = text.trim();
|
||||
if !v.is_empty() {
|
||||
opts.max_height = Some(match v.parse::<u32>() {
|
||||
opts.max_height = Some(match compress::parse_dimension(v, "max_height") {
|
||||
Ok(n) => n,
|
||||
Err(_) => {
|
||||
cleanup_file_paths(&files).await;
|
||||
return Err(AppError::new(
|
||||
ErrorCode::InvalidRequest,
|
||||
"max_height 格式错误",
|
||||
"max_height 必须为大于 0 的整数",
|
||||
));
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user