* Fix #3996

* Don't delete any message when duplicate handles
This commit is contained in:
Grégoire Charvet 黑瓜 2021-07-07 08:59:16 +01:00 committed by GitHub
parent 05cdcbcedc
commit 00be464c05
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 47 additions and 4 deletions

View File

@ -17,6 +17,7 @@ from .exceptions import (
InvalidAttributeName,
MessageNotInflight,
ReceiptHandleIsInvalid,
BatchEntryIdsNotDistinct,
)
from .models import sqs_backends
from .utils import parse_message_attributes, extract_input_message_attributes
@ -330,7 +331,8 @@ class SQSResponse(BaseResponse):
"""
queue_name = self._get_queue_name()
message_ids = []
receipts = []
for index in range(1, 11):
# Loop through looking for messages
receipt_key = "DeleteMessageBatchRequestEntry.{0}.ReceiptHandle".format(
@ -341,12 +343,25 @@ class SQSResponse(BaseResponse):
# Found all messages
break
self.sqs_backend.delete_message(queue_name, receipt_handle[0])
message_user_id_key = "DeleteMessageBatchRequestEntry.{0}.Id".format(index)
message_user_id = self.querystring.get(message_user_id_key)[0]
message_ids.append(message_user_id)
receipts.append(
{"receipt_handle": receipt_handle[0], "msg_user_id": message_user_id}
)
receipt_seen = set()
for receipt_and_id in receipts:
receipt = receipt_and_id["receipt_handle"]
if receipt in receipt_seen:
raise BatchEntryIdsNotDistinct(receipt_and_id["msg_user_id"])
receipt_seen.add(receipt)
for receipt_and_id in receipts:
self.sqs_backend.delete_message(
queue_name, receipt_and_id["receipt_handle"]
)
message_ids = [r["msg_user_id"] for r in receipts]
template = self.response_template(DELETE_MESSAGE_BATCH_RESPONSE)
return template.render(message_ids=message_ids)

View File

@ -1714,6 +1714,34 @@ def test_send_message_batch():
)
@mock_sqs
def test_delete_message_batch_with_duplicates():
client = boto3.client("sqs", region_name="us-east-1")
response = client.create_queue(QueueName="test-queue")
queue_url = response["QueueUrl"]
client.send_message(QueueUrl=queue_url, MessageBody="coucou")
messages = client.receive_message(
QueueUrl=queue_url, WaitTimeSeconds=0, VisibilityTimeout=0
)["Messages"]
assert messages, "at least one msg"
entries = [
{"Id": msg["MessageId"], "ReceiptHandle": msg["ReceiptHandle"]}
for msg in [messages[0], messages[0]]
]
with pytest.raises(ClientError) as e:
client.delete_message_batch(QueueUrl=queue_url, Entries=entries)
ex = e.value
assert ex.response["Error"]["Code"] == "BatchEntryIdsNotDistinct"
# no messages are deleted
messages = client.receive_message(QueueUrl=queue_url, WaitTimeSeconds=0).get(
"Messages", []
)
assert messages, "message still in the queue"
@mock_sqs
def test_message_attributes_in_receive_message():
sqs = boto3.resource("sqs", region_name="us-east-1")