diff --git a/CHANGELOG.md b/CHANGELOG.md index fc7b80b1..304f9ac3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,12 @@ All notable changes to this project will be documented in this file, in reverse ### Added -- Nothing. +- [#117](https://github.com/zendframework/zend-mail/pull/117) adds support + configuring whether or not an SMTP transport should issue a `QUIT` at + `__destruct()` and/or end of script execution. Use the `use_complete_quit` + configuration flag and/or the `setuseCompleteQuit($flag)` method to change + the setting (default is to enable this behavior, which was the previous + behavior). ### Deprecated diff --git a/src/Protocol/Smtp.php b/src/Protocol/Smtp.php index c1168dc4..81b66f75 100644 --- a/src/Protocol/Smtp.php +++ b/src/Protocol/Smtp.php @@ -66,6 +66,13 @@ class Smtp extends AbstractProtocol */ protected $data = null; + /** + * Whether or not send QUIT command + * + * @var bool + */ + protected $useCompleteQuit = true; + /** * Constructor. * @@ -128,6 +135,10 @@ public function __construct($host = '127.0.0.1', $port = null, array $config = n } } + if (array_key_exists('use_complete_quit', $config)) { + $this->setUseCompleteQuit($config['use_complete_quit']); + } + // If no port has been specified then check the master PHP ini file. Defaults to 25 if the ini setting is null. if ($port === null) { if (($port = ini_get('smtp_port')) == '') { @@ -138,6 +149,25 @@ public function __construct($host = '127.0.0.1', $port = null, array $config = n parent::__construct($host, $port); } + /** + * Set whether or not send QUIT command + * + * @param int $useCompleteQuit use complete quit + */ + public function setUseCompleteQuit($useCompleteQuit) + { + return $this->useCompleteQuit = (bool) $useCompleteQuit; + } + + /** + * Whether or not send QUIT command + * + * @return bool + */ + public function useCompleteQuit() + { + return $this->useCompleteQuit; + } /** * Connect to the server with the parameters given in the constructor. @@ -350,8 +380,12 @@ public function quit() { if ($this->sess) { $this->auth = false; - $this->_send('QUIT'); - $this->_expect(221, 300); // Timeout set for 5 minutes as per RFC 2821 4.5.3.2 + + if ($this->useCompleteQuit()) { + $this->_send('QUIT'); + $this->_expect(221, 300); // Timeout set for 5 minutes as per RFC 2821 4.5.3.2 + } + $this->stopSession(); } } diff --git a/test/Protocol/SmtpTest.php b/test/Protocol/SmtpTest.php index 6940748e..8962a7a1 100644 --- a/test/Protocol/SmtpTest.php +++ b/test/Protocol/SmtpTest.php @@ -36,23 +36,23 @@ public function testSendMinimalMail() { $headers = new Headers(); $headers->addHeaderLine('Date', 'Sun, 10 Jun 2012 20:07:24 +0200'); + $message = new Message(); - $message - ->setHeaders($headers) - ->setSender('ralph.schindler@zend.com', 'Ralph Schindler') - ->setBody('testSendMailWithoutMinimalHeaders') - ->addTo('zf-devteam@zend.com', 'ZF DevTeam') - ; + $message->setHeaders($headers); + $message->setSender('ralph.schindler@zend.com', 'Ralph Schindler'); + $message->setBody('testSendMailWithoutMinimalHeaders'); + $message->addTo('zf-devteam@zend.com', 'ZF DevTeam'); + $expectedMessage = "EHLO localhost\r\n" - . "MAIL FROM:\r\n" - . "RCPT TO:\r\n" - . "DATA\r\n" - . "Date: Sun, 10 Jun 2012 20:07:24 +0200\r\n" - . "Sender: Ralph Schindler \r\n" - . "To: ZF DevTeam \r\n" - . "\r\n" - . "testSendMailWithoutMinimalHeaders\r\n" - . ".\r\n"; + . "MAIL FROM:\r\n" + . "RCPT TO:\r\n" + . "DATA\r\n" + . "Date: Sun, 10 Jun 2012 20:07:24 +0200\r\n" + . "Sender: Ralph Schindler \r\n" + . "To: ZF DevTeam \r\n" + . "\r\n" + . "testSendMailWithoutMinimalHeaders\r\n" + . ".\r\n"; $this->transport->send($message); @@ -63,13 +63,13 @@ public function testSendEscapedEmail() { $headers = new Headers(); $headers->addHeaderLine('Date', 'Sun, 10 Jun 2012 20:07:24 +0200'); + $message = new Message(); - $message - ->setHeaders($headers) - ->setSender('ralph.schindler@zend.com', 'Ralph Schindler') - ->setBody("This is a test\n.") - ->addTo('zf-devteam@zend.com', 'ZF DevTeam') - ; + $message->setHeaders($headers); + $message->setSender('ralph.schindler@zend.com', 'Ralph Schindler'); + $message->setBody("This is a test\n."); + $message->addTo('zf-devteam@zend.com', 'ZF DevTeam'); + $expectedMessage = "EHLO localhost\r\n" . "MAIL FROM:\r\n" . "RCPT TO:\r\n" @@ -111,4 +111,31 @@ public function testConnectHasVerboseErrors() $smtp->connect('nonexistentremote'); } + + public function testCanAvoidQuitRequest() + { + $this->assertTrue($this->connection->useCompleteQuit(), 'Default behaviour must be BC'); + + $this->connection->resetLog(); + $this->connection->connect(); + $this->connection->helo(); + $this->connection->disconnect(); + + $this->assertContains('QUIT', $this->connection->getLog()); + + $this->connection->setUseCompleteQuit(false); + $this->assertFalse($this->connection->useCompleteQuit()); + + $this->connection->resetLog(); + $this->connection->connect(); + $this->connection->helo(); + $this->connection->disconnect(); + + $this->assertNotContains('QUIT', $this->connection->getLog()); + + $connection = new SmtpProtocolSpy([ + 'use_complete_quit' => false, + ]); + $this->assertFalse($connection->useCompleteQuit()); + } }