diff options
Diffstat (limited to 'src/api/s3_put.rs')
-rw-r--r-- | src/api/s3_put.rs | 21 |
1 files changed, 17 insertions, 4 deletions
diff --git a/src/api/s3_put.rs b/src/api/s3_put.rs index d7ee5893..421b94a1 100644 --- a/src/api/s3_put.rs +++ b/src/api/s3_put.rs @@ -370,12 +370,15 @@ pub async fn handle_put_part( let key = key.to_string(); let mut chunker = BodyChunker::new(req.into_body(), garage.config.block_size); - let (object, first_block) = - futures::try_join!(garage.object_table.get(&bucket_id, &key), chunker.next(),)?; + let (object, version, first_block) = futures::try_join!( + garage.object_table.get(&bucket_id, &key), + garage.version_table.get(&version_uuid, &EmptyKey), + chunker.next() + )?; // Check object is valid and multipart block can be accepted - let first_block = first_block.ok_or_else(|| Error::BadRequest("Empty body".to_string()))?; - let object = object.ok_or_else(|| Error::BadRequest("Object not found".to_string()))?; + let first_block = first_block.ok_or_bad_request("Empty body")?; + let object = object.ok_or_bad_request("Object not found")?; if !object .versions() @@ -385,6 +388,16 @@ pub async fn handle_put_part( return Err(Error::NoSuchUpload); } + // Check part hasn't already been uploaded + if let Some(v) = version { + if v.has_part_number(part_number) { + return Err(Error::BadRequest(format!( + "Part number {} has already been uploaded", + part_number + ))); + } + } + // Copy block to store let version = Version::new(version_uuid, bucket_id, key, false); let first_block_hash = blake2sum(&first_block[..]); |