Return success for object deletion if object does not exist

This commit is contained in:
Martin Raiber 2025-10-24 00:14:55 +02:00
parent dc25372f9e
commit 77883d612a
2 changed files with 16 additions and 14 deletions

View File

@ -2636,20 +2636,12 @@ void S3Handler::deleteObjects()
res = self->commit() ? 0 : 1;
}
if(res==0)
if(res==0 || res==ENOENT)
{
resp += fmt::format("\t<Deleted>\n"
"\t\t<Key>{}</Key>\n"
"\t</Deleted>\n", obj.key);
}
else if(res==ENOENT)
{
resp += fmt::format("\t<Error>\n"
"\t\t<Code>NoSuchKey</Code>\n"
"\t\t<Message>Object not found</Message>\n"
"\t\t<Key>{}</Key>\n"
"\t</Error>\n", obj.key);
}
else
{
resp += fmt::format("\t<Error>\n"
@ -2723,8 +2715,7 @@ void S3Handler::deleteObject(proxygen::HTTPMessage& headers)
{
XLOGF(INFO, "Removing object '{}' not found", self->keyInfo.key);
ResponseBuilder(self->downstream_)
.status(404, "Not found")
.body(s3errorXml(S3ErrorCode::NoSuchKey, "", self->fullKeyPath(), ""))
.status(204, "No Content")
.sendWithEOM();
}
else if(res!=0)
@ -2738,7 +2729,7 @@ void S3Handler::deleteObject(proxygen::HTTPMessage& headers)
else
{
ResponseBuilder(self->downstream_)
.status(200, "OK")
.status(204, "No Content")
.sendWithEOM();
}
self->finished_ = true;

View File

@ -96,8 +96,7 @@ def test_put_get_del_list(tmp_path: Path, hs5: Hs5Runner):
assert "ETag" in objs[0] and objs[0]["ETag"].strip('"').lower() == fdata_md5.lower()
s3_client.delete_object(Bucket=hs5.testbucketname(), Key="upload.txt")
with pytest.raises(ClientError):
s3_client.delete_object(Bucket=hs5.testbucketname(), Key="upload_nonexistent.txt")
s3_client.delete_object(Bucket=hs5.testbucketname(), Key="upload_nonexistent.txt")
with pytest.raises(ClientError):
s3_client.download_file(hs5.testbucketname(), "upload.txt", str(dl_path))
@ -566,3 +565,15 @@ def test_delete_multiple_objects(tmp_path: Path, hs5: Hs5Runner):
for i in range(5):
with pytest.raises(ClientError):
s3_client.head_object(Bucket='testbucket', Key=f'upload_{i}.txt')
objects_to_delete = [{'Key': f'nonexistent_{i}.txt'} for i in range(5)]
response = s3_client.delete_objects(
Bucket='testbucket',
Delete={
'Objects': objects_to_delete
}
)
# Check if all objects were reported as deleted (even if they didn't exist)
assert response['ResponseMetadata']['HTTPStatusCode'] == 200
assert 'Deleted' in response and len(response['Deleted']) == 5