From 0d441bf62aa318419ed951c60bd0e32f6339b1c2 Mon Sep 17 00:00:00 2001 From: Vincent Langlet Date: Tue, 7 May 2024 11:00:46 +0200 Subject: [PATCH] [Messenger] Comply with Amazon SQS requirements for message body --- .../Tests/Transport/AmazonSqsSenderTest.php | 15 +++++++++++++++ .../AmazonSqs/Transport/AmazonSqsSender.php | 17 +++++++++++++++++ 2 files changed, 32 insertions(+) diff --git a/src/Symfony/Component/Messenger/Bridge/AmazonSqs/Tests/Transport/AmazonSqsSenderTest.php b/src/Symfony/Component/Messenger/Bridge/AmazonSqs/Tests/Transport/AmazonSqsSenderTest.php index 80840c859cb05..d11a5d8037b27 100644 --- a/src/Symfony/Component/Messenger/Bridge/AmazonSqs/Tests/Transport/AmazonSqsSenderTest.php +++ b/src/Symfony/Component/Messenger/Bridge/AmazonSqs/Tests/Transport/AmazonSqsSenderTest.php @@ -72,4 +72,19 @@ public function testSendWithAmazonSqsXrayTraceHeaderStamp() $sender = new AmazonSqsSender($connection, $serializer); $sender->send($envelope); } + + public function testSendEncodeBodyToRespectAmazonRequirements() + { + $envelope = new Envelope(new DummyMessage('Oy')); + $encoded = ['body' => "\x7", 'headers' => ['type' => DummyMessage::class]]; + + $connection = $this->createMock(Connection::class); + $connection->expects($this->once())->method('send')->with(base64_encode($encoded['body']), $encoded['headers']); + + $serializer = $this->createMock(SerializerInterface::class); + $serializer->method('encode')->with($envelope)->willReturn($encoded); + + $sender = new AmazonSqsSender($connection, $serializer); + $sender->send($envelope); + } } diff --git a/src/Symfony/Component/Messenger/Bridge/AmazonSqs/Transport/AmazonSqsSender.php b/src/Symfony/Component/Messenger/Bridge/AmazonSqs/Transport/AmazonSqsSender.php index 1994313720e0d..b253c82e97e30 100644 --- a/src/Symfony/Component/Messenger/Bridge/AmazonSqs/Transport/AmazonSqsSender.php +++ b/src/Symfony/Component/Messenger/Bridge/AmazonSqs/Transport/AmazonSqsSender.php @@ -38,6 +38,7 @@ public function __construct(Connection $connection, SerializerInterface $seriali public function send(Envelope $envelope): Envelope { $encodedMessage = $this->serializer->encode($envelope); + $encodedMessage = $this->complyWithAmazonSqsRequirements($encodedMessage); /** @var DelayStamp|null $delayStamp */ $delayStamp = $envelope->last(DelayStamp::class); @@ -75,4 +76,20 @@ public function send(Envelope $envelope): Envelope return $envelope; } + + /** + * @see https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_SendMessage.html + * + * @param array{body: string, headers?: array} $encodedMessage + * + * @return array{body: string, headers?: array} + */ + private function complyWithAmazonSqsRequirements(array $encodedMessage): array + { + if (preg_match('/[^\x20-\x{D7FF}\xA\xD\x9\x{E000}-\x{FFFD}\x{10000}-\x{10FFFF}]/u', $encodedMessage['body'])) { + $encodedMessage['body'] = base64_encode($encodedMessage['body']); + } + + return $encodedMessage; + } }