mirror of
https://github.com/deuxfleurs-org/garage.git
synced 2026-07-26 07:58:14 +00:00
refactor: reduce number of arguments by use struct
- create and use HandleInfo and DestInfo to reduce number of arguments lint message: warning: this function has too many arguments (9/7) help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.92.0/index.html#too_many_arguments
This commit is contained in:
+40
-29
@@ -148,14 +148,18 @@ pub async fn handle_copy(
|
||||
&& (was_multipart || checksum_algorithm != source_checksum_algorithm));
|
||||
|
||||
let res = if !must_recopy {
|
||||
let dest_info = DestInfo {
|
||||
key: dest_key,
|
||||
uuid: dest_uuid,
|
||||
object_meta: dest_object_meta,
|
||||
encryption: dest_encryption,
|
||||
};
|
||||
|
||||
// In most cases, we can just copy the metadata and link blocks of the
|
||||
// old object from the new object.
|
||||
handle_copy_metaonly(
|
||||
ctx,
|
||||
dest_key,
|
||||
dest_uuid,
|
||||
dest_object_meta,
|
||||
dest_encryption,
|
||||
dest_info,
|
||||
source_version,
|
||||
source_version_data,
|
||||
source_version_meta,
|
||||
@@ -177,12 +181,16 @@ pub async fn handle_copy(
|
||||
checksum_type: checksum_algorithm.map(|_| ChecksumType::FullObject),
|
||||
..dest_object_meta
|
||||
};
|
||||
|
||||
let dest_info = DestInfo {
|
||||
key: dest_key,
|
||||
uuid: dest_uuid,
|
||||
object_meta: dest_object_meta,
|
||||
encryption: dest_encryption,
|
||||
};
|
||||
handle_copy_reencrypt(
|
||||
ctx,
|
||||
dest_key,
|
||||
dest_uuid,
|
||||
dest_object_meta,
|
||||
dest_encryption,
|
||||
dest_info,
|
||||
source_version,
|
||||
source_version_data,
|
||||
source_encryption,
|
||||
@@ -209,12 +217,16 @@ pub async fn handle_copy(
|
||||
Ok(resp.body(string_body(xml))?)
|
||||
}
|
||||
|
||||
struct DestInfo<'a> {
|
||||
key: &'a str,
|
||||
uuid: Uuid,
|
||||
object_meta: ObjectVersionMetaInner,
|
||||
encryption: EncryptionParams,
|
||||
}
|
||||
|
||||
async fn handle_copy_metaonly(
|
||||
ctx: ReqCtx,
|
||||
dest_key: &str,
|
||||
dest_uuid: Uuid,
|
||||
dest_object_meta: ObjectVersionMetaInner,
|
||||
dest_encryption: EncryptionParams,
|
||||
dest_info: DestInfo<'_>,
|
||||
source_version: &ObjectVersion,
|
||||
source_version_data: &ObjectVersionData,
|
||||
source_version_meta: &ObjectVersionMeta,
|
||||
@@ -229,13 +241,13 @@ async fn handle_copy_metaonly(
|
||||
let new_timestamp = now_msec();
|
||||
|
||||
let new_meta = ObjectVersionMeta {
|
||||
encryption: dest_encryption.encrypt_meta(dest_object_meta)?,
|
||||
encryption: dest_info.encryption.encrypt_meta(dest_info.object_meta)?,
|
||||
size: source_version_meta.size,
|
||||
etag: source_version_meta.etag.clone(),
|
||||
};
|
||||
|
||||
let res = SaveStreamResult {
|
||||
version_uuid: dest_uuid,
|
||||
version_uuid: dest_info.uuid,
|
||||
version_timestamp: new_timestamp,
|
||||
etag: new_meta.etag.clone(),
|
||||
};
|
||||
@@ -247,7 +259,7 @@ async fn handle_copy_metaonly(
|
||||
// bytes is either plaintext before&after or encrypted with the
|
||||
// same keys, so it's ok to just copy it as is
|
||||
let dest_object_version = ObjectVersion {
|
||||
uuid: dest_uuid,
|
||||
uuid: dest_info.uuid,
|
||||
timestamp: new_timestamp,
|
||||
state: ObjectVersionState::Complete(ObjectVersionData::Inline(
|
||||
new_meta,
|
||||
@@ -256,7 +268,7 @@ async fn handle_copy_metaonly(
|
||||
};
|
||||
let dest_object = Object::new(
|
||||
dest_bucket_id,
|
||||
dest_key.to_string(),
|
||||
dest_info.key.to_string(),
|
||||
vec![dest_object_version],
|
||||
);
|
||||
garage.object_table.insert(&dest_object).await?;
|
||||
@@ -274,7 +286,7 @@ async fn handle_copy_metaonly(
|
||||
// This holds a reference to the object in the Version table
|
||||
// so that it won't be deleted, e.g. by repair_versions.
|
||||
let tmp_dest_object_version = ObjectVersion {
|
||||
uuid: dest_uuid,
|
||||
uuid: dest_info.uuid,
|
||||
timestamp: new_timestamp,
|
||||
state: ObjectVersionState::Uploading {
|
||||
encryption: new_meta.encryption.clone(),
|
||||
@@ -284,11 +296,13 @@ async fn handle_copy_metaonly(
|
||||
};
|
||||
let tmp_dest_object = Object::new(
|
||||
dest_bucket_id,
|
||||
dest_key.to_string(),
|
||||
dest_info.key.to_string(),
|
||||
vec![tmp_dest_object_version],
|
||||
);
|
||||
garage.object_table.insert(&tmp_dest_object).await?;
|
||||
|
||||
let dest_uuid = dest_info.uuid;
|
||||
|
||||
// Write version in the version table. Even with empty block list,
|
||||
// this means that the BlockRef entries linked to this version cannot be
|
||||
// marked as deleted (they are marked as deleted only if the Version
|
||||
@@ -297,7 +311,7 @@ async fn handle_copy_metaonly(
|
||||
dest_uuid,
|
||||
VersionBacklink::Object {
|
||||
bucket_id: dest_bucket_id,
|
||||
key: dest_key.to_string(),
|
||||
key: dest_info.key.to_string(),
|
||||
},
|
||||
false,
|
||||
);
|
||||
@@ -329,7 +343,7 @@ async fn handle_copy_metaonly(
|
||||
// with the stuff before, the block's reference counts could be decremented before
|
||||
// they are incremented again for the new version, leading to data being deleted.
|
||||
let dest_object_version = ObjectVersion {
|
||||
uuid: dest_uuid,
|
||||
uuid: dest_info.uuid,
|
||||
timestamp: new_timestamp,
|
||||
state: ObjectVersionState::Complete(ObjectVersionData::FirstBlock(
|
||||
new_meta,
|
||||
@@ -338,7 +352,7 @@ async fn handle_copy_metaonly(
|
||||
};
|
||||
let dest_object = Object::new(
|
||||
dest_bucket_id,
|
||||
dest_key.to_string(),
|
||||
dest_info.key.to_string(),
|
||||
vec![dest_object_version],
|
||||
);
|
||||
garage.object_table.insert(&dest_object).await?;
|
||||
@@ -350,10 +364,7 @@ async fn handle_copy_metaonly(
|
||||
|
||||
async fn handle_copy_reencrypt(
|
||||
ctx: ReqCtx,
|
||||
dest_key: &str,
|
||||
dest_uuid: Uuid,
|
||||
dest_object_meta: ObjectVersionMetaInner,
|
||||
dest_encryption: EncryptionParams,
|
||||
dest_info: DestInfo<'_>,
|
||||
source_version: &ObjectVersion,
|
||||
source_version_data: &ObjectVersionData,
|
||||
source_encryption: EncryptionParams,
|
||||
@@ -371,11 +382,11 @@ async fn handle_copy_reencrypt(
|
||||
|
||||
save_stream(
|
||||
&ctx,
|
||||
dest_uuid,
|
||||
dest_object_meta,
|
||||
dest_encryption,
|
||||
dest_info.uuid,
|
||||
dest_info.object_meta,
|
||||
dest_info.encryption,
|
||||
source_stream.map_err(|e| Error::from(GarageError::from(e))),
|
||||
&dest_key.to_string(),
|
||||
&dest_info.key.to_string(),
|
||||
checksum_mode,
|
||||
)
|
||||
.await
|
||||
|
||||
+81
-72
@@ -318,18 +318,22 @@ pub async fn handle_get_without_ctx(
|
||||
|
||||
let checksum_mode = checksum_mode(req);
|
||||
|
||||
let handle_get_info = HandleGetInfo {
|
||||
garage,
|
||||
version: last_v,
|
||||
version_data: last_v_data,
|
||||
version_meta: last_v_meta,
|
||||
encryption: enc,
|
||||
meta_inner: &headers,
|
||||
};
|
||||
|
||||
match (part_number, parse_range_header(req, last_v_meta.size)?) {
|
||||
(Some(_), Some(_)) => Err(Error::bad_request(
|
||||
"Cannot specify both partNumber and Range header",
|
||||
)),
|
||||
(Some(pn), None) => {
|
||||
handle_get_part(
|
||||
garage,
|
||||
last_v,
|
||||
last_v_data,
|
||||
last_v_meta,
|
||||
enc,
|
||||
&headers,
|
||||
handle_get_info,
|
||||
pn,
|
||||
ChecksumMode {
|
||||
// TODO: for multipart uploads, checksums of each part should be stored
|
||||
@@ -342,12 +346,7 @@ pub async fn handle_get_without_ctx(
|
||||
}
|
||||
(None, Some(range)) => {
|
||||
handle_get_range(
|
||||
garage,
|
||||
last_v,
|
||||
last_v_data,
|
||||
last_v_meta,
|
||||
enc,
|
||||
&headers,
|
||||
handle_get_info,
|
||||
range.start,
|
||||
range.start + range.length,
|
||||
ChecksumMode {
|
||||
@@ -359,19 +358,7 @@ pub async fn handle_get_without_ctx(
|
||||
)
|
||||
.await
|
||||
}
|
||||
(None, None) => {
|
||||
handle_get_full(
|
||||
garage,
|
||||
last_v,
|
||||
last_v_data,
|
||||
last_v_meta,
|
||||
enc,
|
||||
&headers,
|
||||
overrides,
|
||||
checksum_mode,
|
||||
)
|
||||
.await
|
||||
}
|
||||
(None, None) => handle_get_full(handle_get_info, overrides, checksum_mode).await,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -390,23 +377,37 @@ pub(crate) fn check_version_not_deleted(version: &Version) -> Result<(), Error>
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn handle_get_full(
|
||||
struct HandleGetInfo<'a> {
|
||||
garage: Arc<Garage>,
|
||||
version: &ObjectVersion,
|
||||
version_data: &ObjectVersionData,
|
||||
version_meta: &ObjectVersionMeta,
|
||||
version: &'a ObjectVersion,
|
||||
version_data: &'a ObjectVersionData,
|
||||
version_meta: &'a ObjectVersionMeta,
|
||||
encryption: EncryptionParams,
|
||||
meta_inner: &ObjectVersionMetaInner,
|
||||
meta_inner: &'a ObjectVersionMetaInner,
|
||||
}
|
||||
|
||||
async fn handle_get_full(
|
||||
info: HandleGetInfo<'_>,
|
||||
overrides: GetObjectOverrides,
|
||||
checksum_mode: ChecksumMode,
|
||||
) -> Result<Response<ResBody>, Error> {
|
||||
let mut resp_builder =
|
||||
object_headers(version, version_meta, meta_inner, encryption, checksum_mode)
|
||||
.header(CONTENT_LENGTH, format!("{}", version_meta.size))
|
||||
.status(StatusCode::OK);
|
||||
let mut resp_builder = object_headers(
|
||||
info.version,
|
||||
info.version_meta,
|
||||
info.meta_inner,
|
||||
info.encryption,
|
||||
checksum_mode,
|
||||
)
|
||||
.header(CONTENT_LENGTH, format!("{}", info.version_meta.size))
|
||||
.status(StatusCode::OK);
|
||||
getobject_override_headers(overrides, &mut resp_builder)?;
|
||||
|
||||
let stream = full_object_byte_stream(garage, version, version_data, encryption);
|
||||
let stream = full_object_byte_stream(
|
||||
info.garage,
|
||||
info.version,
|
||||
info.version_data,
|
||||
info.encryption,
|
||||
);
|
||||
|
||||
Ok(resp_builder.body(response_body_from_stream(stream))?)
|
||||
}
|
||||
@@ -486,12 +487,7 @@ pub fn full_object_byte_stream(
|
||||
}
|
||||
|
||||
async fn handle_get_range(
|
||||
garage: Arc<Garage>,
|
||||
version: &ObjectVersion,
|
||||
version_data: &ObjectVersionData,
|
||||
version_meta: &ObjectVersionMeta,
|
||||
encryption: EncryptionParams,
|
||||
meta_inner: &ObjectVersionMetaInner,
|
||||
info: HandleGetInfo<'_>,
|
||||
begin: u64,
|
||||
end: u64,
|
||||
checksum_mode: ChecksumMode,
|
||||
@@ -499,18 +495,24 @@ async fn handle_get_range(
|
||||
// Here we do not use getobject_override_headers because we don't
|
||||
// want to add any overridden headers (those should not be added
|
||||
// when returning PARTIAL_CONTENT)
|
||||
let resp_builder = object_headers(version, version_meta, meta_inner, encryption, checksum_mode)
|
||||
.header(CONTENT_LENGTH, format!("{}", end - begin))
|
||||
.header(
|
||||
CONTENT_RANGE,
|
||||
format!("bytes {}-{}/{}", begin, end - 1, version_meta.size),
|
||||
)
|
||||
.status(StatusCode::PARTIAL_CONTENT);
|
||||
let resp_builder = object_headers(
|
||||
info.version,
|
||||
info.version_meta,
|
||||
info.meta_inner,
|
||||
info.encryption,
|
||||
checksum_mode,
|
||||
)
|
||||
.header(CONTENT_LENGTH, format!("{}", end - begin))
|
||||
.header(
|
||||
CONTENT_RANGE,
|
||||
format!("bytes {}-{}/{}", begin, end - 1, info.version_meta.size),
|
||||
)
|
||||
.status(StatusCode::PARTIAL_CONTENT);
|
||||
|
||||
match &version_data {
|
||||
match &info.version_data {
|
||||
ObjectVersionData::DeleteMarker => unreachable!(),
|
||||
ObjectVersionData::Inline(_meta, bytes) => {
|
||||
let bytes = encryption.decrypt_blob(bytes)?;
|
||||
let bytes = info.encryption.decrypt_blob(bytes)?;
|
||||
if end as usize <= bytes.len() {
|
||||
let body = bytes_body(bytes[begin as usize..end as usize].to_vec().into());
|
||||
Ok(resp_builder.body(body)?)
|
||||
@@ -521,46 +523,47 @@ async fn handle_get_range(
|
||||
}
|
||||
}
|
||||
ObjectVersionData::FirstBlock(_meta, _first_block_hash) => {
|
||||
let version = garage
|
||||
let version = info
|
||||
.garage
|
||||
.version_table
|
||||
.get(&version.uuid, &EmptyKey)
|
||||
.get(&info.version.uuid, &EmptyKey)
|
||||
.await?
|
||||
.ok_or(Error::NoSuchKey)?;
|
||||
check_version_not_deleted(&version)?;
|
||||
let body =
|
||||
body_from_blocks_range(garage, encryption, version.blocks.items(), begin, end);
|
||||
let body = body_from_blocks_range(
|
||||
info.garage,
|
||||
info.encryption,
|
||||
version.blocks.items(),
|
||||
begin,
|
||||
end,
|
||||
);
|
||||
Ok(resp_builder.body(body)?)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
async fn handle_get_part(
|
||||
garage: Arc<Garage>,
|
||||
object_version: &ObjectVersion,
|
||||
version_data: &ObjectVersionData,
|
||||
version_meta: &ObjectVersionMeta,
|
||||
encryption: EncryptionParams,
|
||||
meta_inner: &ObjectVersionMetaInner,
|
||||
info: HandleGetInfo<'_>,
|
||||
part_number: u64,
|
||||
checksum_mode: ChecksumMode,
|
||||
) -> Result<Response<ResBody>, Error> {
|
||||
// Same as for get_range, no getobject_override_headers
|
||||
let resp_builder = object_headers(
|
||||
object_version,
|
||||
version_meta,
|
||||
meta_inner,
|
||||
encryption,
|
||||
info.version,
|
||||
info.version_meta,
|
||||
info.meta_inner,
|
||||
info.encryption,
|
||||
checksum_mode,
|
||||
)
|
||||
.status(StatusCode::PARTIAL_CONTENT);
|
||||
|
||||
match version_data {
|
||||
match info.version_data {
|
||||
ObjectVersionData::Inline(_, bytes) => {
|
||||
if part_number != 1 {
|
||||
return Err(Error::InvalidPart);
|
||||
}
|
||||
let bytes = encryption.decrypt_blob(bytes)?;
|
||||
assert_eq!(bytes.len() as u64, version_meta.size);
|
||||
let bytes = info.encryption.decrypt_blob(bytes)?;
|
||||
assert_eq!(bytes.len() as u64, info.version_meta.size);
|
||||
Ok(resp_builder
|
||||
.header(CONTENT_LENGTH, format!("{}", bytes.len()))
|
||||
.header(
|
||||
@@ -571,9 +574,10 @@ async fn handle_get_part(
|
||||
.body(bytes_body(bytes.into_owned().into()))?)
|
||||
}
|
||||
ObjectVersionData::FirstBlock(_, _) => {
|
||||
let version = garage
|
||||
let version = info
|
||||
.garage
|
||||
.version_table
|
||||
.get(&object_version.uuid, &EmptyKey)
|
||||
.get(&info.version.uuid, &EmptyKey)
|
||||
.await?
|
||||
.ok_or(Error::NoSuchKey)?;
|
||||
|
||||
@@ -582,14 +586,19 @@ async fn handle_get_part(
|
||||
let (begin, end) =
|
||||
calculate_part_bounds(&version, part_number).ok_or(Error::InvalidPart)?;
|
||||
|
||||
let body =
|
||||
body_from_blocks_range(garage, encryption, version.blocks.items(), begin, end);
|
||||
let body = body_from_blocks_range(
|
||||
info.garage,
|
||||
info.encryption,
|
||||
version.blocks.items(),
|
||||
begin,
|
||||
end,
|
||||
);
|
||||
|
||||
Ok(resp_builder
|
||||
.header(CONTENT_LENGTH, format!("{}", end - begin))
|
||||
.header(
|
||||
CONTENT_RANGE,
|
||||
format!("bytes {}-{}/{}", begin, end - 1, version_meta.size),
|
||||
format!("bytes {}-{}/{}", begin, end - 1, info.version_meta.size),
|
||||
)
|
||||
.header(X_AMZ_MP_PARTS_COUNT, format!("{}", version.n_parts()?))
|
||||
.body(body)?)
|
||||
|
||||
Reference in New Issue
Block a user