Skip to content

Commit cdedbab

Browse files
committed
bug #60772 [Mailer] [Transport] Send clone of RawMessage instance in RoundRobinTransport (jnoordsij)
This PR was squashed before being merged into the 6.4 branch. Discussion ---------- [Mailer] [Transport] Send clone of `RawMessage` instance in `RoundRobinTransport` | Q | A | ------------- | --- | Branch? | 6.4 | Bug fix? | yes | New feature? | no | Deprecations? | no | Issues | N/A | License | MIT When using an implementation of the `TransportInterface`, a common pattern (especially for mass bulk mailing services) is to use headers to communicate various pieces of metadata or settings to the receiving server for processing. Such options or headers might be very specific to the type of service used. Real world examples of such applications are https://github.com/symfony/mailgun-mailer/blob/7.2/Transport/MailgunApiTransport.php#L89 or https://www.reddit.com/r/symfony/comments/1cn32jx/add_header_based_on_transport/?rdt=36882. However, when using such a transport as one of the transports in the `RoundRobinTransport` (or by extension the `FailoverTransport`), this may result in certain headers intended for transport service A to also be sent to transport service B if the former fails. Although this will likely be harmless in most cases, it may cause issues as the one described in laravel/framework#51872 (and https://stackoverflow.com/questions/78660310/why-the-failover-first-driver-fails-and-inline-attachment-image-path-is-wrong-in). To prevent alterations to the message that happen within the scope of a specific transport to leak to another, this PR proposes to use a clone of the `RawMessage` instance whenever attempting a new transport service. This should ensure that any transport-specific manipulations should not leak to a next transport. Note this is mostly a behavioral change, which I don't think should break any existing use case, but may considered to be noteworthy enough to list it somewhere. It may also even be considered a bug fix; if so, and it is better to target `7.3` or `6.4` instead, please let me know. Commits ------- 0972774 [Mailer] [Transport] Send clone of `RawMessage` instance in `RoundRobinTransport`
2 parents 26e3fc7 + 0972774 commit cdedbab

File tree

2 files changed

+24
-1
lines changed

2 files changed

+24
-1
lines changed

src/Symfony/Component/Mailer/Tests/Transport/RoundRobinTransportTest.php

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
use Symfony\Component\Mailer\Exception\TransportExceptionInterface;
1717
use Symfony\Component\Mailer\Transport\RoundRobinTransport;
1818
use Symfony\Component\Mailer\Transport\TransportInterface;
19+
use Symfony\Component\Mime\Header\Headers;
20+
use Symfony\Component\Mime\Message;
1921
use Symfony\Component\Mime\RawMessage;
2022

2123
/**
@@ -143,6 +145,27 @@ public function testSendOneDeadAndRecoveryWithinRetryPeriod()
143145
$this->assertTransports($t, 1, []);
144146
}
145147

148+
public function testSendOneDeadMessageAlterationsDoNotPersist()
149+
{
150+
$t1 = $this->createMock(TransportInterface::class);
151+
$t1->expects($this->once())->method('send')
152+
->willReturnCallback(function (Message $message) {
153+
$message->getHeaders()->addTextHeader('X-Transport-1', 'value');
154+
throw new TransportException();
155+
});
156+
$t2 = $this->createMock(TransportInterface::class);
157+
$t2->expects($this->once())->method('send');
158+
$t = new RoundRobinTransport([$t1, $t2]);
159+
$p = new \ReflectionProperty($t, 'cursor');
160+
$p->setValue($t, 0);
161+
$headers = new Headers();
162+
$headers->addTextHeader('X-Shared', 'value');
163+
$message = new Message($headers);
164+
$t->send($message);
165+
$this->assertSame($message->getHeaders()->get('X-Shared')->getBody(), 'value');
166+
$this->assertFalse($message->getHeaders()->has('X-Transport-1'));
167+
}
168+
146169
public function testFailureDebugInformation()
147170
{
148171
$t1 = $this->createMock(TransportInterface::class);

src/Symfony/Component/Mailer/Transport/RoundRobinTransport.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ public function send(RawMessage $message, ?Envelope $envelope = null): ?SentMess
5252

5353
while ($transport = $this->getNextTransport()) {
5454
try {
55-
return $transport->send($message, $envelope);
55+
return $transport->send(clone $message, $envelope);
5656
} catch (TransportExceptionInterface $e) {
5757
$exception ??= new TransportException('All transports failed.');
5858
$exception->appendDebug(sprintf("Transport \"%s\": %s\n", $transport, $e->getDebug()));

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy