From d2f33d2cfef1aff273c552c74bbb8e6f30ad0c5d Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Wed, 17 Jul 2019 16:15:07 +0200 Subject: [PATCH 1/2] [Mailer] added debug info for HTTP mailers --- .../Bridge/Amazon/Http/Api/SesTransport.php | 9 ++++-- .../Bridge/Amazon/Http/SesTransport.php | 9 ++++-- .../Mailchimp/Http/Api/MandrillTransport.php | 11 ++++--- .../Mailchimp/Http/MandrillTransport.php | 11 ++++--- .../Mailgun/Http/Api/MailgunTransport.php | 9 ++++-- .../Bridge/Mailgun/Http/MailgunTransport.php | 9 ++++-- .../Postmark/Http/Api/PostmarkTransport.php | 9 ++++-- .../Sendgrid/Http/Api/SendgridTransport.php | 9 ++++-- .../Exception/HttpTransportException.php | 15 +++++++++ src/Symfony/Component/Mailer/SentMessage.php | 11 +++++++ .../Transport/Http/AbstractHttpTransport.php | 21 +++++++++++++ .../Http/Api/AbstractApiTransport.php | 31 ++++--------------- 12 files changed, 103 insertions(+), 51 deletions(-) diff --git a/src/Symfony/Component/Mailer/Bridge/Amazon/Http/Api/SesTransport.php b/src/Symfony/Component/Mailer/Bridge/Amazon/Http/Api/SesTransport.php index 7df24401ee..9bc32aff6f 100644 --- a/src/Symfony/Component/Mailer/Bridge/Amazon/Http/Api/SesTransport.php +++ b/src/Symfony/Component/Mailer/Bridge/Amazon/Http/Api/SesTransport.php @@ -12,12 +12,13 @@ namespace Symfony\Component\Mailer\Bridge\Amazon\Http\Api; use Psr\Log\LoggerInterface; -use Symfony\Component\Mailer\Exception\TransportException; +use Symfony\Component\Mailer\Exception\HttpTransportException; use Symfony\Component\Mailer\SmtpEnvelope; use Symfony\Component\Mailer\Transport\Http\Api\AbstractApiTransport; use Symfony\Component\Mime\Email; use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; use Symfony\Contracts\HttpClient\HttpClientInterface; +use Symfony\Contracts\HttpClient\ResponseInterface; /** * @author Kevin Verschaeve @@ -42,7 +43,7 @@ class SesTransport extends AbstractApiTransport parent::__construct($client, $dispatcher, $logger); } - protected function doSendEmail(Email $email, SmtpEnvelope $envelope): void + protected function doSendApi(Email $email, SmtpEnvelope $envelope): ResponseInterface { $date = gmdate('D, d M Y H:i:s e'); $auth = sprintf('AWS3-HTTPS AWSAccessKeyId=%s,Algorithm=HmacSHA256,Signature=%s', $this->accessKey, $this->getSignature($date)); @@ -60,8 +61,10 @@ class SesTransport extends AbstractApiTransport if (200 !== $response->getStatusCode()) { $error = new \SimpleXMLElement($response->getContent(false)); - throw new TransportException(sprintf('Unable to send an email: %s (code %s).', $error->Error->Message, $error->Error->Code)); + throw new HttpTransportException(sprintf('Unable to send an email: %s (code %s).', $error->Error->Message, $error->Error->Code), $response); } + + return $response; } private function getSignature(string $string): string diff --git a/src/Symfony/Component/Mailer/Bridge/Amazon/Http/SesTransport.php b/src/Symfony/Component/Mailer/Bridge/Amazon/Http/SesTransport.php index e5ee143c54..936781a7cc 100644 --- a/src/Symfony/Component/Mailer/Bridge/Amazon/Http/SesTransport.php +++ b/src/Symfony/Component/Mailer/Bridge/Amazon/Http/SesTransport.php @@ -12,11 +12,12 @@ namespace Symfony\Component\Mailer\Bridge\Amazon\Http; use Psr\Log\LoggerInterface; -use Symfony\Component\Mailer\Exception\TransportException; +use Symfony\Component\Mailer\Exception\HttpTransportException; use Symfony\Component\Mailer\SentMessage; use Symfony\Component\Mailer\Transport\Http\AbstractHttpTransport; use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; use Symfony\Contracts\HttpClient\HttpClientInterface; +use Symfony\Contracts\HttpClient\ResponseInterface; /** * @author Kevin Verschaeve @@ -41,7 +42,7 @@ class SesTransport extends AbstractHttpTransport parent::__construct($client, $dispatcher, $logger); } - protected function doSend(SentMessage $message): void + protected function doSendHttp(SentMessage $message): ResponseInterface { $date = gmdate('D, d M Y H:i:s e'); $auth = sprintf('AWS3-HTTPS AWSAccessKeyId=%s,Algorithm=HmacSHA256,Signature=%s', $this->accessKey, $this->getSignature($date)); @@ -61,8 +62,10 @@ class SesTransport extends AbstractHttpTransport if (200 !== $response->getStatusCode()) { $error = new \SimpleXMLElement($response->getContent(false)); - throw new TransportException(sprintf('Unable to send an email: %s (code %s).', $error->Error->Message, $error->Error->Code)); + throw new HttpTransportException(sprintf('Unable to send an email: %s (code %s).', $error->Error->Message, $error->Error->Code), $response); } + + return $response; } private function getSignature(string $string): string diff --git a/src/Symfony/Component/Mailer/Bridge/Mailchimp/Http/Api/MandrillTransport.php b/src/Symfony/Component/Mailer/Bridge/Mailchimp/Http/Api/MandrillTransport.php index 116ca4dcb2..bf1c154b5d 100644 --- a/src/Symfony/Component/Mailer/Bridge/Mailchimp/Http/Api/MandrillTransport.php +++ b/src/Symfony/Component/Mailer/Bridge/Mailchimp/Http/Api/MandrillTransport.php @@ -12,12 +12,13 @@ namespace Symfony\Component\Mailer\Bridge\Mailchimp\Http\Api; use Psr\Log\LoggerInterface; -use Symfony\Component\Mailer\Exception\TransportException; +use Symfony\Component\Mailer\Exception\HttpTransportException; use Symfony\Component\Mailer\SmtpEnvelope; use Symfony\Component\Mailer\Transport\Http\Api\AbstractApiTransport; use Symfony\Component\Mime\Email; use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; use Symfony\Contracts\HttpClient\HttpClientInterface; +use Symfony\Contracts\HttpClient\ResponseInterface; /** * @author Kevin Verschaeve @@ -35,7 +36,7 @@ class MandrillTransport extends AbstractApiTransport parent::__construct($client, $dispatcher, $logger); } - protected function doSendEmail(Email $email, SmtpEnvelope $envelope): void + protected function doSendApi(Email $email, SmtpEnvelope $envelope): ResponseInterface { $response = $this->client->request('POST', self::ENDPOINT, [ 'json' => $this->getPayload($email, $envelope), @@ -44,11 +45,13 @@ class MandrillTransport extends AbstractApiTransport if (200 !== $response->getStatusCode()) { $result = $response->toArray(false); if ('error' === ($result['status'] ?? false)) { - throw new TransportException(sprintf('Unable to send an email: %s (code %s).', $result['message'], $result['code'])); + throw new HttpTransportException(sprintf('Unable to send an email: %s (code %s).', $result['message'], $result['code']), $response); } - throw new TransportException(sprintf('Unable to send an email (code %s).', $result['code'])); + throw new HttpTransportException(sprintf('Unable to send an email (code %s).', $result['code']), $response); } + + return $response; } private function getPayload(Email $email, SmtpEnvelope $envelope): array diff --git a/src/Symfony/Component/Mailer/Bridge/Mailchimp/Http/MandrillTransport.php b/src/Symfony/Component/Mailer/Bridge/Mailchimp/Http/MandrillTransport.php index fd931e97e2..c6e06b496c 100644 --- a/src/Symfony/Component/Mailer/Bridge/Mailchimp/Http/MandrillTransport.php +++ b/src/Symfony/Component/Mailer/Bridge/Mailchimp/Http/MandrillTransport.php @@ -12,11 +12,12 @@ namespace Symfony\Component\Mailer\Bridge\Mailchimp\Http; use Psr\Log\LoggerInterface; -use Symfony\Component\Mailer\Exception\TransportException; +use Symfony\Component\Mailer\Exception\HttpTransportException; use Symfony\Component\Mailer\SentMessage; use Symfony\Component\Mailer\Transport\Http\AbstractHttpTransport; use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; use Symfony\Contracts\HttpClient\HttpClientInterface; +use Symfony\Contracts\HttpClient\ResponseInterface; /** * @author Kevin Verschaeve @@ -33,7 +34,7 @@ class MandrillTransport extends AbstractHttpTransport parent::__construct($client, $dispatcher, $logger); } - protected function doSend(SentMessage $message): void + protected function doSendHttp(SentMessage $message): ResponseInterface { $envelope = $message->getEnvelope(); $response = $this->client->request('POST', self::ENDPOINT, [ @@ -48,10 +49,12 @@ class MandrillTransport extends AbstractHttpTransport if (200 !== $response->getStatusCode()) { $result = $response->toArray(false); if ('error' === ($result['status'] ?? false)) { - throw new TransportException(sprintf('Unable to send an email: %s (code %s).', $result['message'], $result['code'])); + throw new HttpTransportException(sprintf('Unable to send an email: %s (code %s).', $result['message'], $result['code']), $response); } - throw new TransportException(sprintf('Unable to send an email (code %s).', $result['code'])); + throw new HttpTransportException(sprintf('Unable to send an email (code %s).', $result['code']), $response); } + + return $response; } } diff --git a/src/Symfony/Component/Mailer/Bridge/Mailgun/Http/Api/MailgunTransport.php b/src/Symfony/Component/Mailer/Bridge/Mailgun/Http/Api/MailgunTransport.php index ba6983b02c..56f90eb97c 100644 --- a/src/Symfony/Component/Mailer/Bridge/Mailgun/Http/Api/MailgunTransport.php +++ b/src/Symfony/Component/Mailer/Bridge/Mailgun/Http/Api/MailgunTransport.php @@ -12,13 +12,14 @@ namespace Symfony\Component\Mailer\Bridge\Mailgun\Http\Api; use Psr\Log\LoggerInterface; -use Symfony\Component\Mailer\Exception\TransportException; +use Symfony\Component\Mailer\Exception\HttpTransportException; use Symfony\Component\Mailer\SmtpEnvelope; use Symfony\Component\Mailer\Transport\Http\Api\AbstractApiTransport; use Symfony\Component\Mime\Email; use Symfony\Component\Mime\Part\Multipart\FormDataPart; use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; use Symfony\Contracts\HttpClient\HttpClientInterface; +use Symfony\Contracts\HttpClient\ResponseInterface; /** * @author Kevin Verschaeve @@ -40,7 +41,7 @@ class MailgunTransport extends AbstractApiTransport parent::__construct($client, $dispatcher, $logger); } - protected function doSendEmail(Email $email, SmtpEnvelope $envelope): void + protected function doSendApi(Email $email, SmtpEnvelope $envelope): ResponseInterface { $body = new FormDataPart($this->getPayload($email, $envelope)); $headers = []; @@ -58,8 +59,10 @@ class MailgunTransport extends AbstractApiTransport if (200 !== $response->getStatusCode()) { $error = $response->toArray(false); - throw new TransportException(sprintf('Unable to send an email: %s (code %s).', $error['message'], $response->getStatusCode())); + throw new HttpTransportException(sprintf('Unable to send an email: %s (code %s).', $error['message'], $response->getStatusCode()), $response); } + + return $response; } private function getPayload(Email $email, SmtpEnvelope $envelope): array diff --git a/src/Symfony/Component/Mailer/Bridge/Mailgun/Http/MailgunTransport.php b/src/Symfony/Component/Mailer/Bridge/Mailgun/Http/MailgunTransport.php index 0f9f515770..6ddf1f3ed5 100644 --- a/src/Symfony/Component/Mailer/Bridge/Mailgun/Http/MailgunTransport.php +++ b/src/Symfony/Component/Mailer/Bridge/Mailgun/Http/MailgunTransport.php @@ -12,13 +12,14 @@ namespace Symfony\Component\Mailer\Bridge\Mailgun\Http; use Psr\Log\LoggerInterface; -use Symfony\Component\Mailer\Exception\TransportException; +use Symfony\Component\Mailer\Exception\HttpTransportException; use Symfony\Component\Mailer\SentMessage; use Symfony\Component\Mailer\Transport\Http\AbstractHttpTransport; use Symfony\Component\Mime\Part\DataPart; use Symfony\Component\Mime\Part\Multipart\FormDataPart; use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; use Symfony\Contracts\HttpClient\HttpClientInterface; +use Symfony\Contracts\HttpClient\ResponseInterface; /** * @author Kevin Verschaeve @@ -39,7 +40,7 @@ class MailgunTransport extends AbstractHttpTransport parent::__construct($client, $dispatcher, $logger); } - protected function doSend(SentMessage $message): void + protected function doSendHttp(SentMessage $message): ResponseInterface { $body = new FormDataPart([ 'to' => implode(',', $this->stringifyAddresses($message->getEnvelope()->getRecipients())), @@ -59,7 +60,9 @@ class MailgunTransport extends AbstractHttpTransport if (200 !== $response->getStatusCode()) { $error = $response->toArray(false); - throw new TransportException(sprintf('Unable to send an email: %s (code %s).', $error['message'], $response->getStatusCode())); + throw new HttpTransportException(sprintf('Unable to send an email: %s (code %s).', $error['message'], $response->getStatusCode()), $response); } + + return $response; } } diff --git a/src/Symfony/Component/Mailer/Bridge/Postmark/Http/Api/PostmarkTransport.php b/src/Symfony/Component/Mailer/Bridge/Postmark/Http/Api/PostmarkTransport.php index 644e0d0f8e..8114395762 100644 --- a/src/Symfony/Component/Mailer/Bridge/Postmark/Http/Api/PostmarkTransport.php +++ b/src/Symfony/Component/Mailer/Bridge/Postmark/Http/Api/PostmarkTransport.php @@ -12,12 +12,13 @@ namespace Symfony\Component\Mailer\Bridge\Postmark\Http\Api; use Psr\Log\LoggerInterface; -use Symfony\Component\Mailer\Exception\TransportException; +use Symfony\Component\Mailer\Exception\HttpTransportException; use Symfony\Component\Mailer\SmtpEnvelope; use Symfony\Component\Mailer\Transport\Http\Api\AbstractApiTransport; use Symfony\Component\Mime\Email; use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; use Symfony\Contracts\HttpClient\HttpClientInterface; +use Symfony\Contracts\HttpClient\ResponseInterface; /** * @author Kevin Verschaeve @@ -35,7 +36,7 @@ class PostmarkTransport extends AbstractApiTransport parent::__construct($client, $dispatcher, $logger); } - protected function doSendEmail(Email $email, SmtpEnvelope $envelope): void + protected function doSendApi(Email $email, SmtpEnvelope $envelope): ResponseInterface { $response = $this->client->request('POST', self::ENDPOINT, [ 'headers' => [ @@ -48,8 +49,10 @@ class PostmarkTransport extends AbstractApiTransport if (200 !== $response->getStatusCode()) { $error = $response->toArray(false); - throw new TransportException(sprintf('Unable to send an email: %s (code %s).', $error['Message'], $error['ErrorCode'])); + throw new HttpTransportException(sprintf('Unable to send an email: %s (code %s).', $error['Message'], $error['ErrorCode']), $response); } + + return $response; } private function getPayload(Email $email, SmtpEnvelope $envelope): array diff --git a/src/Symfony/Component/Mailer/Bridge/Sendgrid/Http/Api/SendgridTransport.php b/src/Symfony/Component/Mailer/Bridge/Sendgrid/Http/Api/SendgridTransport.php index 86f362f303..3beec418da 100644 --- a/src/Symfony/Component/Mailer/Bridge/Sendgrid/Http/Api/SendgridTransport.php +++ b/src/Symfony/Component/Mailer/Bridge/Sendgrid/Http/Api/SendgridTransport.php @@ -12,13 +12,14 @@ namespace Symfony\Component\Mailer\Bridge\Sendgrid\Http\Api; use Psr\Log\LoggerInterface; -use Symfony\Component\Mailer\Exception\TransportException; +use Symfony\Component\Mailer\Exception\HttpTransportException; use Symfony\Component\Mailer\SmtpEnvelope; use Symfony\Component\Mailer\Transport\Http\Api\AbstractApiTransport; use Symfony\Component\Mime\Address; use Symfony\Component\Mime\Email; use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; use Symfony\Contracts\HttpClient\HttpClientInterface; +use Symfony\Contracts\HttpClient\ResponseInterface; /** * @author Kevin Verschaeve @@ -36,7 +37,7 @@ class SendgridTransport extends AbstractApiTransport parent::__construct($client, $dispatcher, $logger); } - protected function doSendEmail(Email $email, SmtpEnvelope $envelope): void + protected function doSendApi(Email $email, SmtpEnvelope $envelope): ResponseInterface { $response = $this->client->request('POST', self::ENDPOINT, [ 'json' => $this->getPayload($email, $envelope), @@ -46,8 +47,10 @@ class SendgridTransport extends AbstractApiTransport if (202 !== $response->getStatusCode()) { $errors = $response->toArray(false); - throw new TransportException(sprintf('Unable to send an email: %s (code %s).', implode('; ', array_column($errors['errors'], 'message')), $response->getStatusCode())); + throw new HttpTransportException(sprintf('Unable to send an email: %s (code %s).', implode('; ', array_column($errors['errors'], 'message')), $response->getStatusCode()), $response); } + + return $response; } private function getPayload(Email $email, SmtpEnvelope $envelope): array diff --git a/src/Symfony/Component/Mailer/Exception/HttpTransportException.php b/src/Symfony/Component/Mailer/Exception/HttpTransportException.php index c85d686543..f9e49aaeda 100644 --- a/src/Symfony/Component/Mailer/Exception/HttpTransportException.php +++ b/src/Symfony/Component/Mailer/Exception/HttpTransportException.php @@ -11,9 +11,24 @@ namespace Symfony\Component\Mailer\Exception; +use Symfony\Contracts\HttpClient\ResponseInterface; + /** * @author Fabien Potencier */ class HttpTransportException extends TransportException { + private $response; + + public function __construct(string $message = null, ResponseInterface $response, int $code = 0, \Exception $previous = null) + { + parent::__construct($message, $code, $previous); + + $this->response = $response; + } + + public function getResponse(): ResponseInterface + { + return $this->response; + } } diff --git a/src/Symfony/Component/Mailer/SentMessage.php b/src/Symfony/Component/Mailer/SentMessage.php index 45dfbdc2f3..5ed2acabaf 100644 --- a/src/Symfony/Component/Mailer/SentMessage.php +++ b/src/Symfony/Component/Mailer/SentMessage.php @@ -22,6 +22,7 @@ class SentMessage private $original; private $raw; private $envelope; + private $debug = ''; /** * @internal @@ -48,6 +49,16 @@ class SentMessage return $this->envelope; } + public function getDebug(): string + { + return $this->debug; + } + + public function appendDebug(string $debug): void + { + $this->debug .= $debug; + } + public function toString(): string { return $this->raw->toString(); diff --git a/src/Symfony/Component/Mailer/Transport/Http/AbstractHttpTransport.php b/src/Symfony/Component/Mailer/Transport/Http/AbstractHttpTransport.php index b948b16823..885a4ccfea 100644 --- a/src/Symfony/Component/Mailer/Transport/Http/AbstractHttpTransport.php +++ b/src/Symfony/Component/Mailer/Transport/Http/AbstractHttpTransport.php @@ -13,9 +13,12 @@ namespace Symfony\Component\Mailer\Transport\Http; use Psr\Log\LoggerInterface; use Symfony\Component\HttpClient\HttpClient; +use Symfony\Component\Mailer\Exception\HttpTransportException; +use Symfony\Component\Mailer\SentMessage; use Symfony\Component\Mailer\Transport\AbstractTransport; use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; use Symfony\Contracts\HttpClient\HttpClientInterface; +use Symfony\Contracts\HttpClient\ResponseInterface; /** * @author Victor Bocharsky @@ -37,4 +40,22 @@ abstract class AbstractHttpTransport extends AbstractTransport parent::__construct($dispatcher, $logger); } + + abstract protected function doSendHttp(SentMessage $message): ResponseInterface; + + protected function doSend(SentMessage $message): void + { + $response = null; + try { + $response = $this->doSendHttp($message); + } catch (HttpTransportException $e) { + $response = $e->getResponse(); + + throw $e; + } finally { + if (null !== $response) { + $message->appendDebug($response->getInfo('debug')); + } + } + } } diff --git a/src/Symfony/Component/Mailer/Transport/Http/Api/AbstractApiTransport.php b/src/Symfony/Component/Mailer/Transport/Http/Api/AbstractApiTransport.php index ad371171af..081b5bdcc4 100644 --- a/src/Symfony/Component/Mailer/Transport/Http/Api/AbstractApiTransport.php +++ b/src/Symfony/Component/Mailer/Transport/Http/Api/AbstractApiTransport.php @@ -11,42 +11,23 @@ namespace Symfony\Component\Mailer\Transport\Http\Api; -use Psr\Log\LoggerInterface; -use Symfony\Component\HttpClient\HttpClient; use Symfony\Component\Mailer\Exception\RuntimeException; use Symfony\Component\Mailer\SentMessage; use Symfony\Component\Mailer\SmtpEnvelope; -use Symfony\Component\Mailer\Transport\AbstractTransport; +use Symfony\Component\Mailer\Transport\Http\AbstractHttpTransport; use Symfony\Component\Mime\Address; use Symfony\Component\Mime\Email; use Symfony\Component\Mime\MessageConverter; -use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; -use Symfony\Contracts\HttpClient\HttpClientInterface; +use Symfony\Contracts\HttpClient\ResponseInterface; /** * @author Fabien Potencier */ -abstract class AbstractApiTransport extends AbstractTransport +abstract class AbstractApiTransport extends AbstractHttpTransport { - protected $client; + abstract protected function doSendApi(Email $email, SmtpEnvelope $envelope): ResponseInterface; - public function __construct(HttpClientInterface $client = null, EventDispatcherInterface $dispatcher = null, LoggerInterface $logger = null) - { - $this->client = $client; - if (null === $client) { - if (!class_exists(HttpClient::class)) { - throw new \LogicException(sprintf('You cannot use "%s" as the HttpClient component is not installed. Try running "composer require symfony/http-client".', __CLASS__)); - } - - $this->client = HttpClient::create(); - } - - parent::__construct($dispatcher, $logger); - } - - abstract protected function doSendEmail(Email $email, SmtpEnvelope $envelope): void; - - protected function doSend(SentMessage $message): void + protected function doSendHttp(SentMessage $message): ResponseInterface { try { $email = MessageConverter::toEmail($message->getOriginalMessage()); @@ -54,7 +35,7 @@ abstract class AbstractApiTransport extends AbstractTransport throw new RuntimeException(sprintf('Unable to send message with the "%s" transport: %s', __CLASS__, $e->getMessage()), 0, $e); } - $this->doSendEmail($email, $message->getEnvelope()); + return $this->doSendApi($email, $message->getEnvelope()); } protected function getRecipients(Email $email, SmtpEnvelope $envelope): array From fded3cd68cf4422d427a15a503f2fe21428c29d5 Mon Sep 17 00:00:00 2001 From: Fabien Potencier Date: Wed, 17 Jul 2019 18:19:27 +0200 Subject: [PATCH 2/2] [Mailer] added support ffor debug info when using SMTP --- .../Mailer/Transport/Smtp/SmtpTransport.php | 27 ++++++++++--------- .../Transport/Smtp/Stream/AbstractStream.php | 20 +++++++++++++- 2 files changed, 33 insertions(+), 14 deletions(-) diff --git a/src/Symfony/Component/Mailer/Transport/Smtp/SmtpTransport.php b/src/Symfony/Component/Mailer/Transport/Smtp/SmtpTransport.php index ad3bc31b09..edba113f23 100644 --- a/src/Symfony/Component/Mailer/Transport/Smtp/SmtpTransport.php +++ b/src/Symfony/Component/Mailer/Transport/Smtp/SmtpTransport.php @@ -135,7 +135,6 @@ class SmtpTransport extends AbstractTransport */ public function executeCommand(string $command, array $codes): string { - $this->getLogger()->debug(sprintf('Email transport "%s" sent command "%s"', __CLASS__, trim($command))); $this->stream->write($command); $response = $this->getFullResponse(); $this->assertResponseCode($response, $codes); @@ -145,18 +144,22 @@ class SmtpTransport extends AbstractTransport protected function doSend(SentMessage $message): void { - $envelope = $message->getEnvelope(); - $this->doMailFromCommand($envelope->getSender()->toString()); - foreach ($envelope->getRecipients() as $recipient) { - $this->doRcptToCommand($recipient->toString()); - } + try { + $envelope = $message->getEnvelope(); + $this->doMailFromCommand($envelope->getSender()->toString()); + foreach ($envelope->getRecipients() as $recipient) { + $this->doRcptToCommand($recipient->toString()); + } - $this->executeCommand("DATA\r\n", [354]); - foreach (AbstractStream::replace("\r\n.", "\r\n..", $message->toIterable()) as $chunk) { - $this->stream->write($chunk); + $this->executeCommand("DATA\r\n", [354]); + foreach (AbstractStream::replace("\r\n.", "\r\n..", $message->toIterable()) as $chunk) { + $this->stream->write($chunk, false); + } + $this->stream->flush(); + $this->executeCommand("\r\n.\r\n", [250]); + } finally { + $message->appendDebug($this->stream->getDebug()); } - $this->stream->flush(); - $this->executeCommand("\r\n.\r\n", [250]); } protected function doHeloCommand(): void @@ -237,8 +240,6 @@ class SmtpTransport extends AbstractTransport list($code) = sscanf($response, '%3d'); $valid = \in_array($code, $codes); - $this->getLogger()->debug(sprintf('Email transport "%s" received response "%s" (%s).', __CLASS__, trim($response), $valid ? 'ok' : 'error')); - if (!$valid) { throw new TransportException(sprintf('Expected response code "%s" but got code "%s", with message "%s".', implode('/', $codes), $code, trim($response)), $code); } diff --git a/src/Symfony/Component/Mailer/Transport/Smtp/Stream/AbstractStream.php b/src/Symfony/Component/Mailer/Transport/Smtp/Stream/AbstractStream.php index 2724bec64d..a2fcb945dc 100644 --- a/src/Symfony/Component/Mailer/Transport/Smtp/Stream/AbstractStream.php +++ b/src/Symfony/Component/Mailer/Transport/Smtp/Stream/AbstractStream.php @@ -28,8 +28,16 @@ abstract class AbstractStream protected $in; protected $out; - public function write(string $bytes): void + private $debug = ''; + + public function write(string $bytes, $debug = true): void { + if ($debug) { + foreach (explode("\n", trim($bytes)) as $line) { + $this->debug .= sprintf("> %s\n", $line); + } + } + $bytesToWrite = \strlen($bytes); $totalBytesWritten = 0; while ($totalBytesWritten < $bytesToWrite) { @@ -74,9 +82,19 @@ abstract class AbstractStream } } + $this->debug .= sprintf('< %s', $line); + return $line; } + public function getDebug(): string + { + $debug = $this->debug; + $this->debug = ''; + + return $debug; + } + public static function replace(string $from, string $to, iterable $chunks): \Generator { if ('' === $from) {