Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit bc4f7d7

Browse filesBrowse files
nikophilfabpot
authored andcommitted
Messenger: validate options for AMQP and Redis Connections
1 parent fc30e61 commit bc4f7d7
Copy full SHA for bc4f7d7

12 files changed

+155-6Lines changed: 155 additions & 6 deletions

File tree

Expand file treeCollapse file tree
Open diff view settings
Filter options
Expand file treeCollapse file tree
Open diff view settings
Collapse file

‎UPGRADE-5.1.md‎

Copy file name to clipboardExpand all lines: UPGRADE-5.1.md
+1Lines changed: 1 addition & 0 deletions
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ Messenger
3535
* Deprecated AmqpExt transport. It has moved to a separate package. Run `composer require symfony/amqp-messenger` to use the new classes.
3636
* Deprecated Doctrine transport. It has moved to a separate package. Run `composer require symfony/doctrine-messenger` to use the new classes.
3737
* Deprecated RedisExt transport. It has moved to a separate package. Run `composer require symfony/redis-messenger` to use the new classes.
38+
* Deprecated use of invalid options in Redis and AMQP connections.
3839

3940
Routing
4041
-------
Collapse file

‎UPGRADE-6.0.md‎

Copy file name to clipboardExpand all lines: UPGRADE-6.0.md
+1Lines changed: 1 addition & 0 deletions
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ Messenger
3535
* Removed AmqpExt transport. Run `composer require symfony/amqp-messenger` to keep the transport in your application.
3636
* Removed Doctrine transport. Run `composer require symfony/doctrine-messenger` to keep the transport in your application.
3737
* Removed RedisExt transport. Run `composer require symfony/redis-messenger` to keep the transport in your application.
38+
* Use of invalid options in Redis and AMQP connections now throws an error.
3839

3940
Routing
4041
-------
Collapse file

‎src/Symfony/Component/Messenger/Bridge/Amqp/CHANGELOG.md‎

Copy file name to clipboardExpand all lines: src/Symfony/Component/Messenger/Bridge/Amqp/CHANGELOG.md
+1Lines changed: 1 addition & 0 deletions
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ CHANGELOG
55
-----
66

77
* Introduced the AMQP bridge.
8+
* Deprecated use of invalid options
Collapse file

‎src/Symfony/Component/Messenger/Bridge/Amqp/Tests/Transport/AmqpTransportFactoryTest.php‎

Copy file name to clipboardExpand all lines: src/Symfony/Component/Messenger/Bridge/Amqp/Tests/Transport/AmqpTransportFactoryTest.php
+2-2Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,8 @@ public function testItCreatesTheTransport()
3636
$factory = new AmqpTransportFactory();
3737
$serializer = $this->createMock(SerializerInterface::class);
3838

39-
$expectedTransport = new AmqpTransport(Connection::fromDsn('amqp://localhost', ['foo' => 'bar']), $serializer);
39+
$expectedTransport = new AmqpTransport(Connection::fromDsn('amqp://localhost', ['host' => 'localhost']), $serializer);
4040

41-
$this->assertEquals($expectedTransport, $factory->createTransport('amqp://localhost', ['foo' => 'bar'], $serializer));
41+
$this->assertEquals($expectedTransport, $factory->createTransport('amqp://localhost', ['host' => 'localhost'], $serializer));
4242
}
4343
}
Collapse file

‎src/Symfony/Component/Messenger/Bridge/Amqp/Tests/Transport/ConnectionTest.php‎

Copy file name to clipboardExpand all lines: src/Symfony/Component/Messenger/Bridge/Amqp/Tests/Transport/ConnectionTest.php
+36Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,42 @@ public function testOptionsAreTakenIntoAccountAndOverwrittenByDsn()
102102
);
103103
}
104104

105+
/**
106+
* @group legacy
107+
* @expectedDeprecation Invalid option(s) "foo" passed to the AMQP Messenger transport. Passing invalid options is deprecated since Symfony 5.1.
108+
*/
109+
public function testDeprecationIfInvalidOptionIsPassedWithDsn()
110+
{
111+
Connection::fromDsn('amqp://host?foo=bar');
112+
}
113+
114+
/**
115+
* @group legacy
116+
* @expectedDeprecation Invalid option(s) "foo" passed to the AMQP Messenger transport. Passing invalid options is deprecated since Symfony 5.1.
117+
*/
118+
public function testDeprecationIfInvalidOptionIsPassedAsArgument()
119+
{
120+
Connection::fromDsn('amqp://host', ['foo' => 'bar']);
121+
}
122+
123+
/**
124+
* @group legacy
125+
* @expectedDeprecation Invalid queue option(s) "foo" passed to the AMQP Messenger transport. Passing invalid queue options is deprecated since Symfony 5.1.
126+
*/
127+
public function testDeprecationIfInvalidQueueOptionIsPassed()
128+
{
129+
Connection::fromDsn('amqp://host', ['queues' => ['queueName' => ['foo' => 'bar']]]);
130+
}
131+
132+
/**
133+
* @group legacy
134+
* @expectedDeprecation Invalid exchange option(s) "foo" passed to the AMQP Messenger transport. Passing invalid exchange options is deprecated since Symfony 5.1.
135+
*/
136+
public function testDeprecationIfInvalidExchangeOptionIsPassed()
137+
{
138+
Connection::fromDsn('amqp://host', ['exchange' => ['foo' => 'bar']]);
139+
}
140+
105141
public function testSetsParametersOnTheQueueAndExchange()
106142
{
107143
$factory = new TestAmqpFactory(
Collapse file

‎src/Symfony/Component/Messenger/Bridge/Amqp/Transport/Connection.php‎

Copy file name to clipboardExpand all lines: src/Symfony/Component/Messenger/Bridge/Amqp/Transport/Connection.php
+86Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,47 @@ class Connection
3232
'x-message-ttl',
3333
];
3434

35+
private const AVAILABLE_OPTIONS = [
36+
'host',
37+
'port',
38+
'vhost',
39+
'user',
40+
'password',
41+
'queues',
42+
'exchange',
43+
'delay',
44+
'auto_setup',
45+
'prefetch_count',
46+
'retry',
47+
'persistent',
48+
'frame_max',
49+
'channel_max',
50+
'heartbeat',
51+
'read_timeout',
52+
'write_timeout',
53+
'connect_timeout',
54+
'cacert',
55+
'cert',
56+
'key',
57+
'verify',
58+
'sasl_method',
59+
];
60+
61+
private const AVAILABLE_QUEUE_OPTIONS = [
62+
'binding_keys',
63+
'binding_arguments',
64+
'flags',
65+
'arguments',
66+
];
67+
68+
private const AVAILABLE_EXCHANGE_OPTIONS = [
69+
'name',
70+
'type',
71+
'default_publish_routing_key',
72+
'flags',
73+
'arguments',
74+
];
75+
3576
private $connectionOptions;
3677
private $exchangeOptions;
3778
private $queuesOptions;
@@ -84,6 +125,9 @@ public function __construct(array $connectionOptions, array $exchangeOptions, ar
84125
* * vhost: Virtual Host to use with the AMQP service
85126
* * user: Username to use to connect the the AMQP service
86127
* * password: Password to use the connect to the AMQP service
128+
* * read_timeout: Timeout in for income activity. Note: 0 or greater seconds. May be fractional.
129+
* * write_timeout: Timeout in for outcome activity. Note: 0 or greater seconds. May be fractional.
130+
* * connect_timeout: Connection timeout. Note: 0 or greater seconds. May be fractional.
87131
* * queues[name]: An array of queues, keyed by the name
88132
* * binding_keys: The binding keys (if any) to bind to this queue
89133
* * binding_arguments: Arguments to be used while binding the queue.
@@ -100,6 +144,22 @@ public function __construct(array $connectionOptions, array $exchangeOptions, ar
100144
* * exchange_name: Name of the exchange to be used for the delayed/retried messages (Default: "delays")
101145
* * auto_setup: Enable or not the auto-setup of queues and exchanges (Default: true)
102146
* * prefetch_count: set channel prefetch count
147+
*
148+
* * Connection tuning options (see http://www.rabbitmq.com/amqp-0-9-1-reference.html#connection.tune for details):
149+
* * channel_max: Specifies highest channel number that the server permits. 0 means standard extension limit
150+
* (see PHP_AMQP_MAX_CHANNELS constant)
151+
* * frame_max: The largest frame size that the server proposes for the connection, including frame header
152+
* and end-byte. 0 means standard extension limit (depends on librabbimq default frame size limit)
153+
* * heartbeat: The delay, in seconds, of the connection heartbeat that the server wants.
154+
* 0 means the server does not want a heartbeat. Note, librabbitmq has limited heartbeat support,
155+
* which means heartbeats checked only during blocking calls.
156+
*
157+
* TLS support (see https://www.rabbitmq.com/ssl.html for details):
158+
* * cacert: Path to the CA cert file in PEM format..
159+
* * cert: Path to the client certificate in PEM foramt.
160+
* * key: Path to the client key in PEM format.
161+
* * verify: Enable or disable peer verification. If peer verification is enabled then the common name in the
162+
* server certificate must match the server name. Peer verification is enabled by default.
103163
*/
104164
public static function fromDsn(string $dsn, array $options = [], AmqpFactory $amqpFactory = null): self
105165
{
@@ -125,6 +185,8 @@ public static function fromDsn(string $dsn, array $options = [], AmqpFactory $am
125185
],
126186
], $options, $parsedQuery);
127187

188+
self::validateOptions($amqpOptions);
189+
128190
if (isset($parsedUrl['user'])) {
129191
$amqpOptions['login'] = $parsedUrl['user'];
130192
}
@@ -155,6 +217,30 @@ public static function fromDsn(string $dsn, array $options = [], AmqpFactory $am
155217
return new self($amqpOptions, $exchangeOptions, $queuesOptions, $amqpFactory);
156218
}
157219

220+
private static function validateOptions(array $options): void
221+
{
222+
if (0 < \count($invalidOptions = array_diff(array_keys($options), self::AVAILABLE_OPTIONS))) {
223+
@trigger_error(sprintf('Invalid option(s) "%s" passed to the AMQP Messenger transport. Passing invalid options is deprecated since Symfony 5.1.', implode('", "', $invalidOptions)), E_USER_DEPRECATED);
224+
}
225+
226+
if (\is_array($options['queues'] ?? false)) {
227+
foreach ($options['queues'] as $queue) {
228+
if (!\is_array($queue)) {
229+
continue;
230+
}
231+
232+
if (0 < \count($invalidQueueOptions = array_diff(array_keys($queue), self::AVAILABLE_QUEUE_OPTIONS))) {
233+
@trigger_error(sprintf('Invalid queue option(s) "%s" passed to the AMQP Messenger transport. Passing invalid queue options is deprecated since Symfony 5.1.', implode('", "', $invalidQueueOptions)), E_USER_DEPRECATED);
234+
}
235+
}
236+
}
237+
238+
if (\is_array($options['exchange'] ?? false)
239+
&& 0 < \count($invalidExchangeOptions = array_diff(array_keys($options['exchange']), self::AVAILABLE_EXCHANGE_OPTIONS))) {
240+
@trigger_error(sprintf('Invalid exchange option(s) "%s" passed to the AMQP Messenger transport. Passing invalid exchange options is deprecated since Symfony 5.1.', implode('", "', $invalidExchangeOptions)), E_USER_DEPRECATED);
241+
}
242+
}
243+
158244
private static function normalizeQueueArguments(array $arguments): array
159245
{
160246
foreach (self::ARGUMENTS_AS_INTEGER as $key) {
Collapse file

‎src/Symfony/Component/Messenger/Bridge/Doctrine/Tests/Transport/ConnectionTest.php‎

Copy file name to clipboardExpand all lines: src/Symfony/Component/Messenger/Bridge/Doctrine/Tests/Transport/ConnectionTest.php
+2-1Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,6 @@
2222
use Symfony\Component\Messenger\Bridge\Doctrine\Tests\Fixtures\DummyMessage;
2323
use Symfony\Component\Messenger\Bridge\Doctrine\Transport\Connection;
2424

25-
2625
class ConnectionTest extends TestCase
2726
{
2827
public function testGetAMessageWillChangeItsStatus()
@@ -247,12 +246,14 @@ public function buildConfigurationProvider(): iterable
247246
public function testItThrowsAnExceptionIfAnExtraOptionsInDefined()
248247
{
249248
$this->expectException('Symfony\Component\Messenger\Exception\InvalidArgumentException');
249+
$this->expectExceptionMessage('Unknown option found: [new_option]. Allowed options are [table_name, queue_name, redeliver_timeout, auto_setup]');
250250
Connection::buildConfiguration('doctrine://default', ['new_option' => 'woops']);
251251
}
252252

253253
public function testItThrowsAnExceptionIfAnExtraOptionsInDefinedInDSN()
254254
{
255255
$this->expectException('Symfony\Component\Messenger\Exception\InvalidArgumentException');
256+
$this->expectExceptionMessage('Unknown option found in DSN: [new_option]. Allowed options are [table_name, queue_name, redeliver_timeout, auto_setup]');
256257
Connection::buildConfiguration('doctrine://default?new_option=woops');
257258
}
258259

Collapse file

‎src/Symfony/Component/Messenger/Bridge/Doctrine/Transport/Connection.php‎

Copy file name to clipboardExpand all lines: src/Symfony/Component/Messenger/Bridge/Doctrine/Transport/Connection.php
+1-1Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ public static function buildConfiguration(string $dsn, array $options = []): arr
8585
// check for extra keys in options
8686
$optionsExtraKeys = array_diff(array_keys($options), array_keys(self::DEFAULT_OPTIONS));
8787
if (0 < \count($optionsExtraKeys)) {
88-
throw new InvalidArgumentException(sprintf('Unknown option found : [%s]. Allowed options are [%s]', implode(', ', $optionsExtraKeys), implode(', ', array_keys(self::DEFAULT_OPTIONS))));
88+
throw new InvalidArgumentException(sprintf('Unknown option found: [%s]. Allowed options are [%s]', implode(', ', $optionsExtraKeys), implode(', ', array_keys(self::DEFAULT_OPTIONS))));
8989
}
9090

9191
// check for extra keys in options
Collapse file

‎src/Symfony/Component/Messenger/Bridge/Redis/CHANGELOG.md‎

Copy file name to clipboardExpand all lines: src/Symfony/Component/Messenger/Bridge/Redis/CHANGELOG.md
+1Lines changed: 1 addition & 0 deletions
  • Display the source diff
  • Display the rich diff
Original file line numberDiff line numberDiff line change
@@ -6,3 +6,4 @@ CHANGELOG
66

77
* Introduced the Redis bridge.
88
* Added TLS option in the DSN. Example: `redis://127.0.0.1?tls=1`
9+
* Deprecated use of invalid options
Collapse file

‎src/Symfony/Component/Messenger/Bridge/Redis/Tests/Transport/ConnectionTest.php‎

Copy file name to clipboardExpand all lines: src/Symfony/Component/Messenger/Bridge/Redis/Tests/Transport/ConnectionTest.php
+9Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,15 @@ public function testFromDsnWithQueryOptions()
108108
);
109109
}
110110

111+
/**
112+
* @expectedDeprecation Invalid option(s) "foo" passed to the Redis Messenger transport. Passing invalid options is deprecated since Symfony 5.1.
113+
* @group legacy
114+
*/
115+
public function testDeprecationIfInvalidOptionIsPassedWithDsn()
116+
{
117+
Connection::fromDsn('redis://localhost/queue?foo=bar');
118+
}
119+
111120
public function testKeepGettingPendingMessages()
112121
{
113122
$redis = $this->getMockBuilder(\Redis::class)->disableOriginalConstructor()->getMock();

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.