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