diff --git a/src/s3handler.cpp b/src/s3handler.cpp
index ebe7c0c..0c2df3f 100644
--- a/src/s3handler.cpp
+++ b/src/s3handler.cpp
@@ -2636,20 +2636,12 @@ void S3Handler::deleteObjects()
res = self->commit() ? 0 : 1;
}
- if(res==0)
+ if(res==0 || res==ENOENT)
{
resp += fmt::format("\t\n"
"\t\t{}\n"
"\t\n", obj.key);
}
- else if(res==ENOENT)
- {
- resp += fmt::format("\t\n"
- "\t\tNoSuchKey\n"
- "\t\tObject not found\n"
- "\t\t{}\n"
- "\t\n", obj.key);
- }
else
{
resp += fmt::format("\t\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;
diff --git a/test/test_basic.py b/test/test_basic.py
index 9610cdc..04a013d 100644
--- a/test/test_basic.py
+++ b/test/test_basic.py
@@ -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