8000 Encode more data for amazon · symfony/symfony@f61a786 · GitHub
[go: up one dir, main page]

Skip to content

Commit f61a786

Browse files
Encode more data for amazon
1 parent fbc47bc commit f61a786

File tree

10 files changed

+184
-8
lines changed

10 files changed

+184
-8
lines changed

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/Configuration.php

+6-1
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
use Symfony\Component\Lock\Lock;
3333
use Symfony\Component\Lock\Store\SemaphoreStore;
3434
use Symfony\Component\Mailer\Mailer;
35+
use Symfony\Component\Messenger\Bridge\AmazonSqs\Transport\AmazonSqsSerializer;
3536
use Symfony\Component\Messenger\MessageBusInterface;
3637
use Symfony\Component\Notifier\Notifier;
3738
use Symfony\Component\PropertyAccess\PropertyAccessor;
@@ -1332,6 +1333,10 @@ private function addWebLinkSection(ArrayNodeDefinition $rootNode, callable $enab
13321333

13331334
private function addMessengerSection(ArrayNodeDefinition $rootNode, callable $enableIfStandalone)
13341335
{
1336+
$defaultSerializer = class_exists(AmazonSqsSerializer::class)
1337+
? 'messenger.transport.amazon_php_serializer'
1338+
: 'messenger.transport.native_php_serializer';
1339+
13351340
$rootNode
13361341
->children()
13371342
->arrayNode('messenger')
@@ -1395,7 +1400,7 @@ function ($a) {
13951400
->addDefaultsIfNotSet()
13961401
->children()
13971402
->scalarNode('default_serializer')
1398-
->defaultValue('messenger.transport.native_php_serializer')
1403+
->defaultValue($defaultSerializer)
13991404
->info('Service id to use as the default serializer for the transports.')
14001405
->end()
14011406
->arrayNode('symfony_serializer')

src/Symfony/Bundle/FrameworkBundle/Resources/config/messenger.php

+3
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212
namespace Symfony\Component\DependencyInjection\Loader\Configurator;
1313

1414
use Symfony\Component\DependencyInjection\ServiceLocator;
15+
use Symfony\Component\Messenger\Bridge\AmazonSqs\Transport\AmazonSqsSerializer;
1516
use Symfony\Component\Messenger\Bridge\AmazonSqs\Transport\AmazonSqsTransportFactory;
1617
use Symfony\Component\Messenger\Bridge\Amqp\Transport\AmqpTransportFactory;
1718
use Symfony\Component\Messenger\Bridge\Beanstalkd\Transport\BeanstalkdTransportFactory;
@@ -75,6 +76,8 @@
7576

7677
->set('messenger.transport.native_php_serializer', PhpSerializer::class)
7778

79+
->set('messenger.transport.amazon_php_serializer', AmazonSqsSerializer::class)
80+
7881
// Middleware
7982
->set('messenger.middleware.handle_message', HandleMessageMiddleware::class)
8083
->abstract()

src/Symfony/Bundle/FrameworkBundle/Tests/DependencyInjection/ConfigurationTest.php

+4-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
use Symfony\Component\HttpClient\HttpClient;
2323
use Symfony\Component\Lock\Store\SemaphoreStore;
2424
use Symfony\Component\Mailer\Mailer;
25+
use Symfony\Component\Messenger\Bridge\AmazonSqs\Transport\AmazonSqsSerializer;
2526
use Symfony\Component\Messenger\MessageBusInterface;
2627
use Symfony\Component\Notifier\Notifier;
2728
use Symfony\Component\RateLimiter\Policy\TokenBucketLimiter;
@@ -559,7 +560,9 @@ class_exists(SemaphoreStore::class) && SemaphoreStore::isSupported() ? 'semaphor
559560
'transports' => [],
560561
'failure_transport' => null,
561562
'serializer' => [
562-
'default_serializer' => 'messenger.transport.native_php_serializer',
563+
'default_serializer' => class_exists(AmazonSqsSerializer::class)
564+
? 'messenger.transport.amazon_php_serializer'
565+
: 'messenger.transport.native_php_serializer',
563566
'symfony_serializer' => [
564567
'format' => 'json',
565568
'context' => [],
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php
2+
3+
namespace Symfony\Component\Messenger\Bridge\AmazonSqs\Tests\Fixtures;
4+
5+
class DummyMessageTyped
6+
{
7+
private string $message;
8+
9+
public function __construct(string $message)
10+
{
11+
$this->message = $message;
12+
}
13+
14+
public function getMessage(): string
15+
{
16+
return $this->message;
17+
}
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Messenger\Bridge\AmazonSqs\Tests\Transport;
13+
14+
use PHPUnit\Framework\TestCase;
15+
use Symfony\Component\Messenger\Bridge\AmazonSqs\Tests\Fixtures\DummyMessage;
16+
use Symfony\Component\Messenger\Bridge\AmazonSqs\Tests\Fixtures\DummyMessageTyped;
17+
use Symfony\Component\Messenger\Bridge\AmazonSqs\Transport\AmazonSqsSerializer;
18+
use Symfony\Component\Messenger\Envelope;
19+
use Symfony\Component\Messenger\Exception\MessageDecodingFailedException;
20+
use Symfony\Component\Messenger\Stamp\NonSendableStampInterface;
21+
22+
class AmazonSqsSerializerTest extends TestCase
23+
{
24+
public function testEncodedIsDecodable()
25+
{
26+
$serializer = new AmazonSqsSerializer();
27+
28+
$envelope = new Envelope(new DummyMessage('Hello'));
29+
30+
$encoded = $serializer->encode($envelope);
31+
$this->assertStringNotContainsString("\0", $encoded['body'], 'Does not contain the binary characters');
32+
$this->assertEquals($envelope, $serializer->decode($encoded));
33+
}
34+
35+
public function testDecodingFailsWithMissingBodyKey()
36+
{
37+
$serializer = new AmazonSqsSerializer();
38+
39+
$this->expectException(MessageDecodingFailedException::class);
40+
$this->expectExceptionMessage('Encoded envelope should have at least a "body", or maybe you should implement your own serializer');
41+
42+
$serializer->decode([]);
43+
}
44+
45+
public function testDecodingFailsWithBadFormat()
46+
{
47+
$serializer = new AmazonSqsSerializer();
48+
49+
$this->expectException(MessageDecodingFailedException::class);
50+
$this->expectExceptionMessageMatches('/Could not decode/');
51+
52+
$serializer->decode([
53+
'body' => '{"message": "bar"}',
54+
]);
55+
}
56+
57+
public function testDecodingFailsWithBadBase64Body()
58+
{
59+
$serializer = new AmazonSqsSerializer();
60+
61+
$this->expectException(MessageDecodingFailedException::class);
62+
$this->expectExceptionMessageMatches('/Could not decode/');
63+
64+
$serializer->decode([
65+
'body' => 'x',
66+
]);
67+
}
68+
69+
public function testDecodingFailsWithBadClass()
70+
{
71+
$serializer = new AmazonSqsSerializer();
72+
73+
$this->expectException(MessageDecodingFailedException::class);
74+
$this->expectExceptionMessageMatches('/class "ReceivedSt0mp" not found/');
75+
76+
$serializer->decode([
77+
'body' => 'O:13:"ReceivedSt0mp":0:{}',
78+
]);
79+
}
80+
81+
public function testEncodedSkipsNonEncodeableStamps()
82+
{
83+
$serializer = new AmazonSqsSerializer();
84+
85+
$envelope = new Envelope(new DummyMessage('Hello'), [
86+
new DummyPhpSerializerNonSendableStamp(),
87+
]);
88+
89+
$encoded = $serializer->encode($envelope);
90+
$this->assertStringNotContainsString('DummyPhpSerializerNonSendableStamp', $encoded['body']);
91+
}
92+
93+
public function testNonUtf8IsBase64Encoded()
94+
{
95+
$serializer = new AmazonSqsSerializer();
96+
97+
$envelope = new Envelope(new DummyMessage("\xE9"));
98+
99+
$encoded = $serializer->encode($envelope);
100+
$this->assertTrue((bool) preg_match('//u', $encoded['body']), 'Encodes non-UTF8 payloads');
101+
$this->assertEquals($envelope, $serializer->decode($encoded));
102+
}
103+
104+
public function testSomeUtf8IsBase64Encoded()
105+
{
106+
$serializer = new AmazonSqsSerializer();
107+
108+
$envelope = new Envelope(new DummyMessage("\x7"));
109+
110+
$encoded = $serializer->encode($envelope);
111+
$this->assertNotFalse(base64_decode($encoded['body'], true));
112+
$this->assertEquals($envelope, $serializer->decode($encoded));
113+
}
114+
}
115+
116+
class DummyPhpSerializerNonSendableStamp implements NonSendableStampInterface
117+
{
118+
}

src/Symfony/Component/Messenger/Bridge/AmazonSqs/Transport/AmazonSqsReceiver.php

+1-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818
use Symfony\Component\Messenger\Exception\TransportException;
1919
use Symfony\Component\Messenger\Transport\Receiver\MessageCountAwareInterface;
2020
use Symfony\Component\Messenger\Transport\Receiver\ReceiverInterface;
21-
use Symfony\Component\Messenger\Transport\Serialization\PhpSerializer;
2221
use Symfony\Component\Messenger\Transport\Serialization\SerializerInterface;
2322

2423
/**
@@ -32,7 +31,7 @@ class AmazonSqsReceiver implements ReceiverInterface, MessageCountAwareInterface
3231
public function __construct(Connection $connection, ?SerializerInterface $serializer = null)
3332
{
3433
$this->connection = $connection;
35-
$this->serializer = $serializer ?? new PhpSerializer();
34+
$this->serializer = $serializer ?? new AmazonSqsSerializer();
3635
}
3736

3837
/**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Messenger\Bridge\AmazonSqs\Transport;
13+
14+
use Symfony\Component\Messenger\Transport\Serialization\PhpSerializer;
15+
16+
class AmazonSqsSerializer extends PhpSerializer
17+
{
18+
protected function shouldBeEncoded(string $body): bool
19+
{
20+
return parent::shouldBeEncoded($body)
21+
|| preg_match('/[^\x20-\x{D7FF}\xA\xD\x9\x{E000}-\x{FFFD}\x{10000}-\x{10FFFF}]/u', $body);
22+
}
23+
}

src/Symfony/Component/Messenger/Bridge/AmazonSqs/Transport/AmazonSqsTransport.php

+1-2
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@
1717
use Symfony\Component\Messenger\Transport\Receiver\MessageCountAwareInterface;
1818
use Symfony\Component\Messenger\Transport\Receiver\ReceiverInterface;
1919
use Symfony\Component\Messenger\Transport\Sender\SenderInterface;
20-
use Symfony\Component\Messenger\Transport\Serialization\PhpSerializer;
2120
use Symfony\Component\Messenger\Transport\Serialization\SerializerInterface;
2221
use Symfony\Component\Messenger\Transport\SetupableTransportInterface;
2322
use Symfony\Component\Messenger\Transport\TransportInterface;
@@ -36,7 +35,7 @@ class AmazonSqsTransport implements TransportInterface, SetupableTransportInterf
3635
public function __construct(Connection $connection, ?SerializerInterface $serializer = null, ?ReceiverInterface $receiver = null, ?SenderInterface $sender = null)
3736
{
3837
$this->connection = $connection;
39-
$this->serializer = $serializer ?? new PhpSerializer();
38+
$this->serializer = $serializer ?? new AmazonSqsSerializer();
4039
$this->receiver = $receiver;
4140
$this->sender = $sender;
4241
}

src/Symfony/Component/Messenger/Bridge/AmazonSqs/composer.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
"php": ">=7.2.5",
2020
"async-aws/core": "^1.5",
2121
"async-aws/sqs": "^1.0|^2.0",
22-
"symfony/messenger": "^4.3|^5.0|^6.0",
22+
"symfony/messenger": "^5.4|^6.0",
2323
"symfony/service-contracts": "^1.1|^2|^3",
2424
"psr/log": "^1|^2|^3"
2525
},

src/Symfony/Component/Messenger/Transport/Serialization/PhpSerializer.php

+9-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ public function encode(Envelope $envelope): array
4141

4242
$body = addslashes(serialize($envelope));
4343

44-
if (!preg_match('//u', $body)) {
44+
if ($this->shouldBeEncoded($body)) {
4545
$body = base64_encode($body);
4646
}
4747

@@ -50,6 +50,14 @@ public function encode(Envelope $envelope): array
5050
];
5151
}
5252

53+
/**
54+
* Entry point to use stricter condition for base64 encoding.
55+
*/
56+
protected funct 693B ion shouldBeEncoded(string $body): bool
57+
{
58+
return !preg_match('//u', $body);
59+
}
60+
5361
private function safelyUnserialize(string $contents)
5462
{
5563
if ('' === $contents) {

0 commit comments

Comments
 (0)
0